亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP-Zend引擎剖析之Hello World(二)

2019-11-06 06:11:52
字體:
來源:轉載
供稿:網友

前言

這一次,我圍繞Hello World來展開Zend虛擬機的執行過程。Hello World的php版本:
<?php     echo 'Hello World';?>
前一篇文章聊到的詞法分析階段就會把上邊的腳本分析出一個Token序列:我們得到一個Token序列:T_OPEN_TAG, T_ECHO, T_CONSTANT_ENCAPSED_STRING, ';', T_CLOSE_TAG。但在Zend虛擬機執行的過程中,是怎么去分析這個Token序列的?

跟蹤運行軌跡

我們還是從命令行入手,在$PHPSRC/sapi/cli/php_cli.c中的do_cli函數里邊接收了命令行的參數輸入(php -f HelloWorld.php表示執行HelloWorld.php文件)。我們追蹤到$PHPSRC/main/main.c里邊有php_execute_script的定義,緊接著調用了zend_execute_scripts() <Zend/Zend.c>,在zend_execute_scripts的定義里邊我們發現了:
 EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);zend_execute(EG(active_op_array) TSRMLS_CC);
首先通過zend_compile_file把文件解析成opcode中間代碼(這一步會經過詞法語法分析),然后用zend_execute執行這個生成的中間代碼(這里就是所謂的運行時)。這里很像C語言的編譯方式,先編譯成匯編,然后再轉成機器碼,這里的opcode就類似C語言編譯過程中生成的匯編。還可以延伸出一個思路,因為每次解析PHP文件時,都需要經過詞法語法分析得到對應的opcode,其實在腳本文件不變化的時候,生成的opcode也不需要變化,因此為了減少PHP腳本的執行時間,可以把腳本的opcode緩存起來(例如緩存在共享內存里邊)。我給出一個流程圖,然后隨著這個流程圖,看看Zend做了些什么事情:我們先看看如何編譯出opcode的。

詞法語法分析->opcode

從上節知道我們通過zend_compile_file(實際上為compile_file()<定義在Zend/zend_language_scanner.c的555行>)把腳本文件編譯出opcode,實際上通過zendparse這個API來編譯出opcode的。PHP的語法解析器是用bison來生成,安裝完之后在$PHPSRC/Zend目錄運行:
bison -o zend_language_parser.c zend_language_parser.y
在Zend目錄下就會生成語法解析器zend_language_parser.c。而這里的zendparse就是語法解析器里邊的yyparse!我們忽略掉生成的語法解析器,就Hello World的例子來跟蹤一下bison的聲明文件(我去掉不想關的聲明):
start:top_statement_list     { zend_do_end_compilation(TSRMLS_C); };top_statement_list:top_statement_list  { zend_do_extended_info(TSRMLS_C); } top_statement { HANDLE_INTERACTIVE(); }|     /* empty */;top_statement:statement                              { zend_verify_namespace(TSRMLS_C); };statement:unticked_statement { DO_TICKS(); }|     T_STRING ':' { zend_do_label(&$1 TSRMLS_CC); };unticked_statement:|     T_ECHO echo_ex語法分析從start開始,自上而下的分析,一個PHP腳本就是對應一個top_statement_list,接著分成每一行一條語句statement,發現echo 'Hello World'是一條unticked_statement(留意一下echo_expr_list的聲明, 我們還可以發現語法上是支持echo 'Hello', ' World'的)。最后遞歸到T_CONSTANT_ENCAPSED_STRING狀態就結束了這一行的語法解析。在這里我們忽略掉編譯原理在語法分析階段是怎么去做回溯等等東西,我們關注一下Zend引擎自身的的問題。在規則后邊的塊"{}"里邊的代碼就是用來處理掃描到此規則時的動作,可以看到echo的執行是調用了zend_do_echo函數的。在動作聲明的塊里邊我們看到了$$, $1,$2,$3等,這些對應的就是該條規則里邊的返回值,參數1,參數2……,這里的返回值以及參數都是YYSTYPE類型,這個類型在43行里邊有定義:#define YYSTYPE znode。znode的定義在zend_compile.h里邊:留意到zend_op這個結構,于是跟蹤發現這個就是最后每條語句對應的opcode結構了?。。?!opcode的結構跟匯編有很大的相似之處,一個操作符,兩個操作數。在Zend引擎中,每個opcode主要的東西就是那個handler,一會我們會看到Zend里邊是怎么生成這個handler的。到了這里先Hold住一下,回過頭,我們看一下Hello World這個例子生成的opcode是什么。裝上vld,然后運行:php -dvld.active=1 HelloWorld.php,我們就可以看到這個PHP文件編譯出來的opcode列表了:可以看到echo這個語句的opcode類型是ECHO,同時return沒有返回值,只有一個操作數"Hello World"?,F在經過了語法分析,我們對每條語句都編譯出了opcode,Zend就會把它放入一個op_array里邊(其實就是一個opcode的列表)?;剡^頭我們看一下zend_do_echo做了什么事情:首先通過get_next_op在當前的op_array的最后邊生成一條opcode,然后設置其opcode類型是ZEND_ECHO,然后設置它的第一個參數op1,同時標記第二個參數op2是不需要使用的(unused的)。經過了這么多步驟之后我們得到了一個op_array的列表,這個列表里邊的每一條opcode都綁定了自己的類型,接著我們看一下每個opcode節點是如何綁定handler的。zend_vm_def.h定義了ZEND_ECHO的handler,留意到這里的40,一會需要用到,因為echo的參數可以有幾種:常量,變量等等,所以對應著不同的handler在zend_vm_execute.h定義了opcode對應的所有的handler,我們只關注echo相關的handler,注意到其中的代碼:
void zend_init_opcodes_handlers(void){static const opcode_handler_t labels[] = {//40913行ZEND_ECHO_SPEC_CONST_HANDLER,//41914行ZEND_ECHO_SPEC_CONST_HANDLER,ZEND_ECHO_SPEC_CONST_HANDLER,ZEND_ECHO_SPEC_CONST_HANDLER,ZEND_ECHO_SPEC_CONST_HANDLER};
請花費短暫的時間先記住這里的labels以及行數。發現了獲取handler的方法最后邊return語句的計算,根據前面說的echo的opcode是40(假設兩個參數op1,op2的type都是0),于是乎其對應的handler就是:zend_opcode_handlers[40*25+0*5+0*5] = zend_opcode_handlers[1000] = labels[1000] = ZEND_ECHO_SPEC_CONST_HANDLER(怎么來的?因為:41914行-40913行-1=1000)。

虛擬機執行opcode

前邊我們已經解釋了zend_compile_file把一個腳本編譯成一個opcode的list:
 EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);zend_execute(EG(active_op_array) TSRMLS_CC);
在這之后,Zend引擎用zend_execute執行返回的opcode。我們定位到了zend_execute最后執行到Zend/zend_vm_execute.h的337行:可以看到,虛擬機執行的時候會循環當前的opcode列表,然后調用每一行opcode的handler,根據handler返回值確定下一步做啥(例如函數調用等,以后再展開)。在這篇文章中我們只關注跟Hello World相關的東西,我們前邊知道echo的handler是ZEND_ECHO_SPEC_CONST_HANDLER,通過最后的定位你會發現其調用了:
zend_write = (zend_write_func_t) utility_functions->write_function;
這里的utility_functions里邊包含了一些基礎的handler,每個sapi接入層自己修改了這里的基礎函數指針,例如在命令行模式下,最后調用到了sapi_cli_single_write:
源碼中,我們看到了最后的寫操作就是調用了write/fwrite寫入到標準輸出流(也即是終端屏幕上)。

結語

最后根據前邊的過程,再展開一下流程圖就是:
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产31久久久久久| 在线电影av不卡网址| 亚洲精品一区二区久| 日本久久久久久| yellow中文字幕久久| 亚洲人午夜精品免费| 中文字幕久久精品| 91久久精品一区| 色综合伊人色综合网| 国产精品免费一区豆花| 最好看的2019的中文字幕视频| 97免费视频在线播放| 国产在线98福利播放视频| 国产精品69av| 一区二区三区黄色| 国产欧美一区二区| 国产亚洲精品久久久久久777| 国产91免费观看| 国产69精品久久久| 亚洲丁香久久久| 亚洲欧美日韩一区在线| 欧美成人免费小视频| 亚洲福利在线观看| 最近2019中文字幕一页二页| 国产在线拍偷自揄拍精品| 亚洲成人av在线| 久久精品99久久久香蕉| 久久久久久久久久久亚洲| 亚洲片国产一区一级在线观看| 亚洲最大福利网站| 亚洲视频在线看| 午夜精品在线观看| 日韩精品视频免费在线观看| 亚洲天堂网站在线观看视频| 久久综合伊人77777| 欧美电影免费看| 大量国产精品视频| 国内精品中文字幕| 中文字幕v亚洲ⅴv天堂| 91久久在线观看| 国产精品69精品一区二区三区| 欧美中文字幕精品| 成人av在线网址| 亚洲最大的成人网| 国产精品激情av电影在线观看| 日韩国产精品亚洲а∨天堂免| 国产亚洲成精品久久| 57pao国产精品一区| 国产精品久久久久7777婷婷| 国产精品亚洲网站| 国产精品美腿一区在线看| 日韩av一区在线观看| 欧美成人在线网站| 成人情趣片在线观看免费| 91视频国产一区| 亚洲加勒比久久88色综合| 亚洲成人网久久久| 国产精品91久久久| 久久偷看各类女兵18女厕嘘嘘| 91国产在线精品| 国产日韩在线看片| 欧美电影《睫毛膏》| 97精品一区二区视频在线观看| 国外成人在线直播| 欧美理论片在线观看| 91色琪琪电影亚洲精品久久| 色偷偷9999www| 不卡av电影在线观看| www.亚洲男人天堂| 欧美大成色www永久网站婷| x99av成人免费| 日本欧美国产在线| 日本国产高清不卡| 亚洲欧美日韩一区二区在线| 国产精品亚洲欧美导航| 亚洲最新中文字幕| 中文字幕国产日韩| 日韩精品视频在线观看网址| 欧美色视频日本版| 亚洲自拍偷拍色图| 97在线日本国产| 亚洲精品一区久久久久久| 国产精品久久久久久婷婷天堂| 日韩av免费在线看| 久久久免费高清电视剧观看| 91夜夜揉人人捏人人添红杏| 久久天天躁狠狠躁夜夜躁| 国产精品欧美日韩一区二区| 91精品国产99久久久久久| 久久久999国产精品| 2023亚洲男人天堂| 亚洲摸下面视频| 欧美激情视频网址| 日韩av综合网| 九九视频直播综合网| 欧美www视频在线观看| 日韩69视频在线观看| 精品国产欧美一区二区五十路| 亚洲成色999久久网站| 亚洲人免费视频| 国产精品爽黄69| 69久久夜色精品国产69| 国产精品va在线播放我和闺蜜| 久久福利视频导航| 国产精品视频地址| 亚洲人a成www在线影院| 欧美猛交ⅹxxx乱大交视频| 欧美日韩视频免费播放| 久久久免费在线观看| 欧美主播福利视频| 国产精品色婷婷视频| 久久99国产精品久久久久久久久| 国内精品久久久久久中文字幕| 欧美视频专区一二在线观看| 日韩中文在线不卡| 爽爽爽爽爽爽爽成人免费观看| 欧美在线一区二区三区四| 国产精品青青在线观看爽香蕉| 成人黄色在线免费| 欧美一级电影免费在线观看| 欧美午夜激情小视频| 高潮白浆女日韩av免费看| 欧美在线视频免费| 91在线观看免费高清完整版在线观看| 日韩不卡中文字幕| 日韩久久精品电影| 亚洲综合在线中文字幕| 欧美做爰性生交视频| 久久艹在线视频| 日韩av在线电影网| 91av视频在线观看| 91情侣偷在线精品国产| 亚洲精品av在线| 中文字幕欧美精品日韩中文字幕| 欧美又大粗又爽又黄大片视频| 国产精品狼人色视频一区| 亚洲社区在线观看| 狠狠色香婷婷久久亚洲精品| 久久精品国产99国产精品澳门| 欧美性视频精品| 国产精品久久久久久中文字| 人人做人人澡人人爽欧美| 国产精品69av| 久久久久久尹人网香蕉| 国产区精品在线观看| 在线观看成人黄色| 国产日韩专区在线| 国语自产在线不卡| 国产精品扒开腿做爽爽爽的视频| 91精品国产综合久久香蕉的用户体验| 超在线视频97| 国产精品国产三级国产专播精品人| 亚洲色图国产精品| 日韩视频在线免费观看| 久久精彩免费视频| 尤物九九久久国产精品的分类| 久久噜噜噜精品国产亚洲综合| 国产精品va在线播放| 欧美黑人一区二区三区| 亚洲伊人久久大香线蕉av| 2019亚洲日韩新视频| 亚洲精品成人网| 久热爱精品视频线路一| 日韩在线播放av|