深刻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對類的邏輯管理用到了兩個方法,其中一個是命名空間,另一個則是語義化宏。ui

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

namespace v8 {
  class PageAllocator {}
}
namespace v8 {
namespace base {
  class PageAllocator : public ::v8::PageAllocator {}
}
}複製代碼

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

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

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


除去命名空間,另一個對類進行分類的就是語義化宏。這個命名是本身想的,主要是聯想到了語義化標籤,進行過格式化,實際上div和p在表現上並無什麼區別,實際使用上只是爲了語義化。同理,v8的不少宏會對類進行修飾,也是無心義的,純粹的語義化。orm

基本上全部的類都會有宏去修飾,仍是拿以前的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都把這個封裝到一個宏裏,聲明的時候直接調用就好了,這些後面深刻的時候再來細說把。

相關文章
相關標籤/搜索