深刻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都把这个封装到一个宏里,声明的时候直接调用就好了,这些后面深刻的时候再来细说把。

相关文章
相关标签/搜索