From 2ee0adddb0f95051960d57fdf11185a962e0b035 Mon Sep 17 00:00:00 2001 From: zealotchen Date: Tue, 10 Dec 2024 21:56:52 +0800 Subject: [PATCH] feat(ohos): add jsi for jsvm --- driver/js/include/driver/napi/jsh/jsh_ctx.h | 1 + driver/js/src/napi/jsh/jsh_ctx.cc | 90 ++++++++- .../hippy_extend/ExampleNativeTurboModule.ets | 45 +++-- .../ets/hippy_extend/turbo/TurboConfig.ets | 24 +++ .../include/connector/arkts_turbo_module.h | 15 +- .../connector/include/connector/turbo.utils.h | 56 ++++++ .../impl/connector/src/arkts_turbo_module.cc | 67 ++++--- .../connector/src/turbo_module_manager.cc | 77 +++---- .../cpp/impl/connector/src/turbo_utils.cc | 189 ++++++++++++++++++ .../bridge/HippyBridgeManagerImpl.ets | 2 - 10 files changed, 460 insertions(+), 106 deletions(-) create mode 100644 framework/examples/ohos-demo/src/main/ets/hippy_extend/turbo/TurboConfig.ets create mode 100644 framework/ohos/src/main/cpp/impl/connector/include/connector/turbo.utils.h create mode 100644 framework/ohos/src/main/cpp/impl/connector/src/turbo_utils.cc diff --git a/driver/js/include/driver/napi/jsh/jsh_ctx.h b/driver/js/include/driver/napi/jsh/jsh_ctx.h index 910551b1124..af574c09d04 100644 --- a/driver/js/include/driver/napi/jsh/jsh_ctx.h +++ b/driver/js/include/driver/napi/jsh/jsh_ctx.h @@ -59,6 +59,7 @@ constexpr static int kJSHExternalIndex = 0; constexpr static int kJSHScopeWrapperIndex = 1; constexpr static int kJSHWeakCallbackWrapperInvalidIndex = 2; constexpr static int kJSHExternalDataNum = 3; +constexpr static int KJSHTurboFunctionGetIndex = 4; extern void* GetPointerInInstanceData(JSVM_Env env, int index); diff --git a/driver/js/src/napi/jsh/jsh_ctx.cc b/driver/js/src/napi/jsh/jsh_ctx.cc index dad4f77f8f8..de2489c42cb 100644 --- a/driver/js/src/napi/jsh/jsh_ctx.cc +++ b/driver/js/src/napi/jsh/jsh_ctx.cc @@ -45,7 +45,7 @@ using JSHVM = hippy::vm::JSHVM; using CallbackInfo = hippy::CallbackInfo; void* GetPointerInInstanceData(JSVM_Env env, int index) { - if (index < 0 || index >= kJSHExternalDataNum) { + if (index < 0 || index > KJSHTurboFunctionGetIndex) { return nullptr; } @@ -143,6 +143,8 @@ JSVM_Value InvokeJsCallbackOnConstruct(JSVM_Env env, JSVM_CallbackInfo info) { cb_info.AddValue(std::make_shared(env, argv[i])); } + void *wrap_result = nullptr; + status = OH_JSVM_RemoveWrap(env, thisArg, &wrap_result); status = OH_JSVM_Wrap(env, thisArg, cb_info.GetData(), nullptr, nullptr, nullptr); FOOTSTONE_DCHECK(status == JSVM_OK); @@ -213,7 +215,7 @@ std::shared_ptr JSHCtx::GetClassDefinition(const string_view& n } void JSHCtx::SetPointerInInstanceData(int index, void* address) { - if (index < 0 || index >= kJSHExternalDataNum) { + if (index < 0 || index > KJSHTurboFunctionGetIndex) { return; } @@ -1241,9 +1243,89 @@ void* JSHCtx::GetObjectExternalData(const std::shared_ptr& object) { return nullptr; } +static JSVM_Value GetPropertyCbInfo(JSVM_Env env, JSVM_Value name, JSVM_Value thisArg, JSVM_Value data) { + char strValue[100]; + size_t size; + OH_JSVM_GetValueStringUtf8(env, name, strValue, 300, &size); + CallbackInfo cb_info; + + void *scope_data = GetPointerInInstanceData(env, kJSHScopeWrapperIndex); + cb_info.SetSlot(scope_data); + + void *internal_data = nullptr; + auto status = OH_JSVM_Unwrap(env, thisArg, &internal_data); + if (status == JSVM_OK) { + if (internal_data) { + cb_info.SetData(internal_data); + } + } + + cb_info.SetReceiver(std::make_shared(env, thisArg)); + auto function_name = std::make_shared(env, name); + cb_info.AddValue(function_name); + + void* turbo_function_get = GetPointerInInstanceData(env, KJSHTurboFunctionGetIndex); + auto function_wrapper = reinterpret_cast(turbo_function_get); + FOOTSTONE_CHECK(function_wrapper); + auto js_cb = function_wrapper->callback; + auto external_data = function_wrapper->data; + + js_cb(cb_info, external_data); + auto exception = std::static_pointer_cast(cb_info.GetExceptionValue()->Get()); + if (exception) { + OH_JSVM_Throw(env, exception->GetValue()); + JSVM_Value result = nullptr; + OH_JSVM_GetUndefined(env, &result); + return result; + } + + auto ret_value = std::static_pointer_cast(cb_info.GetReturnValue()->Get()); + if (!ret_value) { + JSVM_Value result = nullptr; + OH_JSVM_GetUndefined(env, &result); + return result; + } + + return ret_value->GetValue(); +} + std::shared_ptr JSHCtx::DefineProxy(const std::unique_ptr& constructor_wrapper) { - // JSVM impl - return CreateFunction(constructor_wrapper); + JSHHandleScope handleScope(env_); + JSVM_Value func_tpl; + + callback_structs_.push_back(new JSVM_CallbackStruct()); + JSVM_CallbackStruct* constructorParam = callback_structs_.back(); + constructorParam->data = constructor_wrapper.get(); + constructorParam->callback = InvokeJsCallbackOnConstruct; + + callback_structs_.push_back(new JSVM_CallbackStruct()); + JSVM_CallbackStruct* callbackParam = callback_structs_.back(); + callbackParam->data = constructor_wrapper.get(); + callbackParam->callback = InvokeJsCallback; + + SetPointerInInstanceData(KJSHTurboFunctionGetIndex, constructor_wrapper.get()); + + JSVM_Value res = nullptr; + OH_JSVM_CreateBigintWords(env_, 1, 2, reinterpret_cast(constructor_wrapper.get()), &res); + JSVM_PropertyHandlerConfigurationStruct* propertyHandlerCfg = new JSVM_PropertyHandlerConfigurationStruct(); + propertyHandlerCfg->genericNamedPropertyGetterCallback = GetPropertyCbInfo; + propertyHandlerCfg->namedPropertyData = res; + propertyHandlerCfg->indexedPropertyData = res; + JSVM_PropertyHandlerCfg propertyHandlerConfig = propertyHandlerCfg; + + JSVM_Status status = OH_JSVM_DefineClassWithPropertyHandler( + env_, + "ProxyWrap", + JSVM_AUTO_LENGTH, + constructorParam, + 0, + nullptr, + propertyHandlerConfig, + callbackParam, + &func_tpl); + FOOTSTONE_DCHECK(status == JSVM_OK); + + return std::make_shared(env_, func_tpl); } std::shared_ptr JSHCtx::DefineClass(const string_view& name, diff --git a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleNativeTurboModule.ets b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleNativeTurboModule.ets index c53f11cbe2d..37cac77015a 100644 --- a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleNativeTurboModule.ets +++ b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleNativeTurboModule.ets @@ -18,11 +18,10 @@ * limitations under the License. */ import { HippyEngineContext } from 'hippy'; -import { HippyModulePromise } from 'hippy/src/main/ets/hippy_framework/modules/HippyModulePromise'; import { HippyNativeModuleBase } from 'hippy/src/main/ets/hippy_framework/modules/native'; import { HippyNativeModule } from 'hippy/src/main/ets/support/annotation/HippyNativeModule'; -import { HippyAny } from 'hippy/src/main/ets/support/common/HippyTypes'; -import { LogUtils } from 'hippy/src/main/ets/support/utils/LogUtils'; +import { HippyAny, HippyArray, HippyMap } from 'hippy/src/main/ets/support/common/HippyTypes'; +import { TurboConfig } from './turbo/TurboConfig'; @HippyNativeModule({ name: "demoTurbo" }) @@ -37,19 +36,35 @@ export class ExampleNativeTurboModule extends HippyNativeModuleBase { return true } - public call(method: string, params: Array, promise: HippyModulePromise): HippyAny { - switch (method) { - case 'getString': { - this.getString(params[0] as string); - break; - } - default: - super.call(method, params, promise); - } - return null; - } - public getString(info: string): string { return 'demoTurbo' + info; } + + public getNum(num: number): number { + return num; + } + + public getBoolean(b: boolean): boolean { + return b; + } + + public getMap(map: HippyMap): HippyMap { + return map + } + + public getArray(array: HippyArray): HippyArray { + return array + } + + public getObject(obj: HippyAny): HippyAny { + return obj + } + + public getTurboConfig(): TurboConfig { + return new TurboConfig(); + } + + public printTurboConfig(turboConfig: TurboConfig): string { + return turboConfig.info; + } } diff --git a/framework/examples/ohos-demo/src/main/ets/hippy_extend/turbo/TurboConfig.ets b/framework/examples/ohos-demo/src/main/ets/hippy_extend/turbo/TurboConfig.ets new file mode 100644 index 00000000000..31306ed9dae --- /dev/null +++ b/framework/examples/ohos-demo/src/main/ets/hippy_extend/turbo/TurboConfig.ets @@ -0,0 +1,24 @@ +/* + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2022 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +export class TurboConfig { + public info = "info from turboConfig" +} diff --git a/framework/ohos/src/main/cpp/impl/connector/include/connector/arkts_turbo_module.h b/framework/ohos/src/main/cpp/impl/connector/include/connector/arkts_turbo_module.h index 7905ab56cf7..8f0bdf35af8 100644 --- a/framework/ohos/src/main/cpp/impl/connector/include/connector/arkts_turbo_module.h +++ b/framework/ohos/src/main/cpp/impl/connector/include/connector/arkts_turbo_module.h @@ -24,7 +24,6 @@ #include -//#include "connector/convert_utils.h" #include "connector/turbo.h" #include "driver/napi/js_ctx.h" @@ -38,7 +37,7 @@ class ArkTsTurboModule { using CtxValue = hippy::napi::CtxValue; using FunctionWrapper = hippy::napi::FunctionWrapper; using PropertyDescriptor = hippy::napi::PropertyDescriptor; -// + struct TurboWrapper { ArkTsTurboModule* module; std::shared_ptr name; @@ -57,15 +56,14 @@ class ArkTsTurboModule { ArkTsTurboModule(const std::string& name, std::shared_ptr& impl, - const std::shared_ptr& ctx); + const std::shared_ptr& ctx, + napi_env env); std::string name; std::shared_ptr impl; + napi_env env; std::unique_ptr wrapper_holder_; -// -// // methodName, signature -// std::unordered_map method_map_; -// + std::shared_ptr constructor; std::unique_ptr constructor_wrapper; std::unordered_map, std::unique_ptr> turbo_wrapper_map; @@ -77,9 +75,6 @@ class ArkTsTurboModule { hippy::napi::CallbackInfo& info, void* data); -// static void Init(JNIEnv* j_env); -// -// static void Destroy(JNIEnv* j_env); }; } diff --git a/framework/ohos/src/main/cpp/impl/connector/include/connector/turbo.utils.h b/framework/ohos/src/main/cpp/impl/connector/include/connector/turbo.utils.h new file mode 100644 index 00000000000..feeef2f2ade --- /dev/null +++ b/framework/ohos/src/main/cpp/impl/connector/include/connector/turbo.utils.h @@ -0,0 +1,56 @@ +// +// Created on 2024/7/10. +// +// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, +// please include "napi/native_api.h". + +/* + * + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include "driver/napi/js_ctx_value.h" +#include "driver/napi/js_ctx.h" +#include "oh_napi/ark_ts.h" + +using CtxValue = hippy::napi::CtxValue; +using Ctx = hippy::napi::Ctx; + +namespace hippy { +inline namespace framework { +inline namespace turbo { + +class TurboUtils { +public: + static std::shared_ptr NapiValue2CtxValue( + napi_env env, + napi_value value, + const std::shared_ptr& ctx); + static napi_value CtxValue2NapiValue( + napi_env env, + const std::shared_ptr& ctx, + const std::shared_ptr& value); +}; + +} +} +} diff --git a/framework/ohos/src/main/cpp/impl/connector/src/arkts_turbo_module.cc b/framework/ohos/src/main/cpp/impl/connector/src/arkts_turbo_module.cc index f92895561d4..54c1ca5bec3 100644 --- a/framework/ohos/src/main/cpp/impl/connector/src/arkts_turbo_module.cc +++ b/framework/ohos/src/main/cpp/impl/connector/src/arkts_turbo_module.cc @@ -22,6 +22,7 @@ #include "connector/arkts_turbo_module.h" +#include "connector/turbo.utils.h" #include "driver/napi/js_ctx.h" #include "driver/napi/js_ctx_value.h" #include "driver/napi/callback_info.h" @@ -29,44 +30,63 @@ #include "footstone/logging.h" #include "footstone/string_view.h" #include "footstone/string_view_utils.h" +#include "oh_napi/oh_napi_task_runner.h" +#include "oh_napi/oh_napi_object.h" + +using string_view = footstone::string_view; +using StringViewUtils = footstone::StringViewUtils; +using Ctx = hippy::Ctx; +using CtxValue = hippy::CtxValue; +using CallbackInfo = hippy::CallbackInfo; +using ScopeWrapper = hippy::ScopeWrapper; +using TurboUtils = hippy::TurboUtils; -// using string_view = footstone::string_view; -// using StringViewUtils = footstone::StringViewUtils; -// using Ctx = hippy::Ctx; -// using CtxValue = hippy::CtxValue; -// using CallbackInfo = hippy::CallbackInfo; -// using JNIEnvironment = hippy::JNIEnvironment; -// using ScopeWrapper = hippy::ScopeWrapper; -// using JavaRef = hippy::JavaRef; -// using JniUtils = hippy::JniUtils; namespace hippy { inline namespace framework { inline namespace turbo { -// static jclass argument_utils_clazz; -// static jmethodID get_methods_signature; - std::shared_ptr ArkTsTurboModule::InvokeArkTsMethod(const std::shared_ptr& prop_name, CallbackInfo& info, void* data) { - auto wrapper = reinterpret_cast(data); - FOOTSTONE_CHECK(wrapper && wrapper->module && wrapper->name); - auto scope_wrapper = reinterpret_cast(std::any_cast(info.GetSlot())); + FOOTSTONE_DLOG(INFO) << "[turbo-perf] enter invokeArkTSMethod"; + + auto scope_wrapper = reinterpret_cast(std::any_cast(info.GetSlot())); auto scope = scope_wrapper->scope.lock(); - auto context = scope->GetContext(); - return context->CreateUndefined(); -// auto result = wrapper->module->InvokeArkTsMethod(wrapper->name, info, data); + FOOTSTONE_CHECK(scope); + auto context = scope->GetContext(); + string_view str_view; + std::string method; + std::shared_ptr result; + if (context->GetValueString(prop_name, &str_view)) { + method = StringViewUtils::ToStdString( + StringViewUtils::ConvertEncoding(str_view, string_view::Encoding::Utf8).utf8_value()); + } + + FOOTSTONE_DLOG(INFO) << "invokeArkTSMethod, method = " << method.c_str(); -// auto result = turboManager.Call(prop_name, args); -// }); -// return module; + OhNapiTaskRunner *taskRunner = OhNapiTaskRunner::Instance(env); + taskRunner->RunSyncTask([env = env, impl = impl, &info, context, method, &result]() { + ArkTS arkTs(env); + napi_ref turbo_module_ref = impl->GetRef(); + auto turboModule = arkTs.GetObject(turbo_module_ref); + std::vector args; + for (size_t i = 0; i < info.Length(); ++i) { + auto item = info[i]; + napi_value value = TurboUtils::CtxValue2NapiValue(env, context, item); + args.push_back(value); + } + napi_value ret = turboModule.Call(method, args); + result = TurboUtils::NapiValue2CtxValue(env, ret, context); + }); + return result; } ArkTsTurboModule::ArkTsTurboModule(const std::string& name, std::shared_ptr& impl, - const std::shared_ptr& ctx) - : name(name), impl(impl) { + const std::shared_ptr& ctx, + napi_env env) + : name(name), impl(impl), env(env) { auto getter = std::make_unique([](CallbackInfo& info, void* data) { auto scope_wrapper = reinterpret_cast(std::any_cast(info.GetSlot())); auto scope = scope_wrapper->scope.lock(); @@ -87,7 +107,6 @@ ArkTsTurboModule::ArkTsTurboModule(const std::string& name, auto scope_wrapper = reinterpret_cast(std::any_cast(info.GetSlot())); auto scope = scope_wrapper->scope.lock(); FOOTSTONE_CHECK(scope); - auto ctx = scope->GetContext(); auto wrapper = reinterpret_cast(data); FOOTSTONE_CHECK(wrapper && wrapper->module && wrapper->name); auto result = wrapper->module->InvokeArkTsMethod(wrapper->name, info, data); diff --git a/framework/ohos/src/main/cpp/impl/connector/src/turbo_module_manager.cc b/framework/ohos/src/main/cpp/impl/connector/src/turbo_module_manager.cc index 7c2cbfeac0e..48e62d8eae1 100644 --- a/framework/ohos/src/main/cpp/impl/connector/src/turbo_module_manager.cc +++ b/framework/ohos/src/main/cpp/impl/connector/src/turbo_module_manager.cc @@ -44,19 +44,15 @@ #include -#include #include "footstone/logging.h" #include "footstone/string_view.h" #include "footstone/string_view_utils.h" -#include "driver/napi/v8/v8_ctx.h" - using namespace hippy::napi; using string_view = footstone::string_view; using StringViewUtils = footstone::StringViewUtils; -using V8Ctx = hippy::V8Ctx; constexpr char kTurboKey[] = "getTurboModule"; @@ -70,30 +66,6 @@ void InitTurbo(napi_env env) { s_env = env; } -/** - * com.tencent.mtt.hippy.bridge.jsi.TurboModuleManager.get - */ -std::shared_ptr QueryTurboModuleImpl(std::shared_ptr& scope, const std::string& module_name) { - FOOTSTONE_DLOG(INFO) << "enter QueryTurboModuleImpl " << module_name.c_str(); - auto turbo = std::any_cast>(scope->GetTurbo()); - napi_ref object_ref = turbo->GetRef(); - auto env = s_env; - ArkTS arkTs(env); - auto turboManager = arkTs.GetObject(object_ref); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - std::wstring_convert, char16_t> converter; -#pragma clang diagnostic pop - std::vector args = { - arkTs.CreateStringUtf16(converter.from_bytes(module_name)), - }; - auto module = turboManager.Call("get", args); - auto module_object_ref = arkTs.CreateReference(module); - auto module_object = std::make_shared(module_object_ref); -// }); - return module_object; -} - void GetTurboModule(CallbackInfo& info, void* data) { FOOTSTONE_DLOG(INFO) << "[turbo-perf] enter getTurboModule"; auto scope_wrapper = reinterpret_cast(std::any_cast(info.GetSlot())); @@ -121,34 +93,37 @@ void GetTurboModule(CallbackInfo& info, void* data) { // 2. if not cached, query from ArkTs auto env = s_env; OhNapiTaskRunner *taskRunner = OhNapiTaskRunner::Instance(env); - taskRunner->RunAsyncTask([info, scope, u8_name, name, ctx, result]() { - auto module_impl = QueryTurboModuleImpl(scope, u8_name); - if (!module_impl) { - FOOTSTONE_LOG(ERROR) << "Cannot find TurboModule = " << name; - ctx->ThrowException("Cannot find TurboModule: " + name); - return info.GetReturnValue()->SetUndefined(); - } - - // 3. constructor c++ JavaTurboModule - auto arkTs_turbo_module = std::make_shared(u8_name, module_impl, ctx); - - // 4. bind c++ JavaTurboModule to js - result = ctx->NewInstance(arkTs_turbo_module->constructor, 0, nullptr, arkTs_turbo_module.get()); - - // 5. add To Cache - scope->SetTurboInstance(u8_name, result); - scope->SetTurboHostObject(u8_name, arkTs_turbo_module); - - FOOTSTONE_DLOG(INFO) << "return module = " << name; - }); + taskRunner->RunSyncTask([&info, env, scope, u8_name, name, ctx, &result]() { + auto turbo = std::any_cast>(scope->GetTurbo()); + ArkTS arkTs(env); + napi_ref object_ref = turbo->GetRef(); + auto turboManager = arkTs.GetObject(object_ref); + std::vector args = { + arkTs.CreateString(u8_name), + }; + auto module = turboManager.Call("get", args); + auto module_object_ref = arkTs.CreateReference(module); + auto module_object = std::make_shared(module_object_ref); + + // 3. constructor c++ JavaTurboModule + auto arkTs_turbo_module = std::make_shared(u8_name, module_object, ctx, env); + + // 4. bind c++ JavaTurboModule to js + result = ctx->NewInstance(arkTs_turbo_module->constructor, 0, nullptr, arkTs_turbo_module.get()); + + // 5. add To Cache + scope->SetTurboInstance(u8_name, result); + scope->SetTurboHostObject(u8_name, arkTs_turbo_module); + + FOOTSTONE_DLOG(INFO) << "return module = " << name; + info.GetReturnValue()->Set(result); + }); } else { result = scope->GetTurboInstance(u8_name); + info.GetReturnValue()->Set(result); FOOTSTONE_DLOG(INFO) << "return cached module = " << name; } - - info.GetReturnValue()->Set(result); FOOTSTONE_DLOG(INFO) << "[turbo-perf] exit getTurboModule"; - } void TurboModuleManager::Destroy(napi_env env, napi_callback_info info) { diff --git a/framework/ohos/src/main/cpp/impl/connector/src/turbo_utils.cc b/framework/ohos/src/main/cpp/impl/connector/src/turbo_utils.cc new file mode 100644 index 00000000000..cfdc6479996 --- /dev/null +++ b/framework/ohos/src/main/cpp/impl/connector/src/turbo_utils.cc @@ -0,0 +1,189 @@ +/* + * + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "connector/turbo.utils.h" +#include "oh_napi/oh_napi_utils.h" +#include "oh_napi/oh_napi_object.h" +#include "oh_napi/oh_napi_object_builder.h" +#include "driver/napi/js_ctx_value.h" +#include "driver/napi/js_ctx.h" +#include "footstone/string_view.h" +#include "footstone/string_view_utils.h" + +using CtxValue = hippy::napi::CtxValue; +using Ctx = hippy::napi::Ctx; +using string_view = footstone::string_view; +using StringViewUtils = footstone::StringViewUtils; + +namespace hippy { +inline namespace framework { +inline namespace turbo { + +std::shared_ptr TurboUtils::NapiValue2CtxValue( + napi_env env, + napi_value value, + const std::shared_ptr& ctx) { + ArkTS arkTs(env); + auto type = arkTs.GetType(value); + + switch (type) { + case napi_undefined: { + return ctx->CreateUndefined(); + } + case napi_null: { + return ctx->CreateNull(); + } + case napi_boolean: { + bool result = arkTs.GetBoolean(value); + return ctx->CreateBoolean(result); + } + case napi_number: { + double result = arkTs.GetDouble(value); + return ctx->CreateNumber(result); + } + case napi_string: { + std::string result = arkTs.GetString(value); + return ctx->CreateString(string_view::new_from_utf8(result.c_str(), result.length())); + } + case napi_symbol: { + return ctx->CreateUndefined(); + } + case napi_object: { + if (arkTs.IsArray(value)) { + auto length = arkTs.GetArrayLength(value); + std::shared_ptr array[length]; + if (length > 0) { + for (uint32_t i = 0; i < length; i ++) { + auto item = arkTs.GetArrayElement(value, i); + auto objValue = NapiValue2CtxValue(env, item, ctx); + array[i] = objValue; + } + } + return ctx->CreateArray(length, array); + } + std::unordered_map, std::shared_ptr> map; + OhNapiObject napiObj = arkTs.GetObject(value); + std::vector> pairs = napiObj.GetKeyValuePairs(); + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto &pair = *it; + auto &pairItem1 = pair.first; + auto objKey = arkTs.GetString(pairItem1); + if (objKey.length() > 0) { + auto &pairItem2 = pair.second; + auto key = ctx->CreateString(string_view::new_from_utf8(objKey.c_str(), objKey.length())); + auto objValue = NapiValue2CtxValue(env, pairItem2, ctx); + map[key] = objValue; + } + } + return ctx->CreateObject(map); + } + case napi_function: { + return ctx->CreateUndefined(); + } + case napi_external: { + return ctx->CreateUndefined(); + } + case napi_bigint: { + int64_t result = arkTs.GetInt64(value); + return ctx->CreateNumber(static_cast(result)); + } + default: + break; + } + return ctx->CreateUndefined(); +} + +napi_value TurboUtils::CtxValue2NapiValue( + napi_env env, + const std::shared_ptr& ctx, + const std::shared_ptr& value) { + ArkTS arkTs(env); + if (ctx->IsNumber(value)) { + double num; + ctx->GetValueNumber(value, &num); + return arkTs.CreateDouble(num); + } else if (ctx->IsBoolean(value)) { + bool v; + ctx->GetValueBoolean(value, &v); + return arkTs.CreateBoolean(v); + } else if (ctx->IsString(value)) { + string_view str_view; + ctx->GetValueString(value, &str_view); + std::string str = StringViewUtils::ToStdString( + StringViewUtils::ConvertEncoding(str_view, string_view::Encoding::Utf8).utf8_value()); + return arkTs.CreateString(str); + } else if (ctx->IsMap(value)) { + std::unordered_map, std::shared_ptr> map; + auto flag = ctx->GetEntriesFromMap(value, map); + FOOTSTONE_CHECK(flag); + auto builder = arkTs.CreateObjectBuilder(); + for (const auto& [key_object, value_object]: map) { + string_view key_string_view; + flag = ctx->GetValueString(key_object, &key_string_view); + if (!flag) { + continue; + } + std::string key_string = StringViewUtils::ToStdString( + StringViewUtils::ConvertEncoding(key_string_view, string_view::Encoding::Utf8).utf8_value()); + auto objNapiValue = CtxValue2NapiValue(env, ctx, value_object); + builder.AddProperty(key_string.c_str(), objNapiValue); + } + return builder.Build(); + } else if (ctx -> IsArray(value)) { + uint32_t array_len = ctx->GetArrayLength(value); + std::vector argv; + for (uint32_t i = 0; i < array_len; i++) { + std::shared_ptr item = ctx->CopyArrayElement(value, i); + argv.push_back(CtxValue2NapiValue(env, ctx, item)); + } + return arkTs.CreateArray(argv); + } else if (ctx->IsObject(value)) { + std::unordered_map, std::shared_ptr> map; + auto flag = ctx->GetEntriesFromObject(value, map); + FOOTSTONE_CHECK(flag); + auto builder = arkTs.CreateObjectBuilder(); + for (const auto& [key_object, value_object]: map) { + string_view key_string_view; + flag = ctx->GetValueString(key_object, &key_string_view); + if (!flag) { + continue; + } + std::string key_string = StringViewUtils::ToStdString( + StringViewUtils::ConvertEncoding(key_string_view, string_view::Encoding::Utf8).utf8_value()); + auto objNapiValue = CtxValue2NapiValue(env, ctx, value_object); + builder.AddProperty(key_string.c_str(), objNapiValue); + } + return builder.Build(); + } else if (ctx->IsArray(value)) { + auto array_len = ctx->GetArrayLength(value); + std::vector arrayNapiValues; + for (uint32_t it = 0; it != array_len; it++) { + std::shared_ptr item = ctx->CopyArrayElement(value, it); + arrayNapiValues.push_back(CtxValue2NapiValue(env, ctx, item)); + } + return arkTs.CreateArray(arrayNapiValues); + } + return arkTs.GetUndefined(); +} + +} +} +} diff --git a/framework/ohos/src/main/ets/hippy_framework/bridge/HippyBridgeManagerImpl.ets b/framework/ohos/src/main/ets/hippy_framework/bridge/HippyBridgeManagerImpl.ets index a61fcc69e60..7ffb2d6e858 100644 --- a/framework/ohos/src/main/ets/hippy_framework/bridge/HippyBridgeManagerImpl.ets +++ b/framework/ohos/src/main/ets/hippy_framework/bridge/HippyBridgeManagerImpl.ets @@ -266,10 +266,8 @@ export class HippyBridgeManagerImpl implements HippyBridgeManager, BridgeCallbac if (this.mContext != null) { this.mContext.reloadRootView(); } - // TODO if (this.enableTurbo()) { const mTurboModuleManager = new TurboModuleManager(this.mContext, this.libHippy); - // TODO runtimeID mTurboModuleManager.install(this.mHippyBridge.getV8RuntimeId()); } // if (mThirdPartyAdapter != null) {