diff --git a/interfaces/inner_api/napi/native_node_api.h b/interfaces/inner_api/napi/native_node_api.h index 5dbcd8dc54c8d95204190c8e6fd9e29081c871f6..d5ec84c0d345d14f2b1f337e8ea4ea7767ffee8c 100644 --- a/interfaces/inner_api/napi/native_node_api.h +++ b/interfaces/inner_api/napi/native_node_api.h @@ -209,11 +209,18 @@ NAPI_EXTERN napi_status napi_create_xref(napi_env env, napi_value value, uint32_t initial_refcount, napi_ref* result); + +typedef napi_value (*proxy_object_attach_cb)(napi_env env, void* data); +NAPI_EXTERN napi_status napi_mark_attach_with_xref(napi_env env, + napi_value js_object, + void *attach_data, + proxy_object_attach_cb attach_cb); NAPI_EXTERN napi_status napi_wrap_with_xref(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, - napi_ref* result); + napi_ref* result, + proxy_object_attach_cb proxy_cb); NAPI_EXTERN napi_status napi_is_alive_object(napi_env env, napi_ref ref, bool* result); NAPI_EXTERN napi_status napi_is_contain_object(napi_env env, napi_ref ref, bool* result); NAPI_EXTERN napi_status napi_is_xref_type(napi_env env, napi_value js_object, bool* result); diff --git a/native_engine/native_api.cpp b/native_engine/native_api.cpp index d3d17439f738324e71e03294a572d1780668e9dc..e056d2d856cf502573a23ec4234bea3931610860 100644 --- a/native_engine/native_api.cpp +++ b/native_engine/native_api.cpp @@ -4475,11 +4475,51 @@ NAPI_EXTERN napi_status napi_create_xref(napi_env env, napi_value value, uint32_ return napi_clear_last_error(env); } +typedef napi_value (*proxy_object_attach_cb)(napi_env env, void* data); +NAPI_EXTERN napi_status napi_mark_attach_with_xref(napi_env env, + napi_value js_object, + void *attach_data, + proxy_object_attach_cb attach_cb) +{ + NAPI_PREAMBLE(env); + CHECK_ARG(env, js_object); + CHECK_ARG(env, attach_data); + CHECK_ARG(env, attach_cb); + + auto nativeValue = LocalValueFromJsValue(js_object); + auto engine = reinterpret_cast(env); + auto vm = engine->GetEcmaVm(); + panda::JsiFastNativeScope fastNativeScope(vm); + CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject); + size_t nativeBindingSize = 0; + Local key = panda::StringRef::GetProxyNapiWrapperString(vm); + Local object = panda::ObjectRef::NewJSXRefObject(vm); + // Create strong reference now, will update to weak reference after interop support + panda::JSNApi::XRefBindingInfo* data = panda::JSNApi::XRefBindingInfo::CreateNewInstance(); + if (data == nullptr) { + HILOG_ERROR("data is nullptr"); + return napi_set_last_error(env, napi_invalid_arg); + } + data->attachXRefFunc = reinterpret_cast(attach_cb); + data->attachXRefData = attach_data; + object->SetNativePointerFieldCount(vm, 1); + object->SetNativePointerField(vm, 0, nullptr, + [](void* env, void* data, void* info) { + panda::JSNApi::XRefBindingInfo* externalInfo = reinterpret_cast(info); + delete externalInfo; + }, + reinterpret_cast(data), nativeBindingSize); + PropertyAttribute attr(object, true, false, true); + nativeObject->DefineProperty(vm, key, attr); + return GET_RETURN_STATUS(env); +} + NAPI_EXTERN napi_status napi_wrap_with_xref(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, - napi_ref* result) + napi_ref* result, + proxy_object_attach_cb proxy_cb = nullptr) { NAPI_PREAMBLE(env); CHECK_ARG(env, js_object); @@ -4501,8 +4541,20 @@ NAPI_EXTERN napi_status napi_wrap_with_xref(napi_env env, // Create strong reference now, will update to weak reference after interop support ref = engine->CreateXRefReference(js_object, 1, false, callback, native_object); *reference = ref; + panda::JSNApi::XRefBindingInfo* data = panda::JSNApi::XRefBindingInfo::CreateNewInstance(); + if (data == nullptr) { + HILOG_ERROR("data is nullptr"); + return napi_set_last_error(env, napi_invalid_arg); + } + data->attachXRefFunc = reinterpret_cast(proxy_cb); + data->attachXRefData = native_object; object->SetNativePointerFieldCount(vm, 1); - object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize); + object->SetNativePointerField(vm, 0, ref, + [](void* env, void* data, void* info) { + panda::JSNApi::XRefBindingInfo* externalInfo = reinterpret_cast(info); + delete externalInfo; + }, + reinterpret_cast(data), nativeBindingSize); PropertyAttribute attr(object, true, false, true); nativeObject->DefineProperty(vm, key, attr); return GET_RETURN_STATUS(env);