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

发布于 2024-11-28 16:21:02 字数 1969 浏览 8 评论 0原文

请考虑以下基于 v8 的 example.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::Array 之前创建上下文实例化,从而创建循环依赖。

我将不胜感激任何人都可以提供的指导。

Please consider the following code snippets, based on v8's sample.cc sample shell, which causes a segmentation fault:

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;
}

However, if I instantiate the v8::Array after the v8::Context is instantiated and the scope is set, then the code does not segfault:

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;
}

My question is: why does instantiating the v8::Array in the first example cause the application to segfault, whereas creating the v8::Array after the v8::Context is created does not cause the application to segfault? And, why does instantiating a v8::String before the Context is created also not cause the application to segfault?

This question is relevant, because in a real shell application, I would like to instantiate an array and assign it to the global context object, but this is not possible, as it seems the context must be created before the v8::Array can be instantiated, thus creating a cyclic dependency.

I'd appreciate any guidance anyone can provide.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月染过的梦 2024-12-05 16:21:02

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

v8::String 表示原始字符串值。无需调用上下文特定的构造函数来创建它。这就是为什么您可以在上下文之前创建它,而不会导致 V8 出现段错误。

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

When you create a new v8::Array via API V8 actually invokes Array constructor from the current context. It's almost as if you executed new Array(n) in JavaScript. If there is no context then there is nothing V8 can invoke to create an array thats why it segfaults.

v8::String represents primitive string value. No context specific constructors have to be invoked to create it. That's why you can create it before context without segfaulting V8.

You can extend context's global object after it was created by directly setting fields on the object returned by Context::Global() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文