この記事の内容は、PHP7 カーネル分析 5 での PHP コードのコンパイルに関するものです。必要な友達はそれを参照してください。
1 PHP 解析のタスク。プロセスは、PHP コードをオペコード配列に変換します。コード内のすべての情報はオペコード配列に保存され、オペコード配列は実行のために zend エンジンに渡されます。代入、加減算、関数呼び出しなどの各オペコードは処理ハンドルに対応しており、これらのハンドラはあらかじめ定義されたC関数です。
2.PHPコード->抽象構文ツリー(AST)
PHP使用re2c、bison完成这个阶段的工作: re2c: 词法分析器,将输入分割为一个个有意义的词块,称为token bison: 语法分析器,确定词法分析器分割出的token是如何彼此关联的
词法、语法解析过程
1.yyparse(zendparse)调用yylex(zendlex),当读取到一个合法的token时,返回值为token类型
2.yylex调用lex_scan读取合法的token值
3.yyparse将token类型与token值构造抽象语法树,最后将根节点保存到CG(compiler_globals ,Zend编译器相关的全局变量)的ast中
3.ASTノード
れぇぇぇぇぇぇ
4.zend_op_array
typedef struct _zend_ast zend_ast;
//普通节点类型
struct _zend_ast {
zend_ast_kind kind; //节点类型
zend_ast_attr attr; //节点附加属性
uint32_t lineno; //行号
zend_ast *child[1]; //子节点数组
};
//普通节点类型,但有子节点的个数
typedef struct _zend_ast_list {
zend_ast_kind kind; //节点类型
zend_ast_attr attr; //节点附加属性
uint32_t lineno; //行号
uint32_t children; //子节点数量
zend_ast *child[1];//子节点数组
} zend_ast_list;
//函数、类的ast节点结构
typedef struct _zend_ast_decl {
zend_ast_kind kind; //节点类型
zend_ast_attr attr; //节点附加属性
uint32_t start_lineno; //开始行号
uint32_t end_lineno; //结束行号
uint32_t flags;
unsigned char *lex_pos;
zend_string *doc_comment;
zend_string *name;
zend_ast *child[4]; //类中会将继承的父类、实现的接口以及类中的语句解析保存在child中
} zend_ast_decl;
实例:
$a = 123;
$b = "hi~";
echo $a,$b;
5.handler処理関数
handlerは各オペコードに対応したC言語で書かれた処理プロセスであり、すべてのオペコードに対応するプロセスを実行するzend_vm_def.h で定義されているオペコード処理プロセスには、CALL、SWITCH、GOTO の 3 つの異なる形式があります。デフォルトのメソッドは CALL
zend_op *opcodes; //opcode指令数组 zval *literals; //字面量(常量)数组,这些都是在PHP代码定义的一些值 zend_string **vars; //PHP变量名数组,根据变量编号可以获取相应的变量
6 です。
PHP7 カーネル解析 4 ローカル変数、グローバル変数、定数
PHP7 カーネル解析 3 変数
以上がPHP7 カーネル分析 5 PHP コードのコンパイルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。