I'm creating pure C++ objects (from C++ only) and then attaching them to JS-exposed objects returned as API wrapper instances. The means of attachment is using External::New
stored via SetInternalField
- pretty much following exactly the pattern outlined in the V8 Embedder's Guide.
These objects are intended to be memory-managed by JS, but even after dropping the references in JS and triggering garbage collection, the C++ objects remain. The destructors are not called, and if I save an independent reference elsewhere, it still works.
I think it makes sense that V8's cleanup of local values wouldn't know how (or whether) to destruct the contents of a void*
, but isn't this a prominent use-case? There's no way I can find to hook in any way to the de-scoping/cleanup of externals or locals in general. Further, anything I do with persistents (like MakeWeak
) aren't going to affect the locals that become unreachable on the JS side (right?).
How can I ensure that these C++ objects get eventually (preferably immediately) destroyed when the JS wrapper objects containing them fall out of scope?
Example instantiation that gets passed to JS:
Local<Value> createWindow(HWND handle, Isolate* isolate) {
// Build an instance from a premade FunctionTemplate with object
// and method prototypes, and SetInternalFieldCount(1)
Local<Function> fn = Local<Function>::New(isolate, window);
constructingInternally = true;
Local<Object> obj = fn->NewInstance(Context::New(isolate)).ToLocalChecked();
constructingInternally = false;
CppWindow* win = CppWindow(handle);
lastWin = win; // added for debugging
obj->SetInternalField(0, External::New(isolate, win));
return obj;
}
via HonoredMule
No comments:
Post a Comment