如何用较新的 V8 API 编写 setter?
How to write a setter with newer V8 API?
在V8 embedding guide in the section for accessing dynamic variables, it describes how to write a setter for a wrapped C++ object. But the documentation seems to have rotted a bit in its usage of ToInt32
compared to the current (v14.1) API.
这个例子...
void SetPointX(v8::Local<v8::String> property, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
v8::Local<v8::Object> self = info.Holder();
v8::Local<v8::External> wrap =
v8::Local<v8::External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
...调用 v8::Local<v8::Value>::Int32Value()
但不再存在返回可以转换为 int
的内容的无参数重载。在当前 API 中,该函数需要一个 v8::Local<v8::Context>
参数,并且 returns 需要一个 v8::Maybe<int32_t>
.
如何修改此 SetPointX
函数以访问 Context
并处理 ToInt32
returns 的 Maybe
?
对于 Context
:最好跟踪要使用的正确上下文。如果你只有一个,那很简单:-) 只需在创建它时将其存储在 v8::Persistent
中,并在需要时从中创建一个 v8::Local<v8::Context>
。如果您碰巧有多个上下文,您会(希望)欣赏这为您提供的控制量——对于需要关心此类事情的应用程序,排除与安全相关的跨上下文访问尤其重要。
对于Maybe<int32_t>
:检查是否为Nothing
,如果是则处理错误。
// On initialization:
v8::Isolate* isolate = ...;
v8::Persistent context(v8::Context::New(isolate));
// And then later:
v8::Maybe<int32_t> maybe_value = value->Int32Value(context.Get(isolate));
// Alternative 1 (more elegant, can inline `maybe_value`):
int32_t int_value;
if (!maybe_value.To(&value)) {
// Handle exception and return.
}
// Alternative 2 (easier to follow):
if (maybe_value.IsNothing()) {
// Handle exception and return.
}
int32_t int_value = maybe_value.FromJust(); // Crashes if maybe_value.IsNothing()
static_cast<Point*>(ptr)->x_ = int_value;
之所以需要 Maybe
舞蹈是因为 JavaScript 代码如下:
my_point.x = {valueOf: () => throw "this is why we can't have nice things"; }
旧版本 value->Int32Value()
在尝试获取 int32 值时无法发出异常抛出信号。当然,这不仅适用于此类人工示例,还适用于堆栈溢出或 ReferenceError
s 等其他异常
在V8 embedding guide in the section for accessing dynamic variables, it describes how to write a setter for a wrapped C++ object. But the documentation seems to have rotted a bit in its usage of ToInt32
compared to the current (v14.1) API.
这个例子...
void SetPointX(v8::Local<v8::String> property, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
v8::Local<v8::Object> self = info.Holder();
v8::Local<v8::External> wrap =
v8::Local<v8::External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
...调用 v8::Local<v8::Value>::Int32Value()
但不再存在返回可以转换为 int
的内容的无参数重载。在当前 API 中,该函数需要一个 v8::Local<v8::Context>
参数,并且 returns 需要一个 v8::Maybe<int32_t>
.
如何修改此 SetPointX
函数以访问 Context
并处理 ToInt32
returns 的 Maybe
?
对于 Context
:最好跟踪要使用的正确上下文。如果你只有一个,那很简单:-) 只需在创建它时将其存储在 v8::Persistent
中,并在需要时从中创建一个 v8::Local<v8::Context>
。如果您碰巧有多个上下文,您会(希望)欣赏这为您提供的控制量——对于需要关心此类事情的应用程序,排除与安全相关的跨上下文访问尤其重要。
对于Maybe<int32_t>
:检查是否为Nothing
,如果是则处理错误。
// On initialization:
v8::Isolate* isolate = ...;
v8::Persistent context(v8::Context::New(isolate));
// And then later:
v8::Maybe<int32_t> maybe_value = value->Int32Value(context.Get(isolate));
// Alternative 1 (more elegant, can inline `maybe_value`):
int32_t int_value;
if (!maybe_value.To(&value)) {
// Handle exception and return.
}
// Alternative 2 (easier to follow):
if (maybe_value.IsNothing()) {
// Handle exception and return.
}
int32_t int_value = maybe_value.FromJust(); // Crashes if maybe_value.IsNothing()
static_cast<Point*>(ptr)->x_ = int_value;
之所以需要 Maybe
舞蹈是因为 JavaScript 代码如下:
my_point.x = {valueOf: () => throw "this is why we can't have nice things"; }
旧版本 value->Int32Value()
在尝试获取 int32 值时无法发出异常抛出信号。当然,这不仅适用于此类人工示例,还适用于堆栈溢出或 ReferenceError
s 等其他异常