1

Resolved

Callback for {ObjectTemplate}.RegisterInvokeHandler is GC'ed

description

Environment
Windows 7 x64
Visual Studio 2015
Project type - library
Project build configuration x86

Steps to reproduce
  1. Create object template with "call" signature using {ObjectTemplate}.RegisterInvokeHandler
  2. Create 2000 object instances using that template
  3. Try to use object() call signature on first object.
Actual result
CallbackOnCollectedDelegate exception

Possible reason
In V8.net/ObjectTemplate.cs,
public void RegisterInvokeHandler(JSFunction callback)
{
    V8NetProxy.RegisterInvokeHandler(_NativeObjectTemplateProxy, (managedObjectID, isConstructCall, _this, args, argCount)
    =>
    {
        return FunctionTemplate._CallBack(managedObjectID, isConstructCall, _this, args, argCount, callback);
    });
    _Engine._StoreAccessor<JSFunction>(_NativeObjectTemplateProxy->ObjectID, "$__InvokeHandler", callback);
}
Anonymous delegate (from lambda-expression) of type ManagedJSFunctionCallback is not stored, so gets GC'ed and is causing an error above.

Suggestion
Save ManagedJSFunctionCallback delegate in _Store, as it was before commit 9eec95970eb5d7de813485b240bcd02b1265a500

comments

jamesnw wrote Oct 29, 2015 at 9:36 PM

That function is depreciated. It was renamed and changed to "SetCallAsFunctionHandler()". Make sure you have the latest development branch (though I think the main branch has this change also).

That aside, yes, this is a bug, thanks for the catch! ;) I just made a possible fix for this and committed it to the dev branch. I decided to put the lambda into a variable and store that reference instead, since it closes over the callback anyhow, which should keep it alive. Let me know if this helps at all.

dmitry_demchenko wrote Oct 30, 2015 at 8:29 AM

Yes, your last patch resolves an issue, thank you.

BTW, last week i made an analogous patch in V8.NET "release" branch, applied it, compiled V8.NET against latest V8 engine available from V8 SVN repository (latest git version was incompatible with V8.NET release branch), and got this issue resolved too.