Skip to content

Commit 8474b82

Browse files
Gabriel SchulhofBridgeAR
Gabriel Schulhof
authored andcommitted
n-api: delete callback bundle via reference
We should strive to use weak persistent references consistently throughout the code, since using `v8::Persistent` directly results in having to change many sites in the code when the way we use it changes. N-API uses `v8impl::Reference` internally when maintaining a weak persistent reference is necessary. So far, `v8impl::CallbackBundle` was using `v8::Persistent` directly in order to weakly reference the JS function backed by a N-API callback. The change introduced here reduces `v8impl::CallbackBundle` to a simple structure and uses a `v8impl::Reference` to weakly reference the N-API callback with which it is associated. The structure is freed by the `napi_finalize` callback of the `v8impl::Reference`. This brings N-API use of `v8::Persistent` completely under the `v8impl::Reference` umbrella, rendering our use of weak references consistent. PR-URL: #29479 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent b1509e8 commit 8474b82

File tree

1 file changed

+6
-18
lines changed

1 file changed

+6
-18
lines changed

src/js_native_api_v8.cc

+6-18
Original file line numberDiff line numberDiff line change
@@ -379,27 +379,10 @@ inline static napi_status Unwrap(napi_env env,
379379
// Ref: benchmark/misc/function_call
380380
// Discussion (incl. perf. data): https://github.com/nodejs/node/pull/21072
381381
struct CallbackBundle {
382-
// Bind the lifecycle of `this` C++ object to a JavaScript object.
383-
// We never delete a CallbackBundle C++ object directly.
384-
void BindLifecycleTo(v8::Isolate* isolate, v8::Local<v8::Value> target) {
385-
handle.Reset(isolate, target);
386-
handle.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
387-
}
388-
389382
napi_env env; // Necessary to invoke C++ NAPI callback
390383
void* cb_data; // The user provided callback data
391384
napi_callback function_or_getter;
392385
napi_callback setter;
393-
v8impl::Persistent<v8::Value> handle; // Die with this JavaScript object
394-
395-
private:
396-
static void WeakCallback(v8::WeakCallbackInfo<CallbackBundle> const& info) {
397-
// Use the "WeakCallback mechanism" to delete the C++ `bundle` object.
398-
// This will be called when the v8::External containing `this` pointer
399-
// is being GC-ed.
400-
CallbackBundle* bundle = info.GetParameter();
401-
delete bundle;
402-
}
403386
};
404387

405388
// Base class extended by classes that wrap V8 function and property callback
@@ -580,6 +563,11 @@ class SetterCallbackWrapper
580563
const v8::Local<v8::Value>& _value;
581564
};
582565

566+
static void DeleteCallbackBundle(napi_env env, void* data, void* hint) {
567+
CallbackBundle* bundle = static_cast<CallbackBundle*>(data);
568+
delete bundle;
569+
}
570+
583571
// Creates an object to be made available to the static function callback
584572
// wrapper, used to retrieve the native callback function and data pointer.
585573
static
@@ -591,7 +579,7 @@ v8::Local<v8::Value> CreateFunctionCallbackData(napi_env env,
591579
bundle->cb_data = data;
592580
bundle->env = env;
593581
v8::Local<v8::Value> cbdata = v8::External::New(env->isolate, bundle);
594-
bundle->BindLifecycleTo(env->isolate, cbdata);
582+
Reference::New(env, cbdata, 0, true, DeleteCallbackBundle, bundle, nullptr);
595583

596584
return cbdata;
597585
}

0 commit comments

Comments
 (0)