Calling V8 function causes access violation

本小妞迷上赌 提交于 2020-01-05 10:18:52

问题


I have a global event manager, allowing you to listen with lambdas to string event names.

// somewhere in the ModuleScript class
Event->Listen("WindowResize", [=]{
    // ...
});

Now, I want to register to events from JavaScript, too. Therefore, I wrote this callback.

v8::Handle<v8::Value> ModuleScript::jsOn(const v8::Arguments& args)
{
    // get pointer to class since we're in a static method
    ModuleScript *module = (ModuleScript*)HelperScript::Unwrap(args.Data());

    // get event name we want to register to from arguments
    if(args.Length() < 1 || !args[0]->IsString())
        return v8::Undefined();
    string name = *v8::String::Utf8Value(args[0]);

    // get callback function from arguments
    if(args.Length() < 2 || !args[1]->IsFunction())
        return v8::Undefined();
    v8::Handle<v8::Function> callback =
        v8::Local<v8::Function>::Cast(args[1]->ToObject());

    // register event on global event manager
    module->Event->Listen(name, [=]{
        // create persistent handle so that function stays valid
        // maybe this doesn't work, I don't know
        v8::Persistent<v8::Function> function =
            v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
        // execute callback function
        // causes the access violation
        function->Call(function, 0, NULL);
    });

    return v8::Undefined();
}

When the event is triggered, the application crashes with a access violation. My thoughts are that either the function object isn't valid at this time anymore, or it is a JavaScript scope issue. But I couldn't figure it out.

What causes the access violation and how to overcome it?


回答1:


I believe there are several potential issues here.

First, you're not using a persistent handle to hold the JavaScript function after ModuleScript::jsOn() terminates. By the time your event handler is invoked, the function might be gone. Consider making callback a persistent handle.

Second, your event handler needs to enter an appropriate V8 context before calling the JavaScript function. Depending on your architecture, explicitly locking and entering the V8 isolate may be required as well.

Third (and this may not be an issue in your specific scenario), you need to manage the lifetime of the V8 isolate. If your event manager fires events on background threads, you have to make sure your event handler somehow prevents the isolate from being disposed from another thread. Unfortunately this is one area where the V8 API doesn't provide much help.

Fourth, to prevent a leak, your event handler should dispose the persistent function handle after invoking the function.

Good luck!



来源:https://stackoverflow.com/questions/17209794/calling-v8-function-causes-access-violation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!