代码之家  ›  专栏  ›  技术社区  ›  Wyck

如何用更新的V8 API编写一个setter?

  •  0
  • Wyck  · 技术社区  · 4 年前

    在the V8 embedding guide in the section for accessing dynamic variables ,它描述了如何编写 设定器 对于一个包装好的C++对象。但文档在使用过程中似乎有点腐烂了 ToInt32 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> 参数,并返回 v8::Maybe<int32_t> .

    如何修改这个 SetPointX 函数以访问 Context 并处理 Maybe 那个 ToInt32 返回?

    0 回复  |  直到 4 年前
        1
  •  0
  •   jmrk    4 年前

    对于 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 dance是JavaScript代码所必需的,例如:

    my_point.x = {valueOf: () => throw "this is why we can't have nice things"; }
    

    旧版本在哪里 value->Int32Value() 在尝试获取int32值时,无法发出抛出异常的信号。当然,这不仅适用于此类人为示例,也适用于其他异常,如堆栈溢出或 ReferenceError s等。