原本打算是把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
這是因為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
3、Persistent屬於全域性物件(可參考Global),獨立於HanldeScope,可使用Reset方法清空。
Value
所以JS資料型別對映到C++的根類,繼承關係如下:
複雜的繼承樹
具體的內部實現後面做分析。
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