@@ -1157,6 +1157,63 @@ class ThreadSafeFunction : public node::AsyncResource {
11571157 bool handles_closing;
11581158};
11591159
1160+ enum WrapType {
1161+ retrievable,
1162+ anonymous
1163+ };
1164+
1165+ template <WrapType wrap_type> static inline
1166+ napi_status Wrap (napi_env env,
1167+ napi_value js_object,
1168+ void * native_object,
1169+ napi_finalize finalize_cb,
1170+ void * finalize_hint,
1171+ napi_ref* result) {
1172+ NAPI_PREAMBLE (env);
1173+ CHECK_ARG (env, js_object);
1174+
1175+ v8::Isolate* isolate = env->isolate ;
1176+ v8::Local<v8::Context> context = isolate->GetCurrentContext ();
1177+
1178+ v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue (js_object);
1179+ RETURN_STATUS_IF_FALSE (env, value->IsObject (), napi_invalid_arg);
1180+ v8::Local<v8::Object> obj = value.As <v8::Object>();
1181+
1182+ if (wrap_type == retrievable) {
1183+ // If we've already wrapped this object, we error out.
1184+ RETURN_STATUS_IF_FALSE (env,
1185+ !obj->HasPrivate (context, NAPI_PRIVATE_KEY (context, wrapper))
1186+ .FromJust (),
1187+ napi_invalid_arg);
1188+ } else if (wrap_type == anonymous) {
1189+ // If no finalize callback is provided, we error out.
1190+ CHECK_ARG (env, finalize_cb);
1191+ }
1192+
1193+ v8impl::Reference* reference = nullptr ;
1194+ if (result != nullptr ) {
1195+ // The returned reference should be deleted via napi_delete_reference()
1196+ // ONLY in response to the finalize callback invocation. (If it is deleted
1197+ // before then, then the finalize callback will never be invoked.)
1198+ // Therefore a finalize callback is required when returning a reference.
1199+ CHECK_ARG (env, finalize_cb);
1200+ reference = v8impl::Reference::New (
1201+ env, obj, 0 , false , finalize_cb, native_object, finalize_hint);
1202+ *result = reinterpret_cast <napi_ref>(reference);
1203+ } else {
1204+ // Create a self-deleting reference.
1205+ reference = v8impl::Reference::New (env, obj, 0 , true , finalize_cb,
1206+ native_object, finalize_cb == nullptr ? nullptr : finalize_hint);
1207+ }
1208+
1209+ if (wrap_type == retrievable) {
1210+ CHECK (obj->SetPrivate (context, NAPI_PRIVATE_KEY (context, wrapper),
1211+ v8::External::New (isolate, reference)).FromJust ());
1212+ }
1213+
1214+ return GET_RETURN_STATUS (env);
1215+ }
1216+
11601217} // end of namespace v8impl
11611218
11621219// Intercepts the Node-V8 module registration callback. Converts parameters
@@ -2859,41 +2916,12 @@ napi_status napi_wrap(napi_env env,
28592916 napi_finalize finalize_cb,
28602917 void * finalize_hint,
28612918 napi_ref* result) {
2862- NAPI_PREAMBLE (env);
2863- CHECK_ARG (env, js_object);
2864-
2865- v8::Isolate* isolate = env->isolate ;
2866- v8::Local<v8::Context> context = isolate->GetCurrentContext ();
2867-
2868- v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue (js_object);
2869- RETURN_STATUS_IF_FALSE (env, value->IsObject (), napi_invalid_arg);
2870- v8::Local<v8::Object> obj = value.As <v8::Object>();
2871-
2872- // If we've already wrapped this object, we error out.
2873- RETURN_STATUS_IF_FALSE (env,
2874- !obj->HasPrivate (context, NAPI_PRIVATE_KEY (context, wrapper)).FromJust (),
2875- napi_invalid_arg);
2876-
2877- v8impl::Reference* reference = nullptr ;
2878- if (result != nullptr ) {
2879- // The returned reference should be deleted via napi_delete_reference()
2880- // ONLY in response to the finalize callback invocation. (If it is deleted
2881- // before then, then the finalize callback will never be invoked.)
2882- // Therefore a finalize callback is required when returning a reference.
2883- CHECK_ARG (env, finalize_cb);
2884- reference = v8impl::Reference::New (
2885- env, obj, 0 , false , finalize_cb, native_object, finalize_hint);
2886- *result = reinterpret_cast <napi_ref>(reference);
2887- } else {
2888- // Create a self-deleting reference.
2889- reference = v8impl::Reference::New (env, obj, 0 , true , finalize_cb,
2890- native_object, finalize_cb == nullptr ? nullptr : finalize_hint);
2891- }
2892-
2893- CHECK (obj->SetPrivate (context, NAPI_PRIVATE_KEY (context, wrapper),
2894- v8::External::New (isolate, reference)).FromJust ());
2895-
2896- return GET_RETURN_STATUS (env);
2919+ return v8impl::Wrap<v8impl::retrievable>(env,
2920+ js_object,
2921+ native_object,
2922+ finalize_cb,
2923+ finalize_hint,
2924+ result);
28972925}
28982926
28992927napi_status napi_unwrap (napi_env env, napi_value obj, void ** result) {
@@ -4138,3 +4166,17 @@ napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func) {
41384166 CHECK (func != nullptr );
41394167 return reinterpret_cast <v8impl::ThreadSafeFunction*>(func)->Ref ();
41404168}
4169+
4170+ napi_status napi_add_finalizer (napi_env env,
4171+ napi_value js_object,
4172+ void * native_object,
4173+ napi_finalize finalize_cb,
4174+ void * finalize_hint,
4175+ napi_ref* result) {
4176+ return v8impl::Wrap<v8impl::anonymous>(env,
4177+ js_object,
4178+ native_object,
4179+ finalize_cb,
4180+ finalize_hint,
4181+ result);
4182+ }
0 commit comments