为什么在v8 :: Scope之前创建新的v8 :: Array会导致分段错误,但是v8 :: String和v8 :: FunctionTemplate不会?

时间:2011-08-10 17:22:36

标签: javascript c++ embedding v8

请根据v8的sample.cc示例shell考虑以下代码片段,这会导致分段错误:

int RunMain(int argc, char* argv[]) {

  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
  v8::HandleScope handle_scope;
  // Create a template for the global object.
  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();

    v8::Handle<v8::String> testStr = v8::String::New("test");

    v8::Handle<v8::Array> testArr = v8::Array::New();

  // Create a new execution environment containing the built-in
  // functions
  v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
  // Enter the newly created execution environment.
  v8::Context::Scope context_scope(context);

  return 0;
}

int main(int argc, char* argv[]) {
  int result = RunMain(argc, argv);
  v8::V8::Dispose();
  return result;
}

但是,如果在实例化v8 :: Context并设置范围后实例化v8 :: Array,则代码不会出现段错误:

int RunMain(int argc, char* argv[]) {

  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
  v8::HandleScope handle_scope;
  // Create a template for the global object.
  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();

    v8::Handle<v8::String> testStr = v8::String::New("test");


  // Create a new execution environment containing the built-in
  // functions
  v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
  // Enter the newly created execution environment.
  v8::Context::Scope context_scope(context);

  v8::Handle<v8::Array> testArr = v8::Array::New();

  return 0;
}

int main(int argc, char* argv[]) {
  int result = RunMain(argc, argv);
  v8::V8::Dispose();
  return result;
}

我的问题是:为什么在第一个示例中实例化v8 :: Array会导致应用程序出现段错误,而在创建v8 :: Context之后创建v8 :: Array会导致应用程序出现段错误?而且,为什么在创建Context之前实例化v8 :: String也不会导致应用程序出现段错误?

这个问题是相关的,因为在真正的shell应用程序中,我想实例化一个数组并将其分配给全局上下文对象,但这是不可能的,因为它似乎必须在v8之前创建上下文::可以实例化数组,从而创建循环依赖。

我很感激任何人都可以提供任何指导。

1 个答案:

答案 0 :(得分:5)

当您通过API V8创建新的v8::Array时,实际上会从当前上下文中调用Array构造函数。这几乎就像你在JavaScript中执行new Array(n)一样。如果没有上下文,那么V8就无法调用来创建一个数组,这就是为什么它会出现段错误。

v8::String表示原始字符串值。不必调用特定于上下文的构造函数来创建它。这就是为什么你可以在没有segfaulting V8的情况下在上下文之前创建它。

您可以通过直接设置Context::Global()方法返回的对象上的字段来扩展上下文的全局对象。

相关问题