Skip to content

Commit 7597d8e

Browse files
napi: add finalize hint support (#155)
napi: add finalize hint support Change napi_finalize_callback to support a hint parameter APIs that take in a finalize callback now also take a hint This hint is passed back in when the finalize callback is called Fixes: #111 Reviewed-By: @jasongin @boingoing @mhdawson PR-Url: #155
1 parent 2791cf9 commit 7597d8e

File tree

11 files changed

+64
-20
lines changed

11 files changed

+64
-20
lines changed

src/node_jsvmapi.cc

+35-9
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,15 @@ class Reference {
119119
int initialRefcount,
120120
bool deleteSelf,
121121
napi_finalize finalizeCallback = nullptr,
122-
void* finalizeData = nullptr)
123-
: _isolate(isolate),
122+
void* finalizeData = nullptr,
123+
void* finalizeHint = nullptr)
124+
: _isolate(isolate),
124125
_persistent(isolate, value),
125126
_refcount(initialRefcount),
126127
_deleteSelf(deleteSelf),
127128
_finalizeCallback(finalizeCallback),
128-
_finalizeData(finalizeData) {
129+
_finalizeData(finalizeData),
130+
_finalizeHint(finalizeHint) {
129131
if (initialRefcount == 0) {
130132
if (_finalizeCallback != nullptr || _deleteSelf) {
131133
_persistent.SetWeak(
@@ -187,7 +189,8 @@ class Reference {
187189
bool deleteSelf = reference->_deleteSelf;
188190

189191
if (reference->_finalizeCallback != nullptr) {
190-
reference->_finalizeCallback(reference->_finalizeData);
192+
reference->_finalizeCallback(reference->_finalizeData,
193+
reference->_finalizeHint);
191194
}
192195

193196
if (deleteSelf) {
@@ -201,6 +204,7 @@ class Reference {
201204
bool _deleteSelf;
202205
napi_finalize _finalizeCallback;
203206
void* _finalizeData;
207+
void* _finalizeHint;
204208
};
205209

206210
class TryCatch : public v8::TryCatch {
@@ -1782,6 +1786,7 @@ napi_status napi_wrap(napi_env e,
17821786
napi_value jsObject,
17831787
void* nativeObj,
17841788
napi_finalize finalize_cb,
1789+
void* finalize_hint,
17851790
napi_ref* result) {
17861791
NAPI_PREAMBLE(e);
17871792
CHECK_ARG(jsObject);
@@ -1800,7 +1805,13 @@ napi_status napi_wrap(napi_env e,
18001805
// Create a separate self-deleting reference for the finalizer callback.
18011806
// This ensures the finalizer is not dependent on the lifetime of the
18021807
// returned reference.
1803-
new v8impl::Reference(isolate, obj, 0, true, finalize_cb, nativeObj);
1808+
new v8impl::Reference(isolate,
1809+
obj,
1810+
0,
1811+
true,
1812+
finalize_cb,
1813+
nativeObj,
1814+
finalize_hint);
18041815
}
18051816

18061817
if (result != nullptr) {
@@ -1810,7 +1821,7 @@ napi_status napi_wrap(napi_env e,
18101821
// deleted via
18111822
// napi_delete_reference() when it is no longer needed.
18121823
v8impl::Reference* reference =
1813-
new v8impl::Reference(isolate, obj, 0, false, nullptr, nullptr);
1824+
new v8impl::Reference(isolate, obj, 0, false);
18141825
*result = reinterpret_cast<napi_ref>(reference);
18151826
}
18161827

@@ -1838,6 +1849,7 @@ napi_status napi_unwrap(napi_env e, napi_value jsObject, void** result) {
18381849
napi_status napi_create_external(napi_env e,
18391850
void* data,
18401851
napi_finalize finalize_cb,
1852+
void* finalize_hint,
18411853
napi_value* result) {
18421854
NAPI_PREAMBLE(e);
18431855
CHECK_ARG(result);
@@ -1848,7 +1860,13 @@ napi_status napi_create_external(napi_env e,
18481860

18491861
// The Reference object will delete itself after invoking the finalizer
18501862
// callback.
1851-
new v8impl::Reference(isolate, externalValue, 0, true, finalize_cb, data);
1863+
new v8impl::Reference(isolate,
1864+
externalValue,
1865+
0,
1866+
true,
1867+
finalize_cb,
1868+
data,
1869+
finalize_hint);
18521870

18531871
*result = v8impl::JsValueFromV8LocalValue(externalValue);
18541872

@@ -2177,6 +2195,7 @@ napi_status napi_create_external_buffer(napi_env e,
21772195
size_t size,
21782196
void* data,
21792197
napi_finalize finalize_cb,
2198+
void* finalize_hint,
21802199
napi_value* result) {
21812200
NAPI_PREAMBLE(e);
21822201
CHECK_ARG(result);
@@ -2185,7 +2204,7 @@ napi_status napi_create_external_buffer(napi_env e,
21852204
static_cast<char*>(data),
21862205
size,
21872206
(node::Buffer::FreeCallback)finalize_cb,
2188-
nullptr);
2207+
finalize_hint);
21892208

21902209
CHECK_MAYBE_EMPTY(maybe, napi_generic_failure);
21912210

@@ -2271,6 +2290,7 @@ napi_status napi_create_external_arraybuffer(napi_env e,
22712290
void* external_data,
22722291
size_t byte_length,
22732292
napi_finalize finalize_cb,
2293+
void* finalize_hint,
22742294
napi_value* result) {
22752295
NAPI_PREAMBLE(e);
22762296
CHECK_ARG(result);
@@ -2282,7 +2302,13 @@ napi_status napi_create_external_arraybuffer(napi_env e,
22822302
if (finalize_cb != nullptr) {
22832303
// Create a self-deleting weak reference that invokes the finalizer
22842304
// callback.
2285-
new v8impl::Reference(isolate, buffer, 0, true, finalize_cb, external_data);
2305+
new v8impl::Reference(isolate,
2306+
buffer,
2307+
0,
2308+
true,
2309+
finalize_cb,
2310+
external_data,
2311+
finalize_hint);
22862312
}
22872313

22882314
*result = v8impl::JsValueFromV8LocalValue(buffer);

src/node_jsvmapi.h

+4
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,15 @@ NODE_EXTERN napi_status napi_wrap(napi_env e,
321321
napi_value jsObject,
322322
void* nativeObj,
323323
napi_finalize finalize_cb,
324+
void* finalize_hint,
324325
napi_ref* result);
325326
NODE_EXTERN napi_status napi_unwrap(napi_env e,
326327
napi_value jsObject,
327328
void** result);
328329
NODE_EXTERN napi_status napi_create_external(napi_env e,
329330
void* data,
330331
napi_finalize finalize_cb,
332+
void* finalize_hint,
331333
napi_value* result);
332334
NODE_EXTERN napi_status napi_get_value_external(napi_env e,
333335
napi_value value,
@@ -408,6 +410,7 @@ NODE_EXTERN napi_status napi_create_external_buffer(napi_env e,
408410
size_t size,
409411
void* data,
410412
napi_finalize finalize_cb,
413+
void* finalize_hint,
411414
napi_value* result);
412415
NODE_EXTERN napi_status napi_create_buffer_copy(napi_env e,
413416
const void* data,
@@ -434,6 +437,7 @@ napi_create_external_arraybuffer(napi_env env,
434437
void* external_data,
435438
size_t byte_length,
436439
napi_finalize finalize_cb,
440+
void* finalize_hint,
437441
napi_value* result);
438442
NODE_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
439443
napi_value arraybuffer,

src/node_jsvmapi_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ typedef struct napi_escapable_handle_scope__ *napi_escapable_handle_scope;
1414
typedef struct napi_callback_info__ *napi_callback_info;
1515

1616
typedef void (*napi_callback)(napi_env, napi_callback_info);
17-
typedef void (*napi_finalize)(void* v);
17+
typedef void (*napi_finalize)(void* finalize_data, void* finalize_hint);
1818

1919
enum napi_property_attributes {
2020
napi_default = 0,

test/addons-abi/6_object_wrap/myobject.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ MyObject::MyObject(double value)
77

88
MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
99

10-
void MyObject::Destructor(void* nativeObject) {
10+
void MyObject::Destructor(void* nativeObject, void* /*finalize_hint*/) {
1111
reinterpret_cast<MyObject*>(nativeObject)->~MyObject();
1212
}
1313

@@ -66,6 +66,7 @@ void MyObject::New(napi_env env, napi_callback_info info) {
6666
jsthis,
6767
reinterpret_cast<void*>(obj),
6868
MyObject::Destructor,
69+
nullptr, // finalize_hint
6970
&obj->wrapper_);
7071
if (status != napi_ok) return;
7172

test/addons-abi/6_object_wrap/myobject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class MyObject {
77
public:
88
static void Init(napi_env env, napi_value exports);
9-
static void Destructor(void* nativeObject);
9+
static void Destructor(void* nativeObject, void* finalize_hint);
1010

1111
private:
1212
explicit MyObject(double value_ = 0);

test/addons-abi/7_factory_wrap/myobject.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ MyObject::MyObject() : env_(nullptr), wrapper_(nullptr) {}
44

55
MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
66

7-
void MyObject::Destructor(void* nativeObject) {
7+
void MyObject::Destructor(void* nativeObject, void* /*finalize_hint*/) {
88
reinterpret_cast<MyObject*>(nativeObject)->~MyObject();
99
}
1010

@@ -56,6 +56,7 @@ void MyObject::New(napi_env env, napi_callback_info info) {
5656
jsthis,
5757
reinterpret_cast<void*>(obj),
5858
MyObject::Destructor,
59+
nullptr, /* finalize_hint */
5960
&obj->wrapper_);
6061
if (status != napi_ok) return;
6162

test/addons-abi/7_factory_wrap/myobject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class MyObject {
77
public:
88
static napi_status Init(napi_env env);
9-
static void Destructor(void* nativeObject);
9+
static void Destructor(void* nativeObject, void* /*finalize_hint*/);
1010
static napi_status NewInstance(napi_env env,
1111
napi_value arg,
1212
napi_value* instance);

test/addons-abi/8_passing_wrapped/myobject.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ MyObject::MyObject() : env_(nullptr), wrapper_(nullptr) {}
55

66
MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
77

8-
void MyObject::Destructor(void* nativeObject) {
8+
void MyObject::Destructor(void* nativeObject, void* /*finalize_hint*/) {
99
reinterpret_cast<MyObject*>(nativeObject)->~MyObject();
1010
}
1111

@@ -53,6 +53,7 @@ void MyObject::New(napi_env env, napi_callback_info info) {
5353
jsthis,
5454
reinterpret_cast<void*>(obj),
5555
MyObject::Destructor,
56+
nullptr, // finalize_hint
5657
&obj->wrapper_);
5758
if (status != napi_ok) return;
5859

test/addons-abi/8_passing_wrapped/myobject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class MyObject {
77
public:
88
static napi_status Init(napi_env env);
9-
static void Destructor(void* nativeObject);
9+
static void Destructor(void* nativeObject, void* finalize_hint);
1010
static napi_status NewInstance(napi_env env,
1111
napi_value arg,
1212
napi_value* instance);

test/addons-abi/test_buffer/test_buffer.cc

+9-3
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ static const char theText[] =
2323
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
2424

2525
static int deleterCallCount = 0;
26-
static void deleteTheText(void *data) {
26+
static void deleteTheText(void *data, void* /*finalize_hint*/) {
2727
delete reinterpret_cast<char *>(data);
2828
deleterCallCount++;
2929
}
3030

31-
static void noopDeleter(void *data) { deleterCallCount++; }
31+
static void noopDeleter(void *data, void* /*finalize_hint*/) { deleterCallCount++; }
3232

3333
void newBuffer(napi_env env, napi_callback_info info) {
3434
napi_value theBuffer;
@@ -52,7 +52,12 @@ void newExternalBuffer(napi_env env, napi_callback_info info) {
5252
JS_ASSERT(env, theCopy, "Failed to copy static text for newExternalBuffer");
5353
NAPI_CALL(env,
5454
napi_create_external_buffer(
55-
env, sizeof(theText), theCopy, deleteTheText, &theBuffer));
55+
env,
56+
sizeof(theText),
57+
theCopy,
58+
deleteTheText,
59+
nullptr, // finalize_hint
60+
&theBuffer));
5661
NAPI_CALL(env, napi_set_return_value(env, info, theBuffer));
5762
}
5863

@@ -116,6 +121,7 @@ void staticBuffer(napi_env env, napi_callback_info info) {
116121
sizeof(theText),
117122
const_cast<char *>(theText),
118123
noopDeleter,
124+
nullptr, // finalize_hint
119125
&theBuffer));
120126
NAPI_CALL(env, napi_set_return_value(env, info, theBuffer));
121127
}

test/addons-abi/test_typedarray/test_typedarray.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ void External(napi_env env, napi_callback_info info) {
105105

106106
napi_value output_buffer;
107107
napi_status status = napi_create_external_arraybuffer(
108-
env, externalData, sizeof(externalData), nullptr, &output_buffer);
108+
env,
109+
externalData,
110+
sizeof(externalData),
111+
nullptr, // finalize_callback
112+
nullptr, // finalize_hint
113+
&output_buffer);
109114
if (status != napi_ok) return;
110115

111116
napi_value output_array;

0 commit comments

Comments
 (0)