在 v8 中对值句柄进行投射与 ToXXX

Cast vs ToXXX for value handles in v8

本文关键字:ToXXX 句柄 v8      更新时间:2023-10-16

我将V8作为辅助语言嵌入到C++程序中。

当我调用类似的东西时,我从 V8 检索Handle<Value>

Handle<Value> value_handle = context->Global()->Get(key_handle);

然后我可以发现它是(说(一个带有value_handle->IsString()的字符串。如果是这样,我可以将其转换为Handle<String>以访问其特定于字符串的方法。

但似乎有两种方法可以做到这一点:

Handle<String> string = value_handle->ToString();

Handle<String> string = Handle<String>::Cast(value_handle);

但是,对于数组和函数,没有toArray()toFunction方法,只有强制转换。

所以我的问题是:a( ToXXX只是用于铸造的语法糖吗?如果不是 b( ToXXX方法在做什么?

ToXXX函数执行 ECMA-262 5th 第 9 节小节中所述的类型强制。例如,ToString在第 9.8 节中描述:当给定一个非字符串值时,它将返回它的适当字符串表示形式,如果您正在传递对象,它将在其上调用toString方法(如果不存在toStringvalueOf(。ToString的相关代码:在调用runtime.js ToStringapi.cc Value::ToString

另一方面,Handle<XXX>::Cast(...)不做胁迫。它只是句柄的类型转换。从本质上讲,它只是一个static_cast<XXX*>。在调试模式下,Handle<T>::Cast(...)被选中,并在类型不匹配时中止执行。如果为您提供包含ObjectHandle<Value>,并且您尝试将其转换为Handle<String>,那将是一个致命错误。在发布模式下,当您尝试使用强制转换的结果时,转换为不兼容的类型稍后会导致奇怪的结果并可能崩溃。v8.h Handle<T>::Cast中的相关代码,委托给(例如(String::Cast通过String::CheckCast检查转换(如果启用了检查(。

我们可以找到

V8EXPORT Local ToString(( const;

v8.h的第 971 行其中V8EXPORT是依赖于操作系统的函数方法。


字符串句柄的 ToString 位于 api.cc 的第 2362 行

Local<String> Value::ToString() const {
  i::Handle<i::Object> obj = Utils::OpenHandle(this);
  i::Handle<i::Object> str;
  if (obj->IsString()) {
    str = obj;
  } else {
    i::Isolate* isolate = i::Isolate::Current();
    if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
      return Local<String>();
    }
    LOG_API(isolate, "ToString");
    ENTER_V8(isolate);
    EXCEPTION_PREAMBLE(isolate);
    str = i::Execution::ToString(obj, &has_pending_exception);
    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
  }
  return Local<String>(ToApi<String>(str));
}

为了保持一致性并从 V8 版本的进一步升级中获利,我强烈建议使用 toString(( 而不是原始强制转换。