diff --git a/BUILD.gn b/BUILD.gn index eb2b4c3321941e54d3da87db2c8bd8b54e54c291..1d28d6eab34d3251ad0ac5c11ffb386a835d3b4f 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -196,7 +196,6 @@ ohos_source_set("ace_napi_static") { configs += [ "${ets_runtime_path}:ark_jsruntime_public_config" ] } else { external_deps += [ - "ets_runtime:libark_jsruntime", "icu:shared_icui18n", "icu:shared_icuuc", "libuv:uv", @@ -204,6 +203,11 @@ ohos_source_set("ace_napi_static") { if (!ark_standalone_build) { external_deps += [ "node:node_header_notice" ] } + if (defined(ark_hybrid) && ark_hybrid) { + external_deps += [ "runtime_core:libarkruntime" ] + } else { + external_deps += [ "ets_runtime:libark_jsruntime" ] + } } cflags_cc = [ "-Wno-missing-braces" ] diff --git a/interfaces/inner_api/cjffi/ark_interop/BUILD.gn b/interfaces/inner_api/cjffi/ark_interop/BUILD.gn index c09ff8dc3350b826da7ebc6451eec44db91a1ef2..4bc0a3837b8059fd863ad181bf63bfc073861d2a 100644 --- a/interfaces/inner_api/cjffi/ark_interop/BUILD.gn +++ b/interfaces/inner_api/cjffi/ark_interop/BUILD.gn @@ -83,7 +83,12 @@ ohos_shared_library("ark_interop") { "../../../..:ace_napi", ] - external_deps = [ "ets_runtime:libark_jsruntime" ] + external_deps = [] + if (defined(ark_hybrid) && ark_hybrid) { + external_deps += [ "runtime_core:libarkruntime" ] + } else { + external_deps += [ "ets_runtime:libark_jsruntime" ] + } if (!ark_standalone_build) { external_deps += [ "hilog:libhilog" ] diff --git a/interfaces/inner_api/napi/native_node_api.h b/interfaces/inner_api/napi/native_node_api.h index c871bffa3c80b6d23e20b3a9f990e4be00cfce32..78ca10dedb9917b58820187df8b7539280ca5dbc 100644 --- a/interfaces/inner_api/napi/native_node_api.h +++ b/interfaces/inner_api/napi/native_node_api.h @@ -27,7 +27,7 @@ typedef void (*NAPIGetJSCode)(const char** buf, int* bufLen); typedef void (*NapiNativeFinalize)(napi_env env, void* data, void* hint); -typedef void* (*NapiDetachCallback)(napi_env env, void* nativeObject, void* hint); // hint: detach params +typedef void* (*NapiDetachCallback)(napi_env env, void* nativeObject, void* hint); // hint: detach params typedef napi_value (*NapiAttachCallback)(napi_env env, void* nativeObject, void* hint); // hint: attach params typedef bool (*napi_module_validate_callback)(const char* moduleName); typedef struct napi_fast_native_scope__* napi_fast_native_scope; diff --git a/interfaces/inner_api/napi/native_node_hybrid_api.h b/interfaces/inner_api/napi/native_node_hybrid_api.h index 38839f14d200ec184caead3eaca1c973d14d20d9..5f603d72082607b65df3c7f8ebfbda85227c69f3 100644 --- a/interfaces/inner_api/napi/native_node_hybrid_api.h +++ b/interfaces/inner_api/napi/native_node_hybrid_api.h @@ -85,13 +85,16 @@ NAPI_EXTERN napi_status napi_mark_attach_with_xref(napi_env env, void* attach_data, proxy_object_attach_cb attach_cb); +NAPI_EXTERN napi_status napi_mark_from_object_for_cmc(napi_env env, + napi_ref ref, + std::function& visitor); + 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); NAPI_EXTERN napi_status napi_get_ets_implements(napi_env env, napi_value value, napi_value* result); NAPI_EXTERN napi_status napi_deserialize_hybrid(napi_env env, void* buffer, napi_value* object); NAPI_EXTERN napi_status napi_setup_hybrid_environment(napi_env env); - NAPI_EXTERN napi_status napi_serialize_hybrid(napi_env env, napi_value object, napi_value transfer_list, @@ -100,6 +103,7 @@ NAPI_EXTERN napi_status napi_serialize_hybrid(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, + proxy_object_attach_cb proxy_cb, napi_ref* result); #endif // PANDA_JS_ETS_HYBRID_MODE NAPI_EXTERN napi_status napi_register_appstate_callback(napi_env env, NapiAppStateCallback callback); diff --git a/native_engine/impl/ark/ark_native_engine.cpp b/native_engine/impl/ark/ark_native_engine.cpp index 6dc8b8d735ade7bdd00b82f5f3f177da8c645ee9..0be2fe9aca1509af4188b6eceb0d46f7e242677e 100644 --- a/native_engine/impl/ark/ark_native_engine.cpp +++ b/native_engine/impl/ark/ark_native_engine.cpp @@ -23,6 +23,7 @@ #include "ark_hybrid_native_reference.h" #include "ark_native_deferred.h" #include "ark_native_reference.h" +#include "ark_hybrid_native_reference.h" #include "ark_native_timer.h" #include "native_engine/native_utils.h" #include "native_sendable.h" diff --git a/native_engine/impl/ark/ark_native_reference.cpp b/native_engine/impl/ark/ark_native_reference.cpp index ef60dc97c1d5bf0fdf465e4a6e4cf95cbb28eee1..19010f4a2bc33a8bfce6e4e780e1d2313a9f23ab 100644 --- a/native_engine/impl/ark/ark_native_reference.cpp +++ b/native_engine/impl/ark/ark_native_reference.cpp @@ -334,6 +334,11 @@ inline void ArkNativeReference::SetFinalRan() } #ifdef PANDA_JS_ETS_HYBRID_MODE +void ArkNativeReference::MarkFromObject(std::function &visitor) +{ + value_.MarkFromObject(visitor); +} + void ArkNativeReference::MarkFromObject() { value_.MarkFromObject(); diff --git a/native_engine/impl/ark/ark_native_reference.h b/native_engine/impl/ark/ark_native_reference.h index 3955cbf905aa3dcf37b878a60ffefe2453c51870..2219f8ca691d9879d122c79a1413461b3bf96362 100644 --- a/native_engine/impl/ark/ark_native_reference.h +++ b/native_engine/impl/ark/ark_native_reference.h @@ -91,6 +91,7 @@ public: napi_value GetNapiValue() override; void ResetFinalizer() override; #ifdef PANDA_JS_ETS_HYBRID_MODE + void MarkFromObject(std::function &visitor); void MarkFromObject(); bool IsObjectAlive(); bool IsValidHeapObject(); diff --git a/native_engine/native_node_api.cpp b/native_engine/native_node_api.cpp index 9319d07f9a20ea03722c706a0fbbaaa5adf7b932..b009f67a1e1e38b62e7181c2a4a093f99140e40e 100644 --- a/native_engine/native_node_api.cpp +++ b/native_engine/native_node_api.cpp @@ -20,6 +20,7 @@ using panda::Local; using panda::StringRef; +using panda::ObjectRef; static constexpr int32_t MAX_THREAD_SAFE_COUNT = 128; diff --git a/native_engine/native_node_hybrid_api.cpp b/native_engine/native_node_hybrid_api.cpp index 2d959cefeccfc8af4af0fe782e82546e3b31aa5f..4b2ae3b2258f260b8d11bd2b4e0ac5c69617a711 100644 --- a/native_engine/native_node_hybrid_api.cpp +++ b/native_engine/native_node_hybrid_api.cpp @@ -145,7 +145,16 @@ NAPI_EXTERN napi_status napi_xref_unwrap(napi_env env, napi_value js_object, voi panda::JsiFastNativeScope fastNativeScope(vm); CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject); Local key = panda::StringRef::GetProxyNapiWrapperString(vm); - Local val = nativeObject->Get(vm, key); + + Local val = {}; + if (UNLIKELY(nativeValue->IsProxy(vm))) { + val = nativeObject->Get(vm, key); + } else { + panda::PropertyAttribute property; + nativeObject->GetOwnProperty(vm, key, property); + val = property.GetValue(vm); + } + *result = nullptr; if (val->IsObject(vm)) { Local ext(val); @@ -216,6 +225,17 @@ NAPI_EXTERN napi_status napi_vm_handshake(napi_env env, return napi_clear_last_error(env); } +NAPI_EXTERN napi_status napi_mark_from_object_for_cmc(napi_env env, + napi_ref ref, + std::function& visitor) +{ + NAPI_PREAMBLE(env); + CHECK_ARG(env, ref); + ArkNativeReference* reference = reinterpret_cast(ref); + reference->MarkFromObject(visitor); + return napi_clear_last_error(env); +} + NAPI_EXTERN napi_status napi_is_alive_object(napi_env env, napi_ref ref, bool* result) { NAPI_PREAMBLE(env); @@ -330,6 +350,7 @@ NAPI_EXTERN napi_status napi_wrap_with_xref(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, + proxy_object_attach_cb proxy_cb, napi_ref* result) { NAPI_PREAMBLE(env); @@ -352,9 +373,22 @@ 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); - PropertyAttribute attr(object, true, false, true); + object->SetNativePointerField( + vm, 0, ref, + [](void* env, void* data, void* info) { + panda::JSNApi::XRefBindingInfo* externalInfo = reinterpret_cast(info); + delete externalInfo; + }, + reinterpret_cast(data), nativeBindingSize); + panda::PropertyAttribute attr(object, true, false, true); nativeObject->DefineProperty(vm, key, attr); return GET_RETURN_STATUS(env); } diff --git a/test/unittest/test_napi.cpp b/test/unittest/test_napi.cpp index 7e05d997979256a4e7e419899282776f70f632ed..19981a15f9fb339cf3bdf242af7ad9f0699c872c 100644 --- a/test/unittest/test_napi.cpp +++ b/test/unittest/test_napi.cpp @@ -7806,7 +7806,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest001, testing::ext::TestSize.Level1) napi_create_object(env, &obj); napi_status status = napi_wrap_with_xref( - env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, &result); + env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, nullptr, &result); ASSERT_EQ(status, napi_ok); } @@ -7818,7 +7818,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest002, testing::ext::TestSize.Level1) napi_create_object(env, &obj); napi_status status = napi_wrap_with_xref( - env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, &result); + env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, nullptr, &result); ASSERT_EQ(status, napi_ok); } @@ -7829,7 +7829,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest003, testing::ext::TestSize.Level1) napi_ref result; napi_status status = napi_wrap_with_xref( - env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, &result); + env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, nullptr, &result); ASSERT_EQ(status, napi_invalid_arg); } @@ -7841,7 +7841,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest004, testing::ext::TestSize.Level1) napi_create_object(env, &obj); napi_status status = napi_wrap_with_xref( - env, obj, nullptr, [](napi_env, void* data, void* hint) {}, &result); + env, obj, nullptr, [](napi_env, void* data, void* hint) {}, nullptr, &result); ASSERT_EQ(status, napi_invalid_arg); } @@ -7852,7 +7852,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest005, testing::ext::TestSize.Level1) napi_ref result; napi_create_object(env, &obj); - napi_status status = napi_wrap_with_xref(env, obj, (void*)TEST_STRING, nullptr, &result); + napi_status status = napi_wrap_with_xref(env, obj, (void*)TEST_STRING, nullptr, nullptr, &result); ASSERT_EQ(status, napi_invalid_arg); } @@ -7863,7 +7863,7 @@ HWTEST_F(NapiBasicTest, NapiWrapWithXRefTest006, testing::ext::TestSize.Level1) napi_ref result; napi_create_object(env, &obj); - napi_status status = napi_wrap_with_xref(env, obj, (void*)TEST_STRING, nullptr, &result); + napi_status status = napi_wrap_with_xref(env, obj, (void*)TEST_STRING, nullptr, nullptr, &result); ASSERT_EQ(status, napi_invalid_arg); } @@ -7875,7 +7875,7 @@ HWTEST_F(NapiBasicTest, NapiMarkFromObjectTest001, testing::ext::TestSize.Level1 napi_create_object(env, &obj); napi_status status = napi_wrap_with_xref( - env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, &result); + env, obj, (void*)TEST_STRING, [](napi_env, void* data, void* hint) {}, nullptr, &result); ASSERT_EQ(status, napi_ok); status = napi_mark_from_object(env, result); ASSERT_EQ(status, napi_ok); @@ -7915,6 +7915,33 @@ HWTEST_F(NapiBasicTest, NapiCreateXRefTest003, testing::ext::TestSize.Level1) auto res = napi_create_xref(env, nullptr, 1, nullptr); ASSERT_EQ(res, napi_invalid_arg); } + +HWTEST_F(NapiBasicTest, NapiCreateXRefTest004, testing::ext::TestSize.Level1) +{ + ASSERT_NE(engine_, nullptr); + napi_env env = reinterpret_cast(engine_); + + auto res = napi_serialize_hybrid(env, nullptr, nullptr, nullptr, nullptr); + ASSERT_EQ(res, napi_invalid_arg); +} + +HWTEST_F(NapiBasicTest, NapiCreateXRefTest005, testing::ext::TestSize.Level1) +{ + ASSERT_NE(engine_, nullptr); + napi_env env = reinterpret_cast(engine_); + + auto res = napi_deserialize_hybrid(env, nullptr, nullptr); + ASSERT_EQ(res, napi_invalid_arg); +} + +HWTEST_F(NapiBasicTest, NapiCreateXRefTest006, testing::ext::TestSize.Level1) +{ + ASSERT_NE(engine_, nullptr); + napi_env env = reinterpret_cast(engine_); + + auto res = napi_mark_attach_with_xref(env, nullptr, nullptr, nullptr); + ASSERT_EQ(res, napi_invalid_arg); +} #endif HWTEST_F(NapiBasicTest, NapiRegisterAppStateCallbakcTest001, testing::ext::TestSize.Level1)