欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

深入V8引擎-引擎内部类管理解析

程序员文章站 2022-06-27 22:26:20
v8的初始化三部曲,前面花了三篇解决了第一步,由于只是生成了一个对象,第二步就是将其嵌入v8中,先看一下三个步骤。 第一步可以由用户自己手动实现platform,只要按照规范来继承对应基类,一般也不会有人搞吧。 这里的嵌入,如果用代码来进行解释,实际上是叫做"命名空间"。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都把这个封装到一个宏里,声明的时候直接调用就行了,这些后面深入的时候再来细说把。