Skip to content

Commit cb94905

Browse files
author
Gabriel Schulhof
committed
n-api: stop creating references to primitives
The binding testing napi_wrap() creates references to primitives passed into the binding in its second parameter. This is unnecessary and not at all the point of the test. Additionally, creating persistent references to primitive values may not be supported by all VMs, since primitives are best persisted in their native form. Instead, the point of the test is to make sure that the finalize callback gets called when it should get called, that it gets called with the correct pointer, and that it does not get called when it should not get called. Creating persistent references is not necessary for verifying this. PR-URL: #15289 Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Re: nodejs/node-chakracore#380
1 parent c1fce1e commit cb94905

File tree

4 files changed

+21
-18
lines changed

4 files changed

+21
-18
lines changed

doc/api/n-api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ NODE_EXTERN napi_status napi_create_reference(napi_env env,
787787

788788
- `[in] env`: The environment that the API is invoked under.
789789
- `[in] value`: `napi_value` representing the Object to which we want
790-
a reference to.
790+
a reference.
791791
- `[in] initial_refcount`: Initial reference count for the new reference.
792792
- `[out] result`: `napi_ref` pointing to the new reference.
793793

src/node_api.cc

+8-2
Original file line numberDiff line numberDiff line change
@@ -2458,8 +2458,14 @@ napi_status napi_create_reference(napi_env env,
24582458
CHECK_ARG(env, value);
24592459
CHECK_ARG(env, result);
24602460

2461-
v8impl::Reference* reference = v8impl::Reference::New(
2462-
env, v8impl::V8LocalValueFromJsValue(value), initial_refcount, false);
2461+
v8::Local<v8::Value> v8_value = v8impl::V8LocalValueFromJsValue(value);
2462+
2463+
if (!(v8_value->IsObject() || v8_value->IsFunction())) {
2464+
return napi_set_last_error(env, napi_object_expected);
2465+
}
2466+
2467+
v8impl::Reference* reference =
2468+
v8impl::Reference::New(env, v8_value, initial_refcount, false);
24632469

24642470
*result = reinterpret_cast<napi_ref>(reference);
24652471
return napi_clear_last_error(env);

test/addons-napi/test_general/test.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ assert.strictEqual(test_general.testNapiTypeof(null), 'null');
6060
// Ensure that garbage collecting an object with a wrapped native item results
6161
// in the finalize callback being called.
6262
let w = {};
63-
test_general.wrap(w, []);
63+
test_general.wrap(w);
6464
w = null;
6565
global.gc();
6666
assert.strictEqual(test_general.derefItemWasCalled(), true,
@@ -69,17 +69,17 @@ assert.strictEqual(test_general.derefItemWasCalled(), true,
6969

7070
// Assert that wrapping twice fails.
7171
const x = {};
72-
test_general.wrap(x, 25);
72+
test_general.wrap(x);
7373
assert.throws(function() {
74-
test_general.wrap(x, 'Blah');
74+
test_general.wrap(x);
7575
}, Error);
7676

7777
// Ensure that wrapping, removing the wrap, and then wrapping again works.
7878
const y = {};
79-
test_general.wrap(y, -12);
79+
test_general.wrap(y);
8080
test_general.removeWrap(y);
8181
assert.doesNotThrow(function() {
82-
test_general.wrap(y, 're-wrap!');
82+
test_general.wrap(y);
8383
}, Error, 'Wrapping twice succeeds if a remove_wrap() separates the instances');
8484

8585
// Ensure that removing a wrap and garbage collecting does not fire the

test/addons-napi/test_general/test_general.c

+7-10
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ static bool deref_item_called = false;
143143
static void deref_item(napi_env env, void* data, void* hint) {
144144
(void) hint;
145145

146+
NAPI_ASSERT_RETURN_VOID(env, data == &deref_item_called,
147+
"Finalize callback was called with the correct pointer");
148+
146149
deref_item_called = true;
147-
NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, (napi_ref)data));
148150
}
149151

150152
napi_value deref_item_was_called(napi_env env, napi_callback_info info) {
@@ -156,15 +158,13 @@ napi_value deref_item_was_called(napi_env env, napi_callback_info info) {
156158
}
157159

158160
napi_value wrap(napi_env env, napi_callback_info info) {
159-
size_t argc = 2;
160-
napi_value argv[2];
161-
napi_ref payload;
161+
size_t argc = 1;
162+
napi_value to_wrap;
162163

163164
deref_item_called = false;
164165

165-
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
166-
NAPI_CALL(env, napi_create_reference(env, argv[1], 1, &payload));
167-
NAPI_CALL(env, napi_wrap(env, argv[0], payload, deref_item, NULL, NULL));
166+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &to_wrap, NULL, NULL));
167+
NAPI_CALL(env, napi_wrap(env, to_wrap, &deref_item_called, deref_item, NULL, NULL));
168168

169169
return NULL;
170170
}
@@ -176,9 +176,6 @@ napi_value remove_wrap(napi_env env, napi_callback_info info) {
176176

177177
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &wrapped, NULL, NULL));
178178
NAPI_CALL(env, napi_remove_wrap(env, wrapped, &data));
179-
if (data != NULL) {
180-
NAPI_CALL(env, napi_delete_reference(env, (napi_ref)data));
181-
}
182179

183180
return NULL;
184181
}

0 commit comments

Comments
 (0)