How to reuse a global_object correctly with multiple v8::Context s?
Asked Answered
F

0

6

I'm refactoring my V8 with OpenGL implementation and got stuck with a problem on the execution context.

The concept is the following:

  • V8GL::initialize() This method initializes a context and the global template. It also uses the context for glut, because there are several loops running that are also exposed to the JS context. (e.g. glut.mainLoop())

  • V8GL::execute(context, source, url) This method mostly executes a string inside a given context. I think it has to be this way for later isolates usage with intervals/timeouts.

What doesn't work:

V8GL::initialize() also attaches built-in JavaScript files and executes them. That works perfectly fine.

Simplified code:

V8GL::initialize(...) {
    v8::Persistent<v8::Context> context = v8::Context::New(NULL, globalTemplate);
    v8::Context::Scope context_scope(context);

    // cached for glut mainLoop etc.
    GlutFactory::context_ = v8::Persistent<v8::Context>::New(context);

    execute(context, v8::String::New(...script content...), v8::String::New(...script url path to show for exception stacktraces...);


    // after all the stuff was dispatched to the global context, I want to cache the global object for later usage.
    v8gl::global = v8::Persistent<v8::Object>::New(context->Global());
    context->DetachGlobal();
    context.Dispose();

}

V8GL::execute(context, source, filename) {

    v8::HandleScope scope;
    // Previously, I had v8::Context::Scope(context) in here.
    v8::Local<v8::Script> script = v8::Script::Compile(source, filename);

}

The problem:

That was the initialization. That works fine, so the stuff of my own libraries is available in the JavaScript execution. BUT I wanted to execute another file, that is passed through via argument. So the main.cpp's main() looks like this.

int main(...) {

    v8gl::V8GL::initialize(&argc, argv); // argc and argv required for glut.

    v8::HandleScope scope;
    // This doesn't work:
    // v8::Local<v8::Context> context = v8::Context::GetCurrent();

    // You can't pass NULL as second parameter, so what then?
    v8::Context::New(NULL, v8::ObjectTemplate::New(), v8gl::global);

    // In here, all globals are lost. Why?
    v8gl::V8GL::execute(context, source, filepath);

}

Questions:

  • Do I have to cache the objectTemplate of global for usage with v8::Context::New()?
  • Does the global_object has to be persistent or local?
  • How can I reuse it? The DetachGlobal() and ReattachGlobal() stuff only worked on having a single context, not with multiple ones. Multiple contexts are required for my case.
Frolic answered 1/8, 2012 at 10:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.