이 글의 내용은 PHP7 커널 분석 5에서 PHP 코드를 컴파일하는 내용입니다. 이제 여러분과 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다
1. PHP 코드 컴파일
PHP 파싱 작업 프로세스는 PHP 코드를 opcode 배열로 변환합니다. 코드의 모든 정보는 opcode 배열에 저장되고 opcode 배열은 실행을 위해 zend 엔진으로 전달됩니다. 할당, 덧셈 및 뺄셈 연산, 함수 호출 등 각각의 opcode는 처리 핸들에 해당하며 이러한 핸들러는 미리 정의된 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 노드 구조
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;
4.zend_op_array
实例: $a = 123; $b = "hi~"; echo $a,$b;
zend_op *opcodes; //opcode指令数组 zval *literals; //字面量(常量)数组,这些都是在PHP代码定义的一些值 zend_string **vars; //PHP变量名数组,根据变量编号可以获取相应的变量
5.handler 처리 함수
handler는 각 opcode에 해당하는 C 언어로 작성된 처리 프로세스이며, 모두에 해당하는 처리 절차 Opcodes zend_vm_def.h에 정의된 opcode 처리 프로세스에는 CALL, SWITCH, GOTO의 세 가지 형식이 있습니다. 기본 방법은 CALL
//opcode指令结构 struct _zend_op { const void *handler; //指令执行handler znode_op op1; //操作数1 znode_op op2; //操作数2 znode_op result; //返回值 uint32_t extended_value; uint32_t lineno; zend_uchar opcode; //opcode指令 zend_uchar op1_type; //操作数1类型 zend_uchar op2_type; //操作数2类型 zend_uchar result_type; //返回值类型 };
6입니다. 추상 구문 트리 ->Opcodes
CALL:把每种opcode负责的工作封装成不同的function,然后执行器循环调用执行 SWITCH:把所有的处理方式写到一个switch下,然后通过case不同的opcode执行具体的操作 GOTO:把所有opcode的处理方式通过C语言里面的label标签区分开,然后执行器执行的时候goto到相应的位置处理
PHP7 커널 분석의 지역 변수, 전역 변수, 상수 4
위 내용은 PHP7 커널 분석 5 PHP 코드 컴파일의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!