天天看點

v8世界探險(3) - v8的抽象文法樹結構v8世界探險(3) - v8的抽象文法樹結構

首先,我們還是先來看一下地圖:

v8世界探險(3) - v8的抽象文法樹結構v8世界探險(3) - v8的抽象文法樹結構

ast對象都是基于zone進行記憶體管理的,zone是多次配置設定臨時塊對象,然後可以一次性釋放掉。

我們看一下zone的定義,在src/zone.h中:

基于zone配置設定,v8封裝了zoneobject來作為ast對象的基類。

astnode繼承自zoneobject,是所有的語句、表達式和聲明的基類。

astnode的子類有4個大類:

statement: 語句

expression: 表達式

declaration: 聲明

module: es6新增的子產品

我們來一張astnode的圖,大家加深一下印象:

v8世界探險(3) - v8的抽象文法樹結構v8世界探險(3) - v8的抽象文法樹結構

declaration是astnode4大類中最簡單的,它隻有四個直接子類:

variabledeclaration: 變量聲明

functiondeclaration: 函數聲明

importdeclaration: 引用其它子產品聲明

exportdeclaration: 導出聲明

函數聲明的最主要結構就是有一個functionliteral函數文本的指針。

引用的子產品名,儲存在兩個astrawstring指針中。

導出聲明是es6引入的module的功能,可以導出變量,也可以導出函數,例:

導出聲明的類定義如下:

這其中通過一個宏declare_node_type來輸出導出的類型. 不禁讓人聯想起了mfc中著名的declare_message_map宏,不知道v8這部分的作者是不是有mfc的經曆,哈哈

statement表示語句。畢竟javascript還是語句式為主的,表達式是為語句服務的,是以statement對應了js程式的每一個基本執行元素。

語句有對于流程的控制,是以定義了isjump和marktail兩個函數。

isjump用于控制是否是跳轉型的指令。jumpstatement就是專為跳轉而生的,是以jumpstatement的定義就一條有用的,isjump傳回true:

marktail是用來辨別語句結束的,比如我們看看block的marktail的實作:

如果語句清單不為空,那麼語句清單中最後一條就辨別為尾巴。

語句的定義很簡單,下面的子類卻不少:

breakablestatement: 所有流程中可以退出和跳轉的語句

block:塊語句當然是breakablestatement,一個塊也是流程的控制結構

iterationstatement: 循環語句是可中斷的啊,有兩種中斷方法:break和continue

dowhilestatement: do while循環語句

whilestatement: while循環語句

forstatement: for循環語句

foreachstatement: for each型循環,适用于集合周遊的循環形式

forinstatement: for in循環語句

forofstatement: es6新增,使用疊代器的for of循環

switchstatement: switch語句

expressionstatement: 表達式語句,整條語句由一條表達式構成

jumpstatement: 流程跳轉型指令

continuestatement: continue語句

breakstatement: break語句

returnstatement: return語句

withstatement: with語句

ifstatement: if語句

trystatement: try語句

trycatchstatement: try catch語句

tryfinallystatement: try finally語句

debuggerstatement: 調試用途,我暫時也不知道它是做什麼的

emptystatement: 空語句

sloppyblockfunctionstatement: es2016 annex b3.3定義的可被覆寫的其它語句的代理

我們也畫一張圖來加深一下對于statement的印象:

v8世界探險(3) - v8的抽象文法樹結構v8世界探險(3) - v8的抽象文法樹結構

循環類語句的特點是要支援continue語句的落腳點,就是要記錄,執行continue的時候該回到哪裡。

break就不用考慮了,跳到結尾就好了麼。

dowhilestatement比普通的iterationstatement多了一個while時的表達式。

whilestatement對應了while循環,其實除了表達式的判斷位置不同,它與dowhilestatement的結構是基本一樣的:

前面大家已經被代碼轟炸得差不多了,下面就不重複貼完整代碼,隻貼幹貨。

for循環的特點是有三個表達式,分别對應:初始條件,結束條件和下一個的處理三種操作,對應到代碼中是這樣的:

if語句有兩個分支,是以有兩個尾巴:

if有一個條件判斷,外加then和else兩個執行塊:

表達式解釋一向都是文法分析的重點,後面我們再詳細展開介紹,這裡我們先看下表達式分類圖:

v8世界探險(3) - v8的抽象文法樹結構v8世界探險(3) - v8的抽象文法樹結構

表達式包括對于對象、類、函數、數組、正規表達式等字面量的表示,一進制,二進制,比較等運算等操作。

針對于字面和表達式,v8還提供了astvisitor工具類集來幫助通路和修改。

像變量、aststring等元件并不屬于astnode,而是直接從zoneobject派生出來的。後面用到的時候我們再詳細介紹。

v8的文法分析,最終會生成一棵抽象文法樹ast。這些聲明、語句、表達式和子產品都以astnode的形式來儲存。

astnode和變量,aststring等對象都是基于zone方式多次配置設定,一次性回收來進行記憶體管理的。

statement是語句,主要對應分支、循環、跳轉、異常處理等流程控制上的操作。

expression是表達式,構成了語句的組成部分,相對比較複雜。

繼續閱讀