V8中JavaScript对象的内存布局

我正在写一些C绑定到V8,所以我需要弄清楚各种原始JavaScripttypes的内存布局。 有没有关于这些细节的任何文件?

您不需要知道数据types布局就可以为V8编写C绑定。 当你使用V8但是通过一个API时,对象的东西永远不会被直接访问 – 只有V8的实现知道它们是如何布局的。 例如,从一个对象获取属性foo在C ++中看起来像这样:

 v8::Handle<v8::Object> o; v8::Handle<v8::Object> v = o->Get(v8::String::NewFromUtf8(isolate, "foo")); 

现在把它包装到C中, 需要知道如何表示和传递v8::Handle<T> ,那么你可以编写如下的包装器:

 template<typename T> Handle<T> FromC(v8_handle_t h) { /* ... */ } template<typename T> v8_handle_t ToC(Handle<T> h) { /* ... */ } extern "C" v8_handle_t v8_object_get(v8_handle_t self, v8_handle_t key) { return ToC(FromC<Object>(self)->Get(FromC<Value>(key))); } 

那么在v8::Handle<T>呢? 实际上,它只是一个指向某个插槽的指针,而这个指针又包含一个指向底层V8对象的实际指针。 这种双重间接的存在使得V8 GC能够精确跟踪C ++代码中正在使用的对象,并允许它移动这些对象。

所以理论上你可以把v8_handle_t定义为一个不透明的指针,并且像这样编组:

 typedef struct v8_object_pointer_t* v8_handle_t; // Opaque pointer static_assert(sizeof(v8_handle_t) == sizeof(Handle<Object>)) template<typename T> Handle<T> FromC(v8_handle_t h) { return *(Handle<T>*)&h; } template<typename T> v8_handle_t ToC(const Handle<T>& h) { return *(v8_handle_t*)&h; } 

一个小小的复杂来自pipe理称为HandleScope的结构来pipe理Handle 。 在C ++ API中,它依赖于RAII模式来pipe理一些后备存储。 处理它最简单的方法可能是:

 typedef struct { void* a[3]; } v8_handle_scope_t; static_assert(sizeof(v8_handle_scope_t) == sizeof(HandleScope)) void v8_handle_scope_enter(v8_handle_scope_t* scope) { new(scope) HandleScope; } void v8_handle_scope_leave(v8_handle_scope_t* scope) { delete (HandleScope*)scope; } 

仔细平衡使用需要处理范围的代码:

 for (i = 0; i < N; i++) { v8_handle_scope_t scope; v8_handle_scope_enter(&scope); // action v8_handle_scope_leave(&scope); } 

因为你的问题是关于如何编写Node.js的V8 C ++插件,你应该参考nodeJs的手册,这个手册对于编写插件有相当简单的指导 。

如果你的问题是关于如何创build后台线程,那么有一个nodejs插件可以帮助你,但是也可以直接阅读这个插件。

您不应该尝试直接访问V8的内存,因为内存和对象可能会移动 – 总是使用API