Почему создание нового массива v8 :: Array до v8 :: Scope вызывает ошибку сегментации, а v8 :: String и v8 :: FunctionTemplate - нет? - PullRequest
3 голосов
/ 10 августа 2011

Обратите внимание на следующие фрагменты кода, основанные на образце оболочки v8 sample.cc, который вызывает ошибку сегментации:

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 :: Array после создания экземпляра контекста v8 :: Context и установки области действия, то код не перестанет работать:

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 :: в первом примере приводит к тому, что приложение вызывает segfault, а создание массива v8 :: Array после создания контекста v8 :: Context не вызывает приложение к segfault? И почему создание экземпляра v8 :: String перед созданием контекста также не приводит к segfault приложения?

Этот вопрос является актуальным, потому что в реальном приложении оболочки я хотел бы создать экземпляр массива и назначить его глобальному объекту контекста, но это невозможно, так как кажется, что контекст должен быть создан до v8 :: Массив может быть создан, создавая циклическую зависимость.

Буду признателен за любое руководство, которое может дать каждый.

1 Ответ

5 голосов
/ 10 августа 2011

Когда вы создаете новый v8::Array через API V8, фактически вызывается конструктор Array из текущего контекста. Это почти как если бы вы выполнили new Array(n) в JavaScript. Если нет контекста, то V8 ничего не может вызвать для создания массива, поэтому он вызывает ошибки.

v8::String представляет примитивное строковое значение. Никакие контекстно-зависимые конструкторы не должны вызываться для его создания. Вот почему вы можете создать его до контекста без использования segfaulting V8.

Вы можете расширить глобальный объект контекста после его создания, непосредственно задав поля объекта, возвращаемого методом Context::Global().

...