摘要:前言本文簡要介紹虛擬機解釋執行字節碼的基本邏輯以及相關的數據結構,關于源代碼的下載,編譯,調試可以參考之前的系列文章我們來看看執行一個簡單的腳本的調用棧由于是執行腳本文件,所以調用了函數,最終調用函數和其它語言編寫的系統軟件類似,函數中
前言
本文簡要介紹 zend 虛擬機解釋執行字節碼的基本邏輯以及相關的數據結構,關于 PHP 源代碼的下載,編譯,調試可以參考之前的系列文章
execute_ex我們來看看執行一個簡單的腳本 test.php 的調用棧
execute_ex @ zend_vm_execute.h : 411 zend_execute @ zend_vm_execute.h : 474 php_execute_script @ zend.c : 1474 do_cli @ php_cli.c : 993 main @ php_cli.c : 1381
由于是執行腳本文件,所以 do_cli 調用了 php_execute_script 函數,最終調用 execute_ex 函數:
ZEND_API void execute_ex(zend_execute_data *ex) { DCL_OPLINE #ifdef ZEND_VM_IP_GLOBAL_REG const zend_op *orig_opline = opline; #endif #ifdef ZEND_VM_FP_GLOBAL_REG zend_execute_data *orig_execute_data = execute_data; execute_data = ex; #else zend_execute_data *execute_data = ex; #endif LOAD_OPLINE(); ZEND_VM_LOOP_INTERRUPT_CHECK(); while (1) { #if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG) int ret; #endif #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG) ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); if (UNEXPECTED(!OPLINE)) { #else if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0)) { #endif #ifdef ZEND_VM_FP_GLOBAL_REG execute_data = orig_execute_data; # ifdef ZEND_VM_IP_GLOBAL_REG opline = orig_opline; # endif return; #else if (EXPECTED(ret > 0)) { execute_data = EG(current_execute_data); ZEND_VM_LOOP_INTERRUPT_CHECK(); } else { # ifdef ZEND_VM_IP_GLOBAL_REG opline = orig_opline; # endif return; } #endif } } zend_error_noreturn(E_CORE_ERROR, "Arrived at end of main loop which shouldn"t happen"); }
和其它 C 語言編寫的系統軟件類似,函數中使用了大量的宏定義,通過宏定義的名字還是能大概看出其用途
DCL_OPLINE,變量聲明
LOAD_OPLINE(),加載指令字節碼
ZEND_VM_LOOP_INTERRUPT_CHECK(),interrupt 檢測
while (1) 循環,調用指令的處理函數 OPLINE->handler
op_code_handler 總結文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22316.html
摘要:前言字節碼生成編譯的代碼主要集中在,文件中包含大量的函數,基本上一個函數對應語法規則文件一個非終結符,函數是所有函數的入口數據結構結構體是字節碼抽象結構體并沒有像名字那樣簡單,它包含了大量的字段供虛擬機在運行時使用一如既往的簡單,直觀,相比 前言 字節碼生成(編譯)的代碼主要集中在 zend_compile.c ,文件中包含大量的 zend_compile_xxx 函數,基本上一個函數...
摘要:前言本文通過分析這個語句的編譯和執行來窺探解釋執行邏輯準備參考之前的系列文章,在環境下下載,編譯源代碼將代碼導入中編輯運行選項,增加運行參數設置斷點開始調試是一個測試腳本,放在目錄下,中只包含一條簡單的賦值語句調用堆棧參考之前的系列文章 前言 本文通過分析 $a=1 這個 PHP 語句的編譯和執行來窺探 php-cli 解釋執行邏輯 準備 參考之前的系列文章,在 ubuntu 環境下...
摘要:前言使用和進行語法分析和詞法分析,本文以語法定義文件為起點,使用等命令行工具搜索相關源碼,以此來展示探索語法分析源碼思路語法定義文件在源代碼根目錄下通過命令查找文件我們找到了文件,里面定義了腳本的語法語法分析樹節點類型在查看具體的語法規則 前言 php 使用 lex 和 bison 進行語法分析和詞法分析,本文以 bison 語法定義文件為起點,使用 find, grep 等命令行工具...
摘要:前言函數默認構建目標為,相關代碼在目錄下,文件中能夠找到入口函數,大概流程如下命令行參數處理初始化清理工作語言系統編程常用手法,通過中聲明函數指針類型的字段來實現類似面向對象中抽象類的概念,在文件中可以找到該結構體的定義,這里只列出部分 前言 php cli main 函數 configure & make 默認構建目標為 php-cli,相關代碼在 sapi/cli 目錄下,php_...
摘要:前言本文從函數定義的語法規則開始,簡要介紹解釋器如何編譯函數定義函數對應的節點為了看起來清楚一些,我們將語法規則定義與語法動作分開根據語法動作,這條函數定義規則會創建一個類型的結點,我們來看看方法是一個通用的方法,通 前言 本文從函數定義的語法規則開始,簡要介紹 PHP 解釋器如何 編譯 函數定義 函數對應的 AST 節點 為了看起來清楚一些,我們將 語法規則定義 與 語法動作分開: ...
閱讀 666·2021-11-15 11:37
閱讀 4105·2021-09-09 09:34
閱讀 3559·2019-08-30 15:52
閱讀 2602·2019-08-29 14:03
閱讀 2842·2019-08-26 13:36
閱讀 1587·2019-08-26 12:16
閱讀 1592·2019-08-26 11:45
閱讀 3488·2019-08-23 18:41