More Related Content
PHP と SAPI と ZendEngine3 と CPANの依存モジュールをもう少し正しく検出したい php and sapi and zendengine2 and... What's hot (20)
How to debug a perl script using gdb Good Parts of PHP and the UNIX Philosophy はりぼて OS で ELF なアプリを起動してみた Viewers also liked (20)
Writing php extensions in golang N対1 レプリケーション + Optimizer Hint SQLite2と3のエスケープ関数の違いとその対策 signal の話 或いは Zend Signals とは何か OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた realpathキャッシュと OPcacheの面倒すぎる関係 偶然にも500万個のSSH公開鍵を手に入れた俺たちは PHP7で変わること ——言語仕様とエンジンの改善ポイント 20141011 mastering mysqlnd Sinatra風マイクロフレームワークで始めるPython マスタN対スレーブ1レプリケーションの作り方 ~あれから~ Testing PHP extension on Travis CI Similar to php7's ast (20)
C# 7.2 with .NET Core 2.1 ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja) asm.js x emscripten: The foundation of the next level Web games Lisp batton - Common LISP 中3女子が狂える本当に気持ちのいい constexpr 「Html sql」で図書館hpにアクセスしてみよう Elasticsearch入門 pyfes 201207 Lisp Tutorial for Pythonista : Day 3 最新PHP事情 (2000年7月22日,PHPカンファレンス) Write good parser in perl Cookpad Summer Intern 2015 - Programming Paradigm Dalvikバイトコードリファレンスの読み方 改訂版 More from do_aki (17)
Tritonn から Elasticsearch への移行話 MySQL Casual Talks 7 「N:1 レプリケーション ~進捗どうですか?~」 PHP から Groonga を使うにはこんなコードになるよ! N:1 Replication meets MHA セキュアそうでセキュアじゃない少しセキュアな気分になれるmysql_config_editor A bridge between php and ruby Ruby and comparison_and...php Ruby enumerable source code reading php7's ast
- 6. 字句解析
• ソースコードをトークンに分解
• トークン := 意味を持つ最小単位
<?php
function hello ( ) {
echo ‘HELLO WORLD’ ;
}
T_OPEN_TAG
T_FUNCTION T_STRING ( ) {
}
T_ECHO
T_CONSTANT
_ENCAPSED_STRING
;
- 8. php5 の コンパイルプロセス
字句解析 構文解析+コード生成
php7 の コンパイルプロセス
字句解析 構文解析 コード生成
zendlex -> TOKEN zendparse -> OPCODE
zendlex -> TOKEN zendparse -> AST zend_compile_stmt -> OPCODE
- 9. php5 の コンパイルプロセス
字句解析 構文解析+コード生成
php7 の コンパイルプロセス
字句解析 構文解析 コード生成
zendlex -> TOKEN zendparse -> OPCODE
zendlex -> TOKEN zendparse -> AST zend_compile_stmt -> OPCODE
構文解析で AST を構築し、
AST から OPCODE を生成
- 12. zend_ast (基本形)
• Zend/zend_ast.h / Zend/zend_ast.c
typedef uint16_t zend_ast_kind;
typedef uint16_t zend_ast_attr;
struct _zend_ast {
zend_ast_kind kind;
/* Type of the node (ZEND_AST_* enum constant) */
zend_ast_attr attr;
/* Additional attribute, use depending on node type */
uint32_t lineno;
/* Line number */
zend_ast *child[1];
/* Array of children (using struct hack) */
};
typedef struct _zend_ast zend_ast; // <- Zend/zend_types.h
Zend/zend_ast.h より 一部見やすさのために改変
- 13. zend_ast_kind
• ZEND_AST_*
• 全98種 (php7.0.0 RC7 時点)
• 大まかに分類して4系統
– 特殊ノード ZEND_AST_ZVAL / ZEND_AST_ZNODE
– 定義ノード ZEND_AST_CLASS など
– リストノード ZEND_AST_STMT_LIST など
– 通常ノード ZEND_AST_VAR, ZEND_AST_FOREACH など
- 14. 特殊ノード (special nodes)
• ZEND_AST_ZVAL
– zval を包含するノード
– リテラル や 変数名、呼び出し関数名等
– 常にリーフ
• ZEND_AST_ZNODE
– 構文解析の過程では一切利用されない
– コンパイル時に一時的に使われる
– あまり詳しく追ってない
- 15. 定義ノード (declaration nodes)
• doc_comment を保持
• 常に4つの子ノードを確保 (NULL の場合もある)
• ZEND_AST_FUNC_DECL 関数定義
• ZEND_AST_CLOSURE 無名関数定義
• ZEND_AST_METHOD メソッド定義
• ZEND_AST_CLASS クラス、無名クラス、
インタフェース、トレイト定義
- 16. リストノード (list nodes)
• 配下に複数のノードを格納するノード
• ZEND_AST_STMT ステートメントを格納(ASTのROOT)
• ZEND_AST_IF if文の各条件とブロックを格納
• ZEND_AST_ARRAY 配列
• その他、 ZEND_AST_ARG_LIST 等 “,” を
使って列挙するところは大体ここに分類
- 17. 通常ノード(standard nodes)
• 0 child nodes
– ZEND_AST_MAGIC_CONST / ZEND_AST_TYPE
– __LINE__ とか / callable とか
• 1 child nodes
– 変数、定数、キャスト、単項演算子 等
• 2 child nodes
– 配列の要素参照、関数呼び出し、代入、2項演算子、new など
• 3 child nodes
– メソッド呼び出し、プロパティ定義、3項演算子 など
• 4 child nodes
– ZEND_AST_FOR / ZEND_AST_FOREACH
– for (1, 2, 3) { 4 } / foreach (1 as 2 => 3) {4}
- 19. AST Hook Function
• AST構築直後 (OPCODE 生成前)に呼ばれる
• AST そのものが渡される -> 改変可能
• 将来的には、このフックポイントを利用した、最
適化やフィルタを行う拡張が生まれるのでは
• https://wiki.php.net/rfc/parser-
extension-api
typedef void (*zend_ast_process_t)(zend_ast *ast);
extern ZEND_API zend_ast_process_t zend_ast_process;
- 24. FizzBuzz
for ($i = 1; $i <= 100; $i++) {
if ($i % 3 == 0 && $i % 5 == 0) {
echo 'FizzBuzz';
} elseif ($i % 5 == 0) {
echo 'Buzz';
} elseif ($i % 3 == 0) {
echo 'Fizz';
} else {
echo $i;
}
echo PHP_EOL;
}
- 27. 字句解析器の状態 (全10状態)
• 初期状態 (INITIAL)
• PHP Script (ST_IN_SCRIPTING)
• 文字列解析のための状態
– ST_DOUBLE_QUOTES
– ST_BACKQUOTE
– ST_HEREDOC
– ST_END_HEREDOC
– ST_NOWDOC
– ST_LOOKING_FOR_VARNAME (${)
• プロパティ参照解析のための状態
– ST_LOOKING_FOR_PROPERTY ($xxx->)
• 配列要素参照解析のための状態
– ST_VAR_OFFSET
Editor's Notes
- #13: ほかにも zval, list, decl といった構造体もあるが、 kind, attr を持ち、lineno を包含し、 0以上の子ノードを持つ というのは同じ