Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

#include <runtime/base/hphp.h>

#include <sys/literal_strings_remap.h>

#include <sys/scalar_arrays_remap.h>

#include <sys/scalar_integers_remap.h>

#include <sys/global_variables.h>

#include <sys/cpputil.h>

#include <php/test.fws.h>

#include <php/test.h>

// Dependencies

#include <runtime/ext/ext.h>

namespace hphp_impl_starter {}

namespace HPHP {

///////////////////////////////////////////////////////////////////////////////

/* preface starts */

extern CallInfo ci_;

/* preface finishes */

Variant pm_php$test_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test.php, pm_php$test_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

echo(NAMSTR(s_ss3994978b, "hello world"));

return true;

}

namespace hphp_impl_splitter {}

///////////////////////////////////////////////////////////////////////////////

}

Variant pm_php$test8_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test8.php, pm_php$test8_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

Variant &v_b ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ssf8576bd5, "b")) : g->GV(b);

Variant &v_c ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss5c5509b0, "c")) : g->GV(c);

Variant &v_d ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ssaa9bf7c4, "d")) : g->GV(d);

v_a = 1LL;

v_b = NAMSTR(s_sse6f62137, "hello");

v_c = 2LL;

v_c = NAMSTR(s_ss8f83bd9c, "str");

v_d = s_sa00000000;

v_d.append((NAMVAR(s_svi542bad8b, 10LL)));

v_d.set(NAMSTR(s_ssd2bea2d3, "ex"), (NAMVAR(s_svid7a79683, 20LL)), true);

v_d.append((NAMVAR(s_svifc87a5f7, 30LL)));

LINE(14,(x_var_dump(4, v_a, Array(array_createvi(3, toVPOD(v_b), toVPOD(v_c), toVPOD(v_d))))));

return true;

}

PHP>$a = 1;

C++>v_a = 1LL;

PHP>$b = "hello";

C++>v_b = NAMSTR(s_sse6f62137, "hello");

PHP>$c = 2;

PHP>$c = "str";

C++>v_c = 2LL;

C++>v_c = NAMSTR(s_ss8f83bd9c, "str");

PHP>$d = array();

PHP>$d[] = 10;

PHP>$d['ex'] = 20;

PHP>$d[] = 30;

C++>v_d = s_sa00000000;

C++>v_d.append((NAMVAR(s_svi542bad8b, 10LL)));

C++>v_d.set(NAMSTR(s_ssd2bea2d3, "ex"), (NAMVAR(s_svid7a79683, 20LL)), true);

C++>v_d.append((NAMVAR(s_svifc87a5f7, 30LL)));

Variant pm_php$test24_tpl(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test24.tpl, pm_php$test24_tpl);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

echo(NAMSTR(s_ss18b6f89c, "hello "));

echo(toString(v_a));

echo(NAMSTR(s_ss66d2232c, "\n"));

return true;

}

えんいー\e

未来の部屋

萌え萌えCSS

なのは完売

新潟アクセス修飾子

とある関数の電脳戦

(バトルプログラミング)

自己紹介

hiphop php

が生成する

C++のコードを

読んでみよう。

音声認識を利用して

家電制御を制御する

未来の部屋

自己紹介

こんちにはー

プロセスの乗っ取りを防ぐ

アンチフックの話

そして、攻性防壁の構築。

一部アセンブラ

jQueryを

萌え化する

by rti

public

protected

private

そして niigata

名前: rti

仕事: 自宅警備の傍ら音声認識作ってます。

肩書き: シーランド公国伯爵/rti技研代表

特技: イオナズンが使えます。

最近のトレンド: 音声認識

http://d.hatena.ne.jp/rti7743/

http://rtilabs.net/

https://twitter.com/#!/super_rti

http://d.hatena.ne.jp/rti7743/20111220/1324389840

http://prezi.com/2r6wmrriyeqb/niigata/

音声認識で、

部屋中の家電を操作できるようにする

デバイス作ってます。 10月中に出すかも

http://rti-giken.jp/

http://d.hatena.ne.jp/rti7743/20120104/1325668680

http://rtilabs.net/files/2010_12_24/moemoe_css/

処理の流れ

hiphop phpって何?

インストール方法

パフォーマンス

ベンチマーク

Regexp Assemble for PHP

どうやって早くしているんだろう?

からの発表

A

PHPで作ったプログラム

すべてに一致する正規表現を自動生成する。

処理系 速度

PHP 5.3.3 15.260s

PHP 5.4RC4 11.556s

hiphop php 5.022s

B

Scientific Linux 6.1 (64bit)でテスト

が作った、

C

hiphop php

が生成する

C++のコードを

読んでみよう。

hiphop phpとは?

パフォーマンス

通常のwebアプリだと DBなどがネックになる。

PHPだけのロジックで速度を測る。

今回は、自作の regexp assemble for PHP を使う。

C++に変換!!(hiphopのしごと)

インストール方法

D

facebook

centos5系でも入るよ。

パッケージで苦労するけど。

32bit系でも入らなくはないけど、、、

とても苦労するが。

HipHop for PHP。

HipHopにより私たちはページによっては、

Webサーバー上で約50パーセントのCPU使用量を削減できました。

CPUの使用量の少なさは、サーバー台数の削減につながり、

それはより少ないオーバーヘッドを意味します。

今回は hiphop phpがどうやって、

PHPを C++ に変換しているのかについて

みていきたいと思います。

E

<?php

require_once("Regexp_Assemble.php");

for($i = 0 ; $i < 10000 ; ++$i ) {

$reg = new Regexp_Assemble();

$reg->add('神岸あかり');

$reg->add('赤座あかり');

$reg->add('黒座あかり');

$str = $reg->as_string();

$reg = new Regexp_Assemble();

$reg->add('スティーブ・ジョブズ');

$reg->add('スティーブ・ウォズアニック');

$str = $reg->as_string();

$reg = new Regexp_Assemble();

$reg->add('お兄ちゃま');

$reg->add('あにぃ');

$reg->add('お兄様');

$reg->add('おにいたま');

$reg->add('兄上様');

$reg->add('にいさま');

$reg->add('アニキ');

$reg->add('兄くん');

$reg->add('兄君さま');

$reg->add('兄チャマ');

$reg->add('兄や');

$str = $reg->as_string();

}

#追加リポジトリ

rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm

rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-5.noarch.rpm

#アップデートと開発ツールのインストール

yum -y update

yum -y groupinstall "Development Tools"

#依存パッケージで yum で入るものを入れる.

yum -y --enablerepo=rpmforge,epel install git cmake libssh2 gd gd-devel mysql-server mysql-devel php php-cli php-common php-mbstring php-pear python-devel icu libicu-devel oniguruma oniguruma-devel flex memcached libmemcached bison re2c mysql mysql-devel libxml2 libxml2-devel libmcrypt libmcrypt-devel php-mcrypt openssl binutils binutils-devel libcap libcap-devel gd zlib bzip2 bzip2-libs bzip2-devel pcre pcre-devel expat expat-devel gd gd-devel openldap openldap-devel readline readline-devel libc-client libc-client-devel ncurses ncurses-devel pam pam-devel libmcrypt libmcrypt-devel wget tbb tbb-devel

# libmemcache

# OS標準が古いのでアップデートする

#

cd /usr/local/src/

wget http://download.tangent.org/libmemcached-0.43.tar.gz

tar -xvf libmemcached-0.43.tar.gz

cd libmemcached-0.43

./configure --prefix=/usr

make

make install

# boost

# OS標準が古いので新しいやつを /usr/に上書きで。。。

#

cd /usr/local/src/

wget 'http://sourceforge.net/projects/boost/files/boost/1.48.0/boost_1_48_0.tar.gz/download'

tar -xvf boost_1_48_0.tar.gz

cd boost_1_48_0

./bootstrap.sh

./b2 install --prefix=/usr

# download hiphop

# 先にダウンロードしないと patchが手に入らない

#

cd /usr/local/src/

git clone git://github.com/facebook/hiphop-php.git

# install libcurl

# うちでは /usr/に上書きした

#

cd /usr/local/src/

wget http://curl.haxx.se/download/curl-7.20.0.tar.bz2

tar -xvf curl-7.20.0.tar.bz2

cp hiphop-php/src/third_party/libcurl.fb-changes.diff curl-7.20.0/

cd curl-7.20.0

sed -i 's/curl-old\///g' libcurl.fb-changes.diff

sed -i 's/curl-new\///g' libcurl.fb-changes.diff

patch -p0 < libcurl.fb-changes.diff

./configure --with-ssl --with-zlib --with-libidn --enable-sspi --enable-ldap --enable-ldaps --prefix=/usr

make

make install

# install libevent

# うちでは /usr/に上書きした

#

cd /usr/local/src/

wget http://monkey.org/~provos/libevent-1.4.13-stable.tar.gz

tar -xvf libevent-1.4.13-stable.tar.gz

cp hiphop-php/src/third_party/libevent-1.4.13.fb-changes.diff libevent-1.4.13-stable/

cd libevent-1.4.13-stable

sed -i 's/libevent-1.4.13-stable\///g' libevent-1.4.13.fb-changes.diff

sed -i 's/libevent-1.4.13-stable-fb\///g' libevent-1.4.13.fb-changes.diff

patch -p0 < libevent-1.4.13.fb-changes.diff

./configure --prefix=/usr

make

make install

ldconfig

# install hiphop

cd /usr/local/src/

cd hiphop-php/

export HPHP_HOME="/usr/local/src/hiphop-php"

export HPHP_LIB="/usr/local/src/hiphop-php/bin"

cmake -DCMAKE_PREFIX_PATH=/usr .

make

make install

#export で環境変数を定義している。ログアウトすると消えるので注意。

#毎回有効にしたい人は、 ~/.bashrc にでも。

#コピペ用

export HPHP_HOME="/usr/local/src/hiphop-php"

export HPHP_LIB="/usr/local/src/hiphop-php/bin"

F

gccとかでコンパイル。最適化。

C++

<?php

require_once("Regexp_Assemble.php");

$reg = new Regexp_Assemble();

$reg->add('お兄ちゃん');

$reg->add('お兄ちゃま');

$reg->add('あにぃ');

$reg->add('お兄様');

$reg->add('おにいたま');

$reg->add('兄上様');

$reg->add('にいさま');

$reg->add('アニキ');

$reg->add('兄くん');

$reg->add('兄君さま');

$reg->add('兄チャマ');

$reg->add('兄や');

//(?:お(?:兄(?:ちゃ[まん]|様)|にいたま)|兄(?:チャマ|君さま|くん|上様|や)|にいさま|あにぃ|アニキ)

echo $reg->as_string();

トランスレーター

PHP

プログラムは魔法で動いているのではない。

正規表現を自動生成してくれるツール。

perlのライブラリからの勝手移植。

正味2000行~3000行

G

http://developers.facebook.com/news.php?blog=1&story=358 の翻訳 http://blog.candycane.jp/archives/275

実行が超早くなる。

hiphop PHPは、

PHP5.3の3倍、PHP5.4の 2倍以上の速さ

by rti

H

ネイティヴコードで実行

(ここまで前ふり)

結果→

I

変換されたソースを見る。

hiphop PHP独自の文字列型

って何?

hello world のコードをもっと単純化して

書くと、こんな感じになります。

echo(s_ss3994978b);

C++に変換は一瞬でも

コンパイルには結構時間が掛かる。

echo(NAMSTR(s_ss3994978b, "hello world"));

変換とコンパイル

元のPHPのコード test.php

C++に変換

hello world

<?php

echo "hello world";

class StaticString : public String {

//略

}

一度だけ必要

extern StaticString s_ss3994978b;

#define NAMVAR(nam, str) (nam)

test.php

export HPHP_HOME="/usr/local/src/hiphop-php"

export HPHP_LIB="/usr/local/src/hiphop-php/bin"

hphp_test/php/test.h

hphp_test/php/test.fws.hで定義

php/test.fws.h

hphp_test/php/test.cpp

runtime/base/macros.h で定義

echo(NAMSTR(s_ss3994978b, "hello world"));

StaticString s_ss3994978b("hello world");

echo(s_ss3994978b);

runtime/base/type_string.h で定義

hello world

C++のだめなところに

コンパイルがとても遅いところがあるが、

hiphopが作ったコードのコンパイルも遅い。

hello worldで 1分程度の時間がかかる。

hiphop PHPが作るコードは、

PHP実行環境も内包しているためとてもでかいのだ。

Stringクラス構造

#ifndef __GENERATED_php_test_h70588221__

#define __GENERATED_php_test_h70588221__

// Declarations

namespace HPHP {

///////////////////////////////////////////////////////////////////////////////

// Includes and Functions

Variant pm_php$test_php(bool incOnce, LVariableTable* variables, Globals *globals);

// Constants

///////////////////////////////////////////////////////////////////////////////

}

#endif // __GENERATED_php_test_h70588221__

running hphp...

creating temporary directory /tmp/hphp_vlzsBB ...

parsing inputs...

parsing inputs took 0'00" (5 ms) wall time

pre-optimizing...

pre-optimizing took 0'00" (0 ms) wall time

inferring types...

inferring types took 0'00" (0 ms) wall time

post-optimizing...

post-optimizing took 0'00" (0 ms) wall time

creating CPP files...

creating CPP files took 0'00" (48 ms) wall time

compiling and linking CPP files...

compiling and linking CPP files took 0'56" (56326 ms) wall time

running executable /tmp/hphp_vlzsBB/program --file test.php...

hello worldall files saved in /tmp/hphp_vlzsBB ...

running hphp took 0'56" (56802 ms) wall time

#ifndef __GENERATED_php_test_fws_h1c89c124__

#define __GENERATED_php_test_fws_h1c89c124__

namespace HPHP {

///////////////////////////////////////////////////////////////////////////////

// 1. Static Strings

extern StaticString s_ss3994978b;

// 2. Static Arrays

// 3. Static Variants

///////////////////////////////////////////////////////////////////////////////

}

#endif // __GENERATED_php_test_fws_h1c89c124__

StaticString s_ss3994978b("hello world");

hphp test.php --keep-tempdir=1 --log=3

echo(s_ss3994978b);

<?php

echo "hello world";

でsys\literal_strings_0.no.cppで定義

遅い!

class StaticString : public String

class String : public SmartPtr<StringData>

class StringData

変換するPHP名

"hello world"という文字は、

人間が見て分かるためのものだった

StaticStringって何?

テンポラリのソースコードがみたいので

テンポラリ

PHPとC++を対訳

Variant型の宣言

Variant型

C++で variant作る時の2つの方法

こっちぽい

A 変数の名前宣言

フラグ + union

Variant型とは?

VBやMS-COM回りで遊んでいた人にお馴染みの、

なんでも代入できる型。

class Variant {

public:

//中略

Variant(bool v) : _count(0), m_type(KindOfBoolean) { m_data.num = (v?1:0);}

Variant(int v) : _count(0), m_type(KindOfInt32 ) { m_data.num = v;}

Variant(int64 v) : _count(0), m_type(KindOfInt64 ) { m_data.num = v;}

Variant(uint64 v) : _count(0), m_type(KindOfInt64 ) { m_data.num = v;}

Variant(long v) : _count(0), m_type(KindOfInt64 ) { m_data.num = v;}

Variant(double v) : _count(0), m_type(KindOfDouble ) { m_data.dbl = v;}

//中略

};

<?php

$a = 1;

$b = "hello";

$c = 2;

$c = "str";

$d = array();

$d[] = 10;

$d['ex'] = 20;

$d[] = 30;

var_dump($a,$b,$c,$d);

型をフラグでもっていて、

データ自体は unionに入れる。

クラスが絡むと面倒

変数

B ロジック

PHP 型が比較的自由

C++ 厳格な型

配列については、

あとで解説

template + new

runtime/base/type_variant.hで定義

なんでも代入できる!!

自前で参照カウントっぽいものをもっている。

boost::anyとかこっち。

型が綺麗に表現できる。

が、newが細切れに発生

このギャップを埋めるには、 Variant という緩衝材が必要。

C++だと boost::anyなどあるが hiphopは自前実装。

StaticArray型

前回のソースから配列だけ

C++>v_d = s_sa00000000;

C++>v_d.append((NAMVAR(s_svi542bad8b, 10LL)));

C++>v_d.set(NAMSTR(s_ssd2bea2d3, "ex"), (NAMVAR(s_svid7a79683, 20LL)), true);

C++>v_d.append((NAMVAR(s_svifc87a5f7, 30LL)));

配列

class StaticArray : public Array {

public:

StaticArray() { }

StaticArray(ArrayData *data) : Array(data) {

m_px->setStatic();

m_px->onSetStatic();

}

~StaticArray() {

m_px = NULL;

}

};

PHP>$d = array();

PHP>$d[] = 10;

PHP>$d['ex'] = 20;

PHP>$d[] = 30;

C++>v_d = s_sa00000000;

C++>v_d.append((NAMVAR(s_svi542bad8b, 10LL)));

C++>v_d.set(NAMSTR(s_ssd2bea2d3, "ex"), (NAMVAR(s_svid7a79683, 20LL)), true);

C++>v_d.append((NAMVAR(s_svifc87a5f7, 30LL)));

extern StaticArray s_sa00000000;

関数の戻り値まとめ

戻り値を返さない

数字かNULLを返す場合

関数を返す場合

Arrayを返す場合

Array型は、Variantではない

Numeric最適化・・・されません。

p_Closure 型

関数の実体

Numeric型だとおもった?

残念。 Variant型でした。

直接呼ばれているのは、関数の実体が書いてある f_myfunc

備考

場合

myfuncが3つある。

function say($str)

{

echo $str;

}

function myfunc($x)

{

if ($x % 2 == 0)

{

return $x;

}

return NULL;

}

Numeric

Variantのtypedef

数値型

function myfunc($x)

{

return function()

{

return 1;

};

}

function myfunc($x)

{

return array($x);

}

typedef Variant Numeric;

function myfunc($v)

{

return $v + 1;

}

Array f_myfunc(CVarRef v_x) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_x)), r);

return Array(array_createvi(1, toVPOD(v_x)));

}

runtime/base/types.h で定義

String

文字型

ちゃんと戻り値が

void 型になりました

他の関数の戻り値型も見てみよう

p_Closure 型に

なりました。

<?php

function myfunc($v)

{

return $v + 1;

}

$a = myfunc(3);

var_dump($a);

Array

配列

戻り値が Variant になりました。

まーしかたない。

extern CallInfo ci_;

extern CallInfo ci_myfunc;

Numeric f_myfunc(CVarRef v_v) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_v)), r);

return (v_v + 1LL);

}

namespace hphp_impl_splitter {}

Variant ifa_myfunc(void *extra, int count, INVOKE_FEW_ARGS_IMPL_ARGS) {

if (UNLIKELY(count < 1)) throw_missing_arguments("myfunc", count+1);

CVarRef arg0(UNLIKELY(count <= 0) ? null_variant : a0);

return (f_myfunc(arg0));

}

Variant i_myfunc(void *extra, CArrRef params) {

return invoke_func_few_handler(extra, params, &ifa_myfunc);

}

CallInfo ci_myfunc((void*)&i_myfunc, (void*)&ifa_myfunc, 1, 0, 0x0000000000000000LL);

Variant pm_php$test12_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test12.php, pm_php$test12_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

{

LINE(8,0);

const Numeric &tmp0((f_myfunc(NAMVAR(s_svia6bfbbdd, 3LL))));

v_a.assignVal(tmp0);

}

LINE(9,(x_var_dump(1, v_a)));

return true;

}

関数

{

LINE(8,0);

const Numeric &tmp0((f_myfunc(NAMVAR(s_svia6bfbbdd, 3LL))));

v_a.assignVal(tmp0);

}

↓↓↓f_myfunc を呼び出す↓↓

Numeric f_myfunc(CVarRef v_v) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_v)), r);

return (v_v + 1LL);

}

クロージャーと関数を返す関数との

厳密な意味は違うが、

最近区別が曖昧になってる。

C++11ともそうなんだけど。

関数返していれば、

束縛しようとしまいとクロージャーらしい

p_Closure

関数

Numeric f_myfunc(CVarRef v_v) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_v)), r);

return (v_v + 1LL);

}

int値が Variantを経由するなんてやや残念です。

int値が2^31を超えてしまったときに

float型に変換されるとかの PHP の仕様が

響いているのでしょうか?

class Array : public SmartPtr<ArrayData> {

}

void f_say(CVarRef v_str) {

FUNCTION_INJECTION_NOMEM(say);

INTERCEPT_INJECTION("say", array_createvi(1, toVPOD(v_str)), );

echo(toString(v_str));

}

Variant f_myfunc(CVarRef v_x) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_x)), r);

if (equal(modulo(toInt64(v_x), 2LL), 0LL)) {

{

return v_x;

}

}

return null;

}

p_Closure f_myfunc(CVarRef v_x) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_x)), r);

return LINE(7,(p_Closure(NEWOBJ(c_Closure)(&ci_07358007151305723156_1, NULL))));

}

Array f_myfunc(CVarRef v_x) {

FUNCTION_INJECTION(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_x)), r);

return Array(array_createvi(1, toVPOD(v_x)));

}

別の値と混合

Variant

runtime/base/type_array.hで定義

void

値を返さない

戻り値が Numeric型 になってる。

typedef Variant Numeric;

他は何に使っているのでしょうか?

今はわからないので、置いといて先に進みましょう。

束縛(キャプチャ)

キャプチャはクラスで表現

CallInfo型

無名関数

A classができた

組み込み関数

<?php

$a = "hello";

$b = strstr($a,"he");

var_dump($a,$b);

<?php

$cap = 10;

$func = function($a) use($cap)

{

return $a + $cap + 1;

};

$c = $func(2); //2 + 10 + 1

var_dump($c);

<?php

$func = function($param1)

{

return $param1 + 1;

};

$a = $func(10);

var_dump($a);

C 関数の情報

束縛(キャプチャ)

B キャプチャしている変数の割り当て

FORWARD_DECLARE_CLASS(Closure$07296613028076329051_1);

class c_Closure$07296613028076329051_1 : public c_Closure {

public:

DECLARE_OBJECT_ALLOCATION_NO_SWEEP(c_Closure$07296613028076329051_1)

Variant v_cap;

c_Closure$07296613028076329051_1(const CallInfo *func, void *extra, CVarRef r_cap) : c_Closure(func, extra) {

v_cap.assignVal(r_cap);

}

};

/* preface starts */

extern CallInfo ci_;

extern CallInfo ci_08511066943069959013_1;

/* preface finishes */

/* SRC: test10.php line 3 */

Numeric f_08511066943069959013_1(void *extra, CVarRef v_param1) {

FUNCTION_INJECTION(08511066943069959013_1);

INTERCEPT_INJECTION("08511066943069959013_1", array_createvi(1, toVPOD(v_param1)), r);

return (v_param1 + 1LL);

}

namespace hphp_impl_splitter {}

Variant ifa_08511066943069959013_1(void *extra, int count, INVOKE_FEW_ARGS_IMPL_ARGS) {

if (UNLIKELY(count < 1)) throw_missing_arguments("08511066943069959013_1", count+1);

CVarRef arg0(UNLIKELY(count <= 0) ? null_variant : a0);

return (f_08511066943069959013_1(extra, arg0));

}

Variant i_08511066943069959013_1(void *extra, CArrRef params) {

return invoke_func_few_handler(extra, params, &ifa_08511066943069959013_1);

}

CallInfo ci_08511066943069959013_1((void*)&i_08511066943069959013_1, (void*)&ifa_08511066943069959013_1, 1, 0, 0x0000000000000000LL);

Variant pm_php$test10_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test10.php, pm_php$test10_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_func ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_sse63d8c2d, "func")) : g->GV(func);

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

{

LINE(6,0);

p_Closure tmp0((p_Closure(NEWOBJ(c_Closure)(&ci_08511066943069959013_1, NULL))));

v_func = tmp0;

}

{

const CallInfo *cit0;

void *vt0;

get_call_info_or_fail(cit0, vt0, v_func);

LINE(8,0);

Variant tmp1(((cit0->getFunc1Args())(vt0, 1, 10LL)));

v_a.assignVal(tmp1);

}

LINE(9,(x_var_dump(1, v_a)));

return true;

}

x_strstrがPHPの組み込み関数

無名関数

組み込み関数

extern CallInfo ci_;

extern CallInfo ci_07296613028076329051_1;

FORWARD_DECLARE_CLASS(Closure$07296613028076329051_1);

class c_Closure$07296613028076329051_1 : public c_Closure {

public:

DECLARE_OBJECT_ALLOCATION_NO_SWEEP(c_Closure$07296613028076329051_1)

Variant v_cap;

c_Closure$07296613028076329051_1(const CallInfo *func, void *extra, CVarRef r_cap) : c_Closure(func, extra) {

v_cap.assignVal(r_cap);

}

};

/* preface finishes */

/* SRC: test27.php line 4 */

Numeric f_07296613028076329051_1(void *extra, CVarRef v_a) {

FUNCTION_INJECTION(07296613028076329051_1);

INTERCEPT_INJECTION("07296613028076329051_1", array_createvi(1, toVPOD(v_a)), r);

c_Closure$07296613028076329051_1 *closure ATTRIBUTE_UNUSED = (c_Closure$07296613028076329051_1*)extra;

Variant v_cap;

v_cap.assignVal(closure->v_cap);

return (v_a + (v_cap + 1LL));

}

namespace hphp_impl_splitter {}

Variant ifa_07296613028076329051_1(void *extra, int count, INVOKE_FEW_ARGS_IMPL_ARGS) {

if (UNLIKELY(count < 1)) throw_missing_arguments("07296613028076329051_1", count+1);

CVarRef arg0(UNLIKELY(count <= 0) ? null_variant : a0);

return (f_07296613028076329051_1(extra, arg0));

}

Variant i_07296613028076329051_1(void *extra, CArrRef params) {

return invoke_func_few_handler(extra, params, &ifa_07296613028076329051_1);

}

CallInfo ci_07296613028076329051_1((void*)&i_07296613028076329051_1, (void*)&ifa_07296613028076329051_1, 1, 0, 0x0000000000000000LL);

IMPLEMENT_OBJECT_ALLOCATION_NO_DEFAULT_SWEEP(c_Closure$07296613028076329051_1)

Variant pm_php$test27_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test27.php, pm_php$test27_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_cap ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ssf0ead937, "cap")) : g->GV(cap);

Variant &v_func ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_sse63d8c2d, "func")) : g->GV(func);

Variant &v_c ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss5c5509b0, "c")) : g->GV(c);

v_cap = 10LL;

{

LINE(7,0);

p_Closure tmp0((p_Closure$07296613028076329051_1(NEWOBJ(c_Closure$07296613028076329051_1)(&ci_07296613028076329051_1, NULL, v_cap))));

v_func = tmp0;

}

{

const CallInfo *cit0;

void *vt0;

get_call_info_or_fail(cit0, vt0, v_func);

LINE(9,0);

Variant tmp1(((cit0->getFunc1Args())(vt0, 1, 2LL)));

v_c.assignVal(tmp1);

}

LINE(10,(x_var_dump(1, v_c)));

return true;

}

関数の種類

class CallInfo {

public:

~中略~

FuncInvoker getFunc() const { return (FuncInvoker)m_invoker; }

FuncInvokerFewArgs getFuncFewArgs() const {

return (FuncInvokerFewArgs)m_invokerFewArgs;

}

typedef Variant (*FuncInvoker0Args)(

void*, int);

typedef Variant (*FuncInvoker1Args)(

void*, int, CVarRef);

typedef Variant (*FuncInvoker2Args)(

void*, int, CVarRef, CVarRef);

typedef Variant (*FuncInvoker3Args)(

void*, int, CVarRef, CVarRef, CVarRef);

typedef Variant (*FuncInvoker4Args)(

void*, int, CVarRef, CVarRef, CVarRef,

CVarRef);

~中略~

typedef Variant (*FuncInvoker10Args)(

void*, int, CVarRef, CVarRef, CVarRef,

CVarRef, CVarRef, CVarRef, CVarRef, CVarRef, CVarRef, CVarRef);

FuncInvoker0Args getFunc0Args() const {

return (FuncInvoker0Args)m_invokerFewArgs;

}

FuncInvoker1Args getFunc1Args() const {

return (FuncInvoker1Args)m_invokerFewArgs;

}

FuncInvoker2Args getFunc2Args() const {

return (FuncInvoker2Args)m_invokerFewArgs;

}

FuncInvoker3Args getFunc3Args() const {

return (FuncInvoker3Args)m_invokerFewArgs;

}

FuncInvoker4Args getFunc4Args() const {

return (FuncInvoker4Args)m_invokerFewArgs;

}

~中略~

FuncInvoker10Args getFunc10Args() const {

return (FuncInvoker10Args)m_invokerFewArgs;

}

~略~

};

引数の異なる関数のポインタをラップするクラス

C++11のtemplate...があれば・・・・

A 無名関数

v_a = NAMSTR(s_sse6f62137, "hello");

{

LINE(3,0);

const Variant &tmp0((x_strstr(toString(v_a), NAMVAR(s_svs546f1cb9, "he"))));

v_b.assignVal(tmp0);

}

LINE(5,(x_var_dump(2, v_a, Array(array_createvi(1, toVPOD(v_b))))));

return true;

B 呼び出し

このクラスに、無名関数のへの関数ポインタを

入れて呼び出しできるようにする。

とても妥当な実装だと思う。

これも、C++11では captureがあるので、

今作ると別の方になりそう。

C 初期化時に cap を渡している。

lambdaの仕様を自前で実装しているので、

回りくどい。

今は、C++11 lambda もあるから

もうちょっといいルーチンが書けるかもしれないが・・・

include

例外

include

switch 文字列

switch

break

foreach

includeされる方を

見てみる

includeするところを

見てみる。

無限ループ検出器

LOOP_COUNTER と LOOP_COUNTER_CHECK

test24.cpp

test24.fws.h

test24.h

test24.tpl.nophp.cpp

test24.tpl.nophp.fws.h

test24.tpl.nophp.h

forとwhile

<?php

$a = 10;

include("test24.tpl");

test24.cpp

test24.fws.h

test24.h

test24.tpl.nophp.cpp

test24.tpl.nophp.fws.h

test24.tpl.nophp.h

B 例外送信部

<?php

$arr = array(0,1,2,3,4,5,6,7,8,9);

foreach($arr as $key => $val)

{

echo "{$key} => {$val}\n";

}

===比較演算子

test24.cpp

test24.fws.h

test24.h

test24.tpl.nophp.cpp

test24.tpl.nophp.fws.h

test24.tpl.nophp.h

if

<?php

function myfunc($a)

{

throw new Exception("hoe-");

}

try

{

myfunc(1);

}

catch(Exception $e)

{

echo "catch!";

}

<?php

$a = 10;

switch($a)

{

case 10:

$b = "10";

break;

case "2":

$b = "2string!";

break;

}

goto先生

ちっすちっす

<?php

$a = 10;

switch($a)

{

case 10:

$b = "10";

break;

case 2:

$b = "2";

break;

}

v_a = 10LL;

switch ((v_a).hashForIntSwitch(10LL, 0LL)) {

case 10LL:

{

v_b = NAMSTR(s_ssa4ae39ed, "10");

break;

}

case 2LL:

{

v_b = NAMSTR(s_ssebb8aab9, "2");

break;

}

}

<?php

for($a = 0 ; $a < 10 ; $a ++ )

{

for($b = 0 ; $b < 10 ; $b ++)

{

if ($b == 2)

{

break;

}

if ($a == 5)

{

break 2;

}

}

}

例外

v_a = 10LL;

{

Variant switch2 = (v_a);

if (equal(switch2, (10LL))) goto case_2_0;

if (equal(switch2, (NAMSTR(s_ssebb8aab9, "2"))))

goto case_2_1;

goto break1;

}

case_2_0:

{

v_b = NAMSTR(s_ssa4ae39ed, "10");

goto break1;

}

case_2_1:

{

v_b = NAMSTR(s_ss5bb3adb6, "2string!");

goto break1;

}

break1:;

switch

break

--test24.tpl--

hello <?php echo $a ?>

include

void f_myfunc(CVarRef v_a) {

FUNCTION_INJECTION_NOMEM(myfunc);

INTERCEPT_INJECTION("myfunc", array_createvi(1, toVPOD(v_a)), );

throw_exception(LINE(5,(p_Exception(((c_Exception*)coo_Exception())->create(NAMVAR(s_svsd792abf7, "hoe-"))))));

}

//略

CallInfo ci_myfunc((void*)&i_myfunc, (void*)&ifa_myfunc, 1, 0, 0x0000000000000000LL);

Variant pm_php$test17_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test17.php, pm_php$test17_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_e ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss6b7ea7eb, "e")) : g->GV(e);

try {

LINE(10,(f_myfunc(NAMVAR(s_svib794f8ce, 1LL))));

} catch (Object e) {

if (e.instanceof(NAMSTR(s_ssae8717ad, "exception"))) {

v_e = e;

echo(NAMSTR(s_ss93e46d56, "catch!"));

} else {

throw;

}

}

return true;

}

{

LOOP_COUNTER(1);

for (v_a = 0LL; (less(v_a, 10LL)); v_a++) {

LOOP_COUNTER_CHECK(1);

{

{

LOOP_COUNTER(2);

for (v_b = 0LL; (less(v_b, 10LL)); v_b++) {

LOOP_COUNTER_CHECK(2);

{

if (equal(v_b, 2LL)) {

{

break;

}

}

if (equal(v_a, 5LL)) {

{

goto break1;

}

}

}

}

}

}

}

break1:;

}

#ifdef INFINITE_LOOP_DETECTION

#define LOOP_COUNTER(n)

#define LOOP_COUNTER_CHECK(n) \

if ((++lc & 1023) == 0) { \

check_request_timeout_ex(fi, lc); \

}

#define LOOP_COUNTER_CHECK_INFO(n) \

if ((++lc & 1023) == 0) { \

check_request_timeout_info(info, lc); \

}

#else

#define LOOP_COUNTER(n)

#define LOOP_COUNTER_CHECK(n)

#define LOOP_COUNTER_CHECK_INFO(n)

#endif

v_a = 10LL;

if (equal(v_a, 10LL)) {

{

echo(NAMSTR(s_ssa4ae39ed, "10"));

}

}

else {

{

echo(NAMSTR(s_ss2dcad959, "else!"));

}

}

return true;

foreach

v_a = 10LL;

if (same(v_a, 10LL)) {

{

echo(NAMSTR(s_ssa4ae39ed, "10"));

}

}

else {

{

echo(NAMSTR(s_ss2dcad959, "else!"));

}

}

return true;

<?php

$a = 10;

if ($a === 10 ){

echo "10";

}

else

{

echo "else!";

}

<?php

$a = 10;

if ($a == 10 ){

echo "10";

}

else

{

echo "else!";

}

<?php

$for_sum = 0;

for($a = 0 ; $a <= 10 ; $a ++)

{

$for_sum += $a;

}

$while_sum = 0;

$a = 10;

while($a)

{

$while_sum += $a;

$a --;

}

A try catchに落ちた

変換されたファイル郡をみると、

*.tpl.*というファイルが増えてる。

v_for_sum = 0LL;

{

LOOP_COUNTER(1);

for (v_a = 0LL; (not_more(v_a, 10LL)); v_a++) {

LOOP_COUNTER_CHECK(1);

{

v_for_sum += v_a;

}

}

}

v_while_sum = 0LL;

v_a = 10LL;

LOOP_COUNTER(2);

{

while (toBoolean(v_a)) {

LOOP_COUNTER_CHECK(2);

{

v_while_sum += v_a;

v_a--;

}

}

}

Variant pm_php$test24_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test24.php, pm_php$test24_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

v_a = 10LL;

LINE(3,(pm_php$test24_tpl(false, variables, g)));

return true;

}

if

forとwhile

v_for_sum = 0LL;

{

LOOP_COUNTER(1);

for (v_a = 0LL; (not_more(v_a, 10LL)); v_a++) {

LOOP_COUNTER_CHECK(1);

{

v_for_sum += v_a;

}

}

}

v_while_sum = 0LL;

v_a = 10LL;

LOOP_COUNTER(2);

{

while (toBoolean(v_a)) {

LOOP_COUNTER_CHECK(2);

{

v_while_sum += v_a;

v_a--;

}

}

}

制御文

PHPは、break 2;で

ループ2回ぶち抜きとかできる。

v_arr = s_sa50d82ba2;

{

LOOP_COUNTER(1);

for (ArrayIter iter3 = v_arr.begin(null_string, true); !iter3.end(); ++iter3) {

LOOP_COUNTER_CHECK(1);

iter3.second(v_val);

v_key.assignVal(iter3.first());

{

{

echo(toString(v_key));

echo(NAMSTR(s_ss8f4bca72, " => "));

echo(toString(v_val));

echo(NAMSTR(s_ss66d2232c, "\n"));

}

}

}

}

std::map っぽい

イテレータ

JSPみたいに、

echo に切り替わった。

hello <?php echo $a ?>

goto先生

ちっすちっす

A includeしているところ

include("test24.tpl");

文字列ラベルを作ると、

gotoに変わる

文字列caseにすると・・・→

=== は、same() という関数になりました。

ディフォルトで、無限ループ検出器が働いている。

俺のコードに無限ループなんて無いっという人は、

無効にすればもっと早くなると思われる。

== は equal関数になりました。

ループカウンタの型は、 Variant なのが残念。

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

equal

==

same

===

cls/baseclass.h

cls/myclass.h

php/test25.cpp

php/test25.fws.h

php/test25.h

とにかく長い!!

ベースクラスを

見て行きましょう。

cls/myclass.h

php/test11.cpp

php/test11.fws.h

php/test11.h

cls/baseclass.h

cls/myclass.h

php/test25.cpp

php/test25.fws.h

php/test25.h

cls/myclass.h

php/test11.cpp

php/test11.fws.h

php/test11.h

<?php

class myclass

{

public $privar = 10;

public $pubvar = 20;

public function pubfunc($a)

{

return $a + $this->privar +

$this->pubvar;

}

}

$class = new myclass();

$a = $class->pubfunc(10);

/* SRC: test11.php line 3 */

FORWARD_DECLARE_CLASS(myclass);

extern const ObjectStaticCallbacks cw_myclass;

class c_myclass : public ObjectData {

public:

// Properties

int64 m_privar;

int64 m_pubvar;

// Class Map

DECLARE_CLASS_NO_SWEEP(myclass, myclass, ObjectData)

static const ClassPropTable os_prop_table;

c_myclass(const ObjectStaticCallbacks *cb = &cw_myclass) : ObjectData(cb, false), m_privar(10LL), m_pubvar(20LL) {}

public: Numeric t_pubfunc(CVarRef v_a);

DECLARE_METHOD_INVOKE_HELPERS(pubfunc);

};

ObjectData *coo_myclass() NEVER_INLINE;

クラスはC++ネイティヴのクラスを利用。

それをラップする型に入れている。

ただし、メソッド呼び出しなどは自前で

メソッドを追跡している。

多分、magic methodや

リフレクション対策だと思われる。

継承

<?php

class baseclass

{

private function prifunc($a)

{

return $a + 1;

}

protected function protfunc($a)

{

return $a + 1;

}

public function pubfunc($a)

{

return $a + 1;

}

}

class myclass extends baseclass

{

public function pubfunc($a)

{

return $this->protfunc( $a + 2 ); //$a + 3

}

}

$class = new myclass();

$a = $class->pubfunc(10);

var_dump($a);

/* preface starts */

extern CallInfo ci_;

/* preface finishes */

/* SRC: test11.php line 3 */

IMPLEMENT_CLASS_NO_DEFAULT_SWEEP(myclass)

const InstanceOfInfo c_myclass::s_instanceof_table[] = {

{0x124B454009539DD2LL,1,"myclass",&cw_myclass},

};

const int c_myclass::s_instanceof_index[] = {

1,

0,-1,

};

CallInfo c_myclass::ci_pubfunc((void*)&c_myclass::i_pubfunc, (void*)&c_myclass::ifa_pubfunc, 1, 4, 0x0000000000000000LL);

Variant c_myclass::i_pubfunc(MethodCallPackage &mcp, CArrRef params) {

return invoke_meth_few_handler(mcp, params, &ifa_pubfunc);

}

Variant c_myclass::ifa_pubfunc(MethodCallPackage &mcp, int count, INVOKE_FEW_ARGS_IMPL_ARGS) {

if (UNLIKELY(mcp.obj == 0)) {

return ObjectData::ifa_dummy(mcp, count, INVOKE_FEW_ARGS_PASS_ARGS, ifa_pubfunc, coo_myclass);

}

c_myclass *self ATTRIBUTE_UNUSED (static_cast<c_myclass*>(mcp.obj));

if (UNLIKELY(count < 1)) throw_missing_arguments("myclass::pubfunc", count+1);

CVarRef arg0(UNLIKELY(count <= 0) ? null_variant : a0);

return (self->t_pubfunc(arg0));

}

const MethodCallInfoTable c_myclass::s_call_info_table[] = {

{ 0x4A7B5BE10021188ALL, 1, 7, "pubfunc", &c_myclass::ci_pubfunc },

{ 0, 1, 0, 0 }

};

const int c_myclass::s_call_info_index[] = {

1,

0,-1,

};

const ObjectStaticCallbacks cw_myclass = {

(ObjectData*(*)(ObjectData*))coo_myclass,

c_myclass::s_call_info_table,c_myclass::s_call_info_index,

c_myclass::s_instanceof_table,c_myclass::s_instanceof_index,

&c_myclass::s_class_name,

&c_myclass::os_prop_table,0,0,0,0x0

};

/* SRC: test11.php line 7 */

Numeric c_myclass::t_pubfunc(CVarRef v_a) {

INSTANCE_METHOD_INJECTION_ROOTLESS(myclass, myclass::pubfunc);

INTERCEPT_INJECTION("myclass::pubfunc", array_createvi(1, toVPOD(v_a)), r);

return ((v_a + m_privar) + m_pubvar);

}

namespace hphp_impl_splitter {}

ObjectData *coo_myclass() {

return NEWOBJ(c_myclass)();

}

Variant pm_php$test11_php(bool incOnce, LVariableTable* variables, Globals *globals) {

PSEUDOMAIN_INJECTION(run_init::test11.php, pm_php$test11_php);

LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;

Variant &v_class ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ssc82dbd12, "class")) : g->GV(class);

Variant &v_a ATTRIBUTE_UNUSED = (variables != gVariables) ? variables->get(NAMSTR(s_ss27b9150a, "a")) : g->GV(a);

{

LINE(13,0);

const p_myclass &tmp0((p_myclass(((c_myclass*)coo_myclass()))));

v_class = tmp0;

}

{

LINE(14,0);

MethodCallPackage mcp0;

CVarRef obj0 = v_class;

mcp0.methodCall((obj0), NAMSTR(s_ss758adc76, "pubfunc"), 0x4A7B5BE10021188ALL);

const CallInfo *cit0 ATTRIBUTE_UNUSED = mcp0.ci;

Variant tmp1(((mcp0.ci->getMeth1Args())(mcp0, 1, NAMVAR(s_svi542bad8b, 10LL))));

v_a.assignVal(tmp1);

}

LINE(16,(x_var_dump(1, v_a)));

return true;

}

namespace hphp_impl_splitter {}

// Class tables

static const int64 cpt_static_inits[] = {

(int64)&NAMVAR(s_svid7a79683, 20LL),

(int64)&NAMVAR(s_svi542bad8b, 10LL),

};

static const ClassPropTableEntry cpt_table_entries[] = {

{0x1CA3E3D9527D20FALL,0,0,0,68,4,GET_PROPERTY_OFFSET(c_myclass, m_pubvar),&NAMSTR(s_ssa42bbae9, "pubvar") },

{0x27731D65F3F36A14LL,-1,1,0,68,4,GET_PROPERTY_OFFSET(c_myclass, m_privar),&NAMSTR(s_ss3b22d7c5, "privar") },

};

static const int cpt_hash_entries[] = {

// myclass hash

-1,-1,0,-1,1,-1,-1,-1,

// myclass lists

-1,

-1,

-1,

};

const ClassPropTable c_myclass::os_prop_table = {

7,1,-1,-1,-1,-1,9,0,

cpt_hash_entries+0,0,cpt_table_entries+0,cpt_static_inits

};

クラス

クラスの実態は、

すべて 本体のコードが書かれている cpp に書かれます。

とても、巨大なので、割愛します。

基本的に、

クラス変換と同じです。

変換された

ファイル郡に、

cls というのが増える。

A インスタンス構築

$class = new myclass();

FORWARD_DECLARE_CLASS(baseclass);

extern const ObjectStaticCallbacks cw_baseclass;

class c_baseclass : public ObjectData {

public:

// Properties

// Class Map

DECLARE_CLASS_NO_SWEEP(baseclass, baseclass, ObjectData)

c_baseclass(const ObjectStaticCallbacks *cb = &cw_baseclass) : ObjectData(cb, false) {}

public: Numeric t_prifunc(CVarRef v_a);

public: Numeric t_protfunc(CVarRef v_a);

public: virtual Variant t_pubfunc(Variant v_a);

DECLARE_METHOD_INVOKE_HELPERS(prifunc);

DECLARE_METHOD_INVOKE_HELPERS(protfunc);

DECLARE_METHOD_INVOKE_HELPERS(pubfunc);

};

ObjectData *coo_baseclass() NEVER_INLINE;

ベースクラスの

clsか増えました。

B メソッド呼び出し

$a = $class->pubfunc(10);

C メソッド名は自前名前解決

magic method対策?

クラス定義だけ書いてある。

実態は、 test11.cpp にまとめられる

A 全部 public になってる。

private function prifunc($a)

{

return $a + 1;

}

protected function protfunc($a)

{

return $a + 1;

}

public function pubfunc($a)

{

return $a + 1;

}

Zzzzz....

magic method

staticメソッド

この節を書こうとした人は途中で

寝てしまいました。

global変数

この節を書こうとした人は途中で

寝てしまいました。

HipHop Virtual Machine

動的言語は、

本質的に静的言語より遅いんじゃない。

ただ研究が遅れているだけだ。

hiphop php がジェネレートする

C++ のコードについて簡単に見てきました。

結構頑張った最適化が

行われていると思います。

現在、 hiphop PHPは、

PHPをC++に変換し gcc でコンパイルしてます。

ただ、コンパイルに時間がかかったりするので、

それを解決する、 JIT が作られているそうです。

Hiphop VirtualMachineは、

インタプリタに比べ1.6倍早く、

コンパイラに比べて0.6倍の速度だそうです。

今後、その差は縮まっていくそうです。

まとめ

という名言があるそうです。

今後の、研究に期待したいところですね。

http://www.publickey1.jp/blog/11/phpjithiphop_virtual_machinefacebook.html

Learn more about creating dynamic, engaging presentations with Prezi