@@ -24,15 +24,24 @@ using namespace v8;
2424using namespace node ;
2525
2626{% if cType %}
27- {{ cppClassName }}::{{ cppClassName }}({{ cType }} *raw, bool selfFreeing, bool shouldDuplicate) {
28- if (shouldDuplicate) {
29- {% if shouldAlloc %}
30- this ->raw = ({{ cType }} *)malloc (sizeof ({{ cType }}));
31- {{ dupFunction }}(this ->raw , raw);
27+ {{ cppClassName }}::{{ cppClassName }}({{ cType }} *raw, bool selfFreeing, Local<v8::Object> owner) {
28+ if (!owner.IsEmpty ()) {
29+ // if we have an owner, there are two options - either we duplicate the raw object
30+ // (so we own the duplicate, and can self-free it)
31+ // or we keep a handle on the owner so it doesn't get garbage collected
32+ // while this wrapper is accessible
33+ {% if dupFunction %}
34+ {% if shouldAlloc %}
35+ this ->raw = ({{ cType }} *)malloc (sizeof ({{ cType }}));
36+ {{ dupFunction }}(this ->raw , raw);
37+ {% else %}
38+ {{ dupFunction }}(&this ->raw , raw);
39+ {% endif %}
40+ selfFreeing = true ;
3241 {% else %}
33- {{ dupFunction }}(&this ->raw , raw);
42+ this ->owner .Reset (owner);
43+ this ->raw = raw;
3444 {% endif %}
35- selfFreeing = true ;
3645 } else {
3746 this ->raw = raw;
3847 }
@@ -117,17 +126,22 @@ using namespace node;
117126 {{ cppClassName }}* object = new {{ cppClassName }}(static_cast <{{ cType }} *>(
118127 Local<External>::Cast (info[0 ])->Value ()),
119128 Nan::To<bool >(info[1 ]).FromJust (),
120- info.Length () >= 3 ? Nan::To< bool >( info[2 ]). FromJust () : false
129+ info.Length () >= 3 && !info[ 2 ]. IsEmpty () && info[2 ]-> IsObject () ? info[ 2 ]-> ToObject () : Local<v8::Object>()
121130 );
122131 object->Wrap (info.This ());
123132
124133 info.GetReturnValue ().Set (info.This ());
125134 }
126135
127- Local<v8::Value> {{ cppClassName }}::New(const {{ cType }} *raw, bool selfFreeing, bool shouldDuplicate ) {
136+ Local<v8::Value> {{ cppClassName }}::New(const {{ cType }} *raw, bool selfFreeing, Local<v8::Object> owner ) {
128137 Nan::EscapableHandleScope scope;
129- Local<v8::Value> argv[3 ] = { Nan::New<External>((void *)raw), Nan::New (selfFreeing), Nan::New (shouldDuplicate) };
130- return scope.Escape (Nan::NewInstance (Nan::New ({{ cppClassName }}::constructor_template), 3 , argv).ToLocalChecked ());
138+ Local<v8::Value> argv[3 ] = { Nan::New<External>((void *)raw), Nan::New (selfFreeing), owner };
139+ return scope.Escape (
140+ Nan::NewInstance (
141+ Nan::New ({{ cppClassName }}::constructor_template),
142+ owner.IsEmpty () ? 2 : 3 , // passing an empty handle as part of the arguments causes a crash
143+ argv
144+ ).ToLocalChecked ());
131145 }
132146
133147 NAN_METHOD ({{ cppClassName }}::GetSelfFreeingInstanceCount) {
0 commit comments