深入V8引擎-引擎內部類管理解析


v8的初始化三部曲,前面花了三篇解決了第一步,由於只是生成了一個對象,第二步就是將其嵌入v8中,先看一下三個步驟。

// 生成默認Platform對象
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
// 將其嵌入V8引擎內
v8::V8::InitializePlatform(platform.get());
// 初始化V8引擎
v8::V8::Initialize();

第一步可以由用戶自己手動實現platform,只要按照規范來繼承對應基類,一般也不會有人搞吧。

這里的嵌入,如果用代碼來進行解釋,實際上是叫做"命名空間"。v8引擎的體量非常巨大,所以需要有完善的規范來管理各個類。如果完整的閱讀過v8源碼,可以發現v8對類的邏輯管理用到了兩個方法,其中一個是命名空間,另外一個則是語義化宏。

先來看看命名空間的定義(對C++熟悉就很簡單了),如果只是跟我一樣的前端頁面仔,可以理解成模塊。舉一個例子,在前面一篇有一個類叫PageAllocator,在看源碼發現有兩個同名類,但是其中一個是掛在v8的命名空間下,另外一個則在v8::base的命名空間下,如下。

namespace v8 {
  class PageAllocator {}
}
namespace v8 {
namespace base {
  class PageAllocator : public ::v8::PageAllocator {}
}
}

通過對v8命名空間所有類進行觀察,發現其所有的類都是一個基類,提供了聲明和一些虛函數,都是需要被繼承去實現的類。而對v8::base進行搜索時,發現了其命名空間下的所有方法都是實現類,可以看出,v8通過命名空間來對所有的class進行分類。

另外,其命名空間的名字也是有意義的,base命名空間下的類提供的功能都是比較底層的功能,比如說CPU、Hash、EnumSet等等。而之前那篇講的DefaultPlatform、TaskRunner,其命名空間都掛在v8::platform的下面。此外,WorkThread雖然從繼承關系上是屬於Thread類型,但是作為TaskRunner的內部類,實際上命名空間還是屬於platform,也就是只看命名空間就可以理解類的歸屬和功能。

比較典型的還有v8::debug包含垃圾回收、內存管理相關,v8::tracing包含調用棧追蹤的相關等等,這里就不一一舉例了。

 

除去命名空間,另外一個對類進行分類的就是語義化宏。這個命名是自己想的,主要是聯想到了語義化標簽,進行過格式化,實際上div和p在表現上並沒有什么區別,實際使用上只是為了語義化。同理,v8的很多宏會對類進行修飾,也是無意義的,純粹的語義化。

基本上所有的類都會有宏去修飾,還是拿之前的DefaultPlatform舉例。

// 宏定義
#define NON_EXPORTED_BASE(code) code
#define V8_PLATFORM_EXPORT
// 類聲明
class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {};

這里分別對實現類和基類都進行了修飾,V8_PLATFORM_EXPORT表明這個類是屬於platform模塊,且是一個實現類,可以輸出並使用。而NON_EXPORTED_BASE則表明該類不可直接使用,需要繼承實現。

宏的定義也給出來了,沒有任何意義,只是一個純粹的為了說明,跟注釋類似但是又有着不一樣的功能。

v8源碼的頭文件在類的定義上隨處可見這種宏,通過宏的名字就可以看出類的一些特征,從而方便調試和像我這樣無聊的人看源碼……

 

其實v8內部還有更多宏起着巨大的作用,比如在類聲明時,有時候需要禁掉這個類的拷貝構造函數和賦值功能,v8都把這個封裝到一個宏里,聲明的時候直接調用就行了,這些后面深入的時候再來細說把。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM