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.
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.