>  기사  >  백엔드 개발  >  PHP7 커널 분석 5 PHP 코드 컴파일

PHP7 커널 분석 5 PHP 코드 컴파일

不言
不言원래의
2018-04-13 15:02:201667검색

이 글의 내용은 PHP7 커널 분석 5에서 PHP 코드를 컴파일하는 내용입니다. 이제 여러분과 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다

1. PHP 코드 컴파일

PHP 파싱 작업 프로세스는 PHP 코드를 opcode 배열로 변환합니다. 코드의 모든 정보는 opcode 배열에 저장되고 opcode 배열은 실행을 위해 zend 엔진으로 전달됩니다. 할당, 덧셈 및 뺄셈 연산, 함수 호출 등 각각의 opcode는 처리 핸들에 해당하며 이러한 핸들러는 미리 정의된 C 함수입니다.

PHP7 커널 분석 5 PHP 코드 컴파일


2.PHP 코드->추상 구문 트리(AST)

PHP使用re2c、bison完成这个阶段的工作:
    re2c: 词法分析器,将输入分割为一个个有意义的词块,称为token
    bison: 语法分析器,确定词法分析器分割出的token是如何彼此关联的

PHP7 커널 분석 5 PHP 코드 컴파일

词法、语法解析过程

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;
rrree

PHP7 커널 분석 5 PHP 코드 컴파일


4.zend_op_array

PHP7 커널 분석 5 PHP 코드 컴파일

实例:
$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 커널 분석의 변수 3

PHP7 커널 분석 2 I/O 모델

​ ​

위 내용은 PHP7 커널 분석 5 PHP 코드 컴파일의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.