PHP7核心剖析5之 PHP代碼的編譯

來源:互聯網
上載者:User
本篇文章的內容介紹的是關於PHP7核心剖析5之 PHP代碼的編譯 ,現在分享給大家,有需要的朋友可以參考一下

1.PHP代碼的編譯

PHP的解析過程任務就是將PHP代碼轉化為opcode數組,代碼裡的所有資訊都儲存在opcode數組中,然後將opcode數組交給zend引擎執行,opcode就是核心具體執行的命令,比如賦值、加減操作、函數調用等,每一條opcode都對應一個處理handle,這些handler是提前定義好的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;
執行個體:$a = 123;$b = "hi~";echo $a,$b;


4.zend_op_array

zend_op *opcodes; //opcode指令數組zval *literals; //字面量(常量)數組,這些都是在PHP代碼定義的一些值zend_string **vars; //PHP變數名數組,根據變數編號可以擷取相應的變數
//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; //傳回值類型};


5.handler處理函數

handler為每條opcode對應的C語言編寫的處理過程,所有opcode對應的處理流程定義在zend_vm_def.h中,opcode的處理過程有三種不同的提供形式:CALL、SWITCH、GOTO,預設為CALL
CALL:把每種opcode負責的工作封裝成不同的function,然後執行器迴圈調用執行SWITCH:把所有的處理方式寫到一個switch下,然後通過case不同的opcode執行具體的操作GOTO:把所有opcode的處理方式通過C語言裡面的label標籤區分開,然後執行器執行的時候goto到相應的位置處理


6.抽象文法樹->Opcodes

void zend_compile_top_stmt(zend_ast *ast){    ....    if (ast->kind == ZEND_AST_STMT_LIST) { //第一次進來一定是這種類型        zend_ast_list *list = zend_ast_get_list(ast);        uint32_t i;        for (i = 0; i < list->children; ++i) {            zend_compile_top_stmt(list->child[i]);//list各child語句相互獨立,遞迴編譯        }        return;    }    //各語句編譯入口    zend_compile_stmt(ast);    ....}1.zend_compile_top_stmt接收文法樹,首先判斷節點類型是否為ZEND_AST_STMT_LIST(表示當前節點下有多個獨立的節點),若是則進行遞迴2.當遞迴結束後,調用zend_compile_stmt進行編譯成opcodes

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.