原本打算是把node原始碼看得差不多了再去深入V8的,但是這兩者基本上沒辦法分開講。

與express是基於node的封裝不同,node是基於V8的一個應用,原始碼內容已經滲透到V8層面,因此這章簡述一下我目前理解的V8引擎吧。

首先需要理解的是V8是一個JS程式碼執行平臺,可以將JS程式碼編譯執行。

本節就非常淺顯的講一下V8內部一些常見類,以及一個執行JS程式碼的簡單demo。

(由於研究V8引擎原理的人非常多,本人學識淺薄,可以去參考別人的部落格)

參考資料:

1、很多大佬的部落格

2、V8引擎API文件:

https://

v8docs。nodesource。com/

3、github:

https://

github。com/v8/v8

本節先列舉一些核心類,示例程式碼大部分來源於node中的原始碼。

Isolate

該類代表一個V8引擎例項,有自己獨立的狀態,用法如下。

1、不能使用new關鍵字來生成一個例項,只能透過類方法Isolate::New(params)來建立。

Isolate

*

const

isolate

=

Isolate

::

New

params

);

2、該類的方法都是設定V8引擎的一些處理細節。

// 新增error的資訊監聽器

isolate

->

AddMessageListener

OnMessage

);

// 從名字能看出來 設定未捕捉中斷異常的回撥函式

isolate

->

SetAbortOnUncaughtExceptionCallback

ShouldAbortOnUncaughtException

);

// 設定Microtask的執行方式(有三種)

isolate

->

SetMicrotasksPolicy

v8

::

MicrotasksPolicy

::

kExplicit

);

// 設定致命錯誤的回撥函式

isolate

->

SetFatalErrorHandler

OnFatalError

);

// WebAssembly程式碼生成回撥函式

isolate

->

SetAllowWasmCodeGenerationCallback

AllowWasmCodeGenerationCallback

);

3、作為一個引數傳入其餘的V8工具類中。

// 單執行緒執行V8的Isolate

Locker

locker

isolate

);

Isolate

::

Scope

isolate_scope

isolate

);

Local/Hanlde

這個地方我之前一直比較混亂,因為有文章指出:Handle類定義在v8。h中,它是一個模板類,而且有兩個派生類Local和Persistent。

出處:

https://

blog。csdn。net/sunbxonli

ne/article/details/20310897

但是從原始碼來看,無論是Local還是MaybeLocal,均不繼承於任何類

這是因為V8版本不一致,所以我這裡只講當前版本的情況,原始碼註釋如下:

#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)

// Handle is an alias for Local for historical reasons。

template

<

class

T

>

using

Handle

=

Local

<

T

>

#endif

這兩個類從作用上講都是handle,但實際上並不繼承於同一個父類。

1、Local/Persistent是V8的兩個類,指向底層的原始資料。

2、所有物件的引用都需要被V8的垃圾回收管理,在管理中可能出現移動物件的情況(參考網上大量關於V8垃圾回收的部落格),這會導致物件指標產生錯誤,所以不能直接使用原始的資料型別,諸如String,而需要使用Local,Local被V8引擎管理,會在物件移動時更新指標指向,並在合適的時候進行回收。

3、Persistent屬於全域性物件(可參考Global),獨立於HanldeScope,可使用Reset方法清空。

Value

所以JS資料型別對映到C++的根類,繼承關係如下:

深入出不來nodejs原始碼-V8引擎初探

複雜的繼承樹

具體的內部實現後面做分析。

HandleScope

一個管理handle的容器,在當前作用域開頭宣告一個HanldeScope,在域結束時會自動清理所有的handle。

HandleScope

handle_scope

isolate

);

巢狀使用時,作用域會自動進行切換。

Context

執行上下文,有自己獨立的函式與物件。與Isolate相似,透過類方法New來生成。

auto

context

=

Context

::

New

isolate

nullptr

object_template

);

可透過內部Scope類來進行上下文的切換。

Context

::

Scope

context_scope

context

);

Script

該類主要負責對JS程式碼字串進行編譯和執行,核心方法為Compile、Run。

Script::Compile可以編譯JS程式碼字串,返回一個Local