diff --git a/plugins/ets/ets_plugin_options.yaml b/plugins/ets/ets_plugin_options.yaml index d8e397beda55a90a5617bdf6bc86aec8c7575bad..c9fe31b0382b6ce6036962dc7564ac0ac2a568ad 100644 --- a/plugins/ets/ets_plugin_options.yaml +++ b/plugins/ets/ets_plugin_options.yaml @@ -38,6 +38,7 @@ components: - name: ets - name: ets_napi + - name: ets_interop_js Verification: header: plugins/ets/verification/ets_plugin.h diff --git a/plugins/ets/runtime/ets_exceptions.h b/plugins/ets/runtime/ets_exceptions.h index 440e5acaf9d25f159b1b937ab76afcecf114e8aa..79083057310ff50bd2c7c210226374f6af32d697 100644 --- a/plugins/ets/runtime/ets_exceptions.h +++ b/plugins/ets/runtime/ets_exceptions.h @@ -24,12 +24,12 @@ class EtsCoroutine; void ThrowEtsException(EtsCoroutine *coroutine, const char *class_descriptor, const char *msg); -static inline void ThrowEtsException(EtsCoroutine *coroutine, std::string_view class_descriptor, const char *msg) +inline void ThrowEtsException(EtsCoroutine *coroutine, std::string_view class_descriptor, const char *msg) { ThrowEtsException(coroutine, class_descriptor.data(), msg); } -static inline void ThrowEtsException(EtsCoroutine *coroutine, std::string_view class_descriptor, std::string_view msg) +inline void ThrowEtsException(EtsCoroutine *coroutine, std::string_view class_descriptor, std::string_view msg) { ThrowEtsException(coroutine, class_descriptor.data(), msg.data()); } diff --git a/plugins/ets/runtime/interop_js/BUILD.gn b/plugins/ets/runtime/interop_js/BUILD.gn index edfbfeff3e69b23449b8b58ddff9e289290ab187..47e27021bf80245e7810a7ef88715b2b39bc074b 100644 --- a/plugins/ets/runtime/interop_js/BUILD.gn +++ b/plugins/ets/runtime/interop_js/BUILD.gn @@ -31,7 +31,7 @@ ohos_shared_library("ets_interop_js_napi") { sources = [ "ets_vm_plugin.cpp", "js_value.cpp", - "global_context.cpp", + "interop_context.cpp", "intrinsics_api_impl.cpp", "js_value_call.cpp", "ts2ets_common.cpp", diff --git a/plugins/ets/runtime/interop_js/CMakeLists.txt b/plugins/ets/runtime/interop_js/CMakeLists.txt index b69bdf4c5db7345f773abc9f4757e336aee8fac5..014120b8ec21bb006fa2bf0edf0c617131034743 100644 --- a/plugins/ets/runtime/interop_js/CMakeLists.txt +++ b/plugins/ets/runtime/interop_js/CMakeLists.txt @@ -27,7 +27,7 @@ endif() panda_ets_interop_js_plugin(ets_interop_js_napi SOURCES - global_context.cpp + interop_context.cpp ets_vm_plugin.cpp intrinsics_api_impl.cpp js_value.cpp diff --git a/plugins/ets/runtime/interop_js/ets_type_visitor-inl.h b/plugins/ets/runtime/interop_js/ets_type_visitor-inl.h index 926c0eb0af3a47b4abf9aa0b6970e962512a29f5..a740a5c4a8dba67b14d302c3627f7ca0ec473de1 100644 --- a/plugins/ets/runtime/interop_js/ets_type_visitor-inl.h +++ b/plugins/ets/runtime/interop_js/ets_type_visitor-inl.h @@ -19,7 +19,6 @@ #include "libpandabase/macros.h" #include "runtime/include/runtime.h" #include "runtime/mem/heap_manager.h" -#include "plugins/ets/runtime/interop_js/global_context.h" namespace panda::ets::interop::js { diff --git a/plugins/ets/runtime/interop_js/ets_vm_plugin.cpp b/plugins/ets/runtime/interop_js/ets_vm_plugin.cpp index a95fa05d4246775be63d8e9b677082302faa3da7..97019624b895adeaa10ec4690eeb1d5857feea0f 100644 --- a/plugins/ets/runtime/interop_js/ets_vm_plugin.cpp +++ b/plugins/ets/runtime/interop_js/ets_vm_plugin.cpp @@ -16,17 +16,10 @@ #include #include "plugins/ets/runtime/ets_panda_file_items.h" #include "plugins/ets/runtime/ets_vm_api.h" -#include "plugins/ets/runtime/types/ets_method.h" -#include "plugins/ets/runtime/interop_js/js_value.h" -#include "plugins/ets/runtime/interop_js/js_convert.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" +#include "plugins/ets/runtime/interop_js/js_value_call.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/ts2ets_copy.h" -#include "plugins/ets/runtime/interop_js/global_context.h" -#include "plugins/ets/runtime/interop_js/js_value_call.h" -#include "runtime/handle_scope-inl.h" -#include "runtime/include/runtime.h" -#include "runtime/include/thread_scopes.h" #include "generated/base_options.h" #ifdef PANDA_TARGET_OHOS @@ -55,123 +48,6 @@ static napi_value Version(napi_env env, [[maybe_unused]] napi_callback_info info return result; } -EtsObject *JsPlugin::CreateJSException(EtsCoroutine *coro, JSValue *jsvalue) -{ - auto ctx = GetContext(); - [[maybe_unused]] HandleScope scope(coro); - VMHandle jsvalue_handle(coro, jsvalue->GetCoreType()); - - auto cls = ctx->JSExceptionClass(); - - Method::Proto proto(Method::Proto::ShortyVector {panda_file::Type(panda_file::Type::TypeId::VOID), - panda_file::Type(panda_file::Type::TypeId::REFERENCE)}, - Method::Proto::RefTypeVector {utf::Mutf8AsCString(ctx->JSValueClass()->GetDescriptor())}); - auto ctor_name = utf::CStringAsMutf8(panda_file_items::CTOR.data()); - auto ctor = cls->GetDirectMethod(ctor_name, proto); - ASSERT(ctor != nullptr); - - VMHandle exc_handle(coro, ObjectHeader::Create(cls)); - std::array args {Value(exc_handle.GetPtr()), Value(jsvalue_handle.GetPtr())}; - - ctor->InvokeVoid(coro, args.data()); - auto res = EtsObject::FromCoreType(exc_handle.GetPtr()); - if (UNLIKELY(coro->HasPendingException())) { - return nullptr; - } - return res; -} - -void JsPlugin::ThrowETSException(napi_value val) -{ - auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); - - if (coro->IsUsePreAllocObj()) { - coro->SetUsePreAllocObj(false); - coro->SetException(coro->GetVM()->GetOOMErrorObject()); - return; - } - ASSERT(!coro->HasPendingException()); - - auto exc = JSConvertJSException::Unwrap(ctx, ctx->GetJSEnv(), val); - if (LIKELY(exc.has_value())) { - ASSERT(exc != nullptr); - coro->SetException(exc.value()->GetCoreType()); - } // otherwise exception is already set -} - -void JsPlugin::ThrowETSException(char const *msg) -{ - auto coro = EtsCoroutine::GetCurrent(); - LanguageContext lang_ctx = coro->GetLanguageContext(); - const uint8_t *class_descriptor = utf::CStringAsMutf8("Lstd/interop/js/JSException;"); - panda::ThrowException(lang_ctx, coro, class_descriptor, utf::CStringAsMutf8(msg)); -} - -void JsPlugin::ThrowJSError(napi_env env, const std::string &msg) -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_ERROR_A("ThrowJSError: %s", msg.c_str()); - - bool pending; - NAPI_CHECK_FATAL(napi_is_exception_pending(env, &pending)); - if (!pending) { - napi_throw_error(env, nullptr, msg.c_str()); - } -} - -void JsPlugin::ThrowJSException(napi_env env, napi_value val) -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_INFO("ThrowJSException"); - napi_throw(env, val); -} - -void JsPlugin::ForwardEtsException(EtsCoroutine *coro) -{ - auto ctx = JsPlugin::GetCurrent(coro)->GetContext(); - auto env = ctx->GetJSEnv(); - - ASSERT(coro->HasPendingException()); - auto exc = EtsObject::FromCoreType(coro->GetException()); - coro->ClearException(); - auto klass = exc->GetClass(); - if (LIKELY(klass->GetRuntimeClass() == ctx->JSExceptionClass())) { - napi_value js_exc = JSConvertJSException::Wrap(env, exc); - JsPlugin::ThrowJSException(env, js_exc); - return; - } - // TODO(vpukhov): put proxy-object instead - JsPlugin::ThrowJSError(env, klass->GetDescriptor()); -} - -void JsPlugin::ForwardJSException([[maybe_unused]] EtsCoroutine *coro) -{ - auto ctx = JsPlugin::GetCurrent(coro)->GetContext(); - auto env = ctx->GetJSEnv(); - napi_value excval; - NAPI_CHECK_FATAL(napi_get_and_clear_last_exception(env, &excval)); - JsPlugin::ThrowETSException(excval); -} - -void JSConvertTypeCheckFailed(char const *type_name) -{ - auto ctx = GlobalCtx::Current(); - auto env = ctx->GetJSEnv(); - std::string str = type_name + std::string(" expected"); - napi_value js_val; - NAPI_CHECK_FATAL(napi_create_string_utf8(env, str.data(), str.length(), &js_val)); - JsPlugin::ThrowJSException(env, js_val); -} - -[[noreturn]] void JsPlugin::Fatal(char const *msg) -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_ERROR_A("JsPlugin::Fatal: %s", msg); - napi_fatal_error("ets::interop::js", NAPI_AUTO_LENGTH, msg, NAPI_AUTO_LENGTH); - std::abort(); -} - static napi_value Call(napi_env env, napi_callback_info info) { size_t argc = 0; @@ -180,7 +56,7 @@ static napi_value Call(napi_env env, napi_callback_info info) assert(status == napi_ok); auto coro = EtsCoroutine::GetCurrent(); - auto &argv = GlobalCtx::Current(coro)->GetTempArgs(argc); + auto &argv = InteropCtx::Current(coro)->GetTempArgs(argc); napi_value this_arg {}; void *data = nullptr; status = napi_get_cb_info(env, info, &argc, argv.data(), &this_arg, &data); @@ -197,7 +73,7 @@ static napi_value CallWithCopy(napi_env env, napi_callback_info info) assert(status == napi_ok); auto coro = EtsCoroutine::GetCurrent(); - auto &argv = GlobalCtx::Current(coro)->GetTempArgs(argc); + auto &argv = InteropCtx::Current(coro)->GetTempArgs(argc); napi_value this_arg {}; void *data = nullptr; status = napi_get_cb_info(env, info, &argc, argv.data(), &this_arg, &data); @@ -263,7 +139,7 @@ static napi_value CreateEtsRuntime(napi_env env, napi_callback_info info) if (res) { auto coro = EtsCoroutine::GetCurrent(); ScopedManagedCodeThread scoped(coro); - JsPlugin::Init(coro); + InteropCtx::Init(coro); } napi_value napi_res; status = napi_get_boolean(env, res, &napi_res); @@ -324,7 +200,7 @@ static napi_value CreateRuntime(napi_env env, napi_callback_info info) base_options->AddOptions(&pa_parser); runtime_options->AddOptions(&pa_parser); - std::vector fake_argv; + std::vector fake_argv; fake_argv.reserve(arg_strings.size()); for (auto const &arg : arg_strings) { fake_argv.push_back(arg.c_str()); // Be careful, do not reallocate referenced strings @@ -347,7 +223,7 @@ static napi_value CreateRuntime(napi_env env, napi_callback_info info) if (res) { auto coro = EtsCoroutine::GetCurrent(); ScopedManagedCodeThread scoped(coro); - JsPlugin::Init(coro); + InteropCtx::Init(coro); } napi_value napi_res; NAPI_ASSERT_OK(napi_get_boolean(env, res, &napi_res)); diff --git a/plugins/ets/runtime/interop_js/ets_vm_plugin.h b/plugins/ets/runtime/interop_js/ets_vm_plugin.h deleted file mode 100644 index 1da35446178cf557e23491b753d6ad157eaabd85..0000000000000000000000000000000000000000 --- a/plugins/ets/runtime/interop_js/ets_vm_plugin.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) 2023 Huawei Device Co., Ltd. - * 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. - */ - -#ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_JS_PLUGIN_H_ -#define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_JS_PLUGIN_H_ - -#include "libpandabase/macros.h" -#include "plugins/ets/runtime/ets_vm.h" -#include "plugins/ets/runtime/interop_js/global_context.h" -#include "plugins/ets/runtime/interop_js/intrinsics_api_impl.h" -#include "plugins/ets/runtime/interop_js/intrinsics/std_js_jsruntime.h" -#include "plugins/ets/runtime/interop_js/js_job_queue.h" - -namespace panda::ets::interop::js { - -class JSValue; - -class JsPlugin { -public: - static void Init(EtsCoroutine *coro) - { - // Initialize JsPlugin in VM ExternalData - new (JsPlugin::GetCurrent(coro)) JsPlugin(coro); - JSRuntimeIntrinsicsSetIntrinsicsAPI(GetIntrinsicsAPI()); - auto *job_queue = Runtime::GetCurrent()->GetInternalAllocator()->New(); - coro->GetPandaVM()->InitJobQueue(job_queue); - } - - GlobalCtx *GetContext() - { - return &ctx_; - } - - static JsPlugin *FromContext(GlobalCtx *ctx) - { - return reinterpret_cast(ToUintPtr(ctx) - MEMBER_OFFSET(JsPlugin, ctx_)); - } - - EtsObject *CreateJSException(EtsCoroutine *coro, JSValue *jsvalue); - - static void ThrowETSException(napi_value val); - static void ThrowETSException(char const *msg); - static void ThrowETSException(std::string const &msg) - { - ThrowETSException(msg.c_str()); - } - - static void ThrowJSError(napi_env env, const std::string &msg); - static void ThrowJSException(napi_env env, napi_value val); - - static void ForwardEtsException(EtsCoroutine *coro); - static void ForwardJSException(EtsCoroutine *coro); - - [[noreturn]] static void Fatal(char const *msg); - [[noreturn]] static void Fatal(std::string const &msg) - { - Fatal(msg.c_str()); - } - - static JsPlugin *GetCurrent(PandaEtsVM *ets_vm) - { - static_assert(sizeof(PandaEtsVM::ExternalData) >= sizeof(JsPlugin)); - static_assert(alignof(PandaEtsVM::ExternalData) >= alignof(JsPlugin)); - return reinterpret_cast(ets_vm->GetExternalData()); - } - - static JsPlugin *GetCurrent(EtsCoroutine *coro) - { - return JsPlugin::GetCurrent(coro->GetPandaVM()); - } - - static JsPlugin *GetCurrent() - { - return JsPlugin::GetCurrent(EtsCoroutine::GetCurrent()); - } - - PandaEtsVM *GetPandaEtsVM() - { - return PandaEtsVM::FromExternalData(reinterpret_cast(this)); - } - -private: - explicit JsPlugin(EtsCoroutine *coro) : ctx_(coro) {} - - GlobalCtx ctx_; -}; - -} // namespace panda::ets::interop::js - -#endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_JS_PLUGIN_H_ diff --git a/plugins/ets/runtime/interop_js/global_context.cpp b/plugins/ets/runtime/interop_js/interop_context.cpp similarity index 40% rename from plugins/ets/runtime/interop_js/global_context.cpp rename to plugins/ets/runtime/interop_js/interop_context.cpp index 6c597c2b45c2877cea14c038812116d94e298144..7ee817b8417fd5293a9092ba8b34c962b7dd2c0c 100644 --- a/plugins/ets/runtime/interop_js/global_context.cpp +++ b/plugins/ets/runtime/interop_js/interop_context.cpp @@ -13,12 +13,12 @@ * limitations under the License. */ -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" +#include "plugins/ets/runtime/ets_exceptions.h" #include "interop_js/js_convert.h" #include "plugins/ets/runtime/ets_class_linker_extension.h" #include "plugins/ets/runtime/ets_vm.h" -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" #include "runtime/include/runtime.h" #include "plugins/ets/runtime/types/ets_method.h" @@ -31,16 +31,14 @@ class JSRefConvertBuiltin : public JSRefConvert { public: JSRefConvertBuiltin() : JSRefConvert(this) {} - napi_value WrapImpl(JsPlugin *plugin, EtsObject *obj) + napi_value WrapImpl(InteropCtx *ctx, EtsObject *obj) { - auto ctx = plugin->GetContext(); using ObjType = std::remove_pointer_t; return Conv::Wrap(ctx->GetJSEnv(), FromEtsObject(obj)); } - EtsObject *UnwrapImpl(JsPlugin *plugin, napi_value js_value) + EtsObject *UnwrapImpl(InteropCtx *ctx, napi_value js_value) { - auto ctx = plugin->GetContext(); auto res = Conv::Unwrap(ctx, ctx->GetJSEnv(), js_value); if (!res) { return nullptr; @@ -55,25 +53,27 @@ static inline void RegisterBuiltinRefConvertor(JSRefConvertCache *cache, Class * cache->Insert(klass, std::unique_ptr(new JSRefConvertBuiltin())); } -void GlobalCtx::CacheClass(Class **klass, const char *descriptor) -{ - EtsClassLinker *ets_class_linker = JsPlugin::FromContext(this)->GetPandaEtsVM()->GetClassLinker(); - *klass = ets_class_linker->GetClass(descriptor)->GetRuntimeClass(); - ASSERT(*klass != nullptr); -} - -GlobalCtx::GlobalCtx(EtsCoroutine *coro) +InteropCtx::InteropCtx(EtsCoroutine *coro) { PandaEtsVM *vm = coro->GetPandaVM(); EtsClassLinker *ets_class_linker = vm->GetClassLinker(); refstor_ = vm->GetGlobalObjectStorage(); linker_ctx_ = ets_class_linker->GetEtsClassLinkerExtension()->GetBootContext(); - CacheClass(&jsruntime_class_, "Lstd/interop/js/JSRuntime;"); - CacheClass(&jsvalue_class_, "Lstd/interop/js/JSValue;"); - CacheClass(&jsexception_class_, "Lstd/interop/js/JSException;"); - CacheClass(&string_class_, "Lstd/core/String;"); - CacheClass(&promise_class_, "Lstd/core/Promise;"); + JSRuntimeIntrinsicsSetIntrinsicsAPI(GetIntrinsicsAPI()); + auto *job_queue = Runtime::GetCurrent()->GetInternalAllocator()->New(); + vm->InitJobQueue(job_queue); + + auto cache_class = [&](const char *descriptor) { + auto klass = ets_class_linker->GetClass(descriptor)->GetRuntimeClass(); + ASSERT(klass != nullptr); + return klass; + }; + jsruntime_class_ = cache_class("Lstd/interop/js/JSRuntime;"); + jsvalue_class_ = cache_class("Lstd/interop/js/JSValue;"); + jsexception_class_ = cache_class("Lstd/interop/js/JSException;"); + string_class_ = cache_class("Lstd/core/String;"); + promise_class_ = cache_class("Lstd/core/Promise;"); RegisterBuiltinRefConvertor(&refconvert_cache_, jsvalue_class_); RegisterBuiltinRefConvertor(&refconvert_cache_, jsexception_class_); @@ -96,9 +96,106 @@ GlobalCtx::GlobalCtx(EtsCoroutine *coro) } } -GlobalCtx *GlobalCtx::Current(EtsCoroutine *coro) +EtsObject *InteropCtx::CreateJSException(EtsCoroutine *coro, JSValue *jsvalue) +{ + [[maybe_unused]] HandleScope scope(coro); + VMHandle jsvalue_handle(coro, jsvalue->GetCoreType()); + + Method::Proto proto(Method::Proto::ShortyVector {panda_file::Type(panda_file::Type::TypeId::VOID), + panda_file::Type(panda_file::Type::TypeId::REFERENCE)}, + Method::Proto::RefTypeVector {utf::Mutf8AsCString(JSValueClass()->GetDescriptor())}); + auto ctor_name = utf::CStringAsMutf8(panda_file_items::CTOR.data()); + auto ctor = JSExceptionClass()->GetDirectMethod(ctor_name, proto); + ASSERT(ctor != nullptr); + + VMHandle exc_handle(coro, ObjectHeader::Create(JSExceptionClass())); + std::array args {Value(exc_handle.GetPtr()), Value(jsvalue_handle.GetPtr())}; + + ctor->InvokeVoid(coro, args.data()); + auto res = EtsObject::FromCoreType(exc_handle.GetPtr()); + if (UNLIKELY(coro->HasPendingException())) { + return nullptr; + } + return res; +} + +void InteropCtx::ThrowETSException(EtsCoroutine *coro, napi_value val) +{ + auto ctx = Current(coro); + + if (coro->IsUsePreAllocObj()) { + coro->SetUsePreAllocObj(false); + coro->SetException(coro->GetVM()->GetOOMErrorObject()); + return; + } + ASSERT(!coro->HasPendingException()); + + auto exc = JSConvertJSException::Unwrap(ctx, ctx->GetJSEnv(), val); + if (LIKELY(exc.has_value())) { + ASSERT(exc != nullptr); + coro->SetException(exc.value()->GetCoreType()); + } // otherwise exception is already set +} + +void InteropCtx::ThrowETSException(EtsCoroutine *coro, const char *msg) +{ + ets::ThrowEtsException(coro, "Lstd/interop/js/JSException;", msg); +} + +void InteropCtx::ThrowJSError(napi_env env, const std::string &msg) +{ + INTEROP_LOG(INFO) << "ThrowJSError: " << msg; + bool pending; + NAPI_CHECK_FATAL(napi_is_exception_pending(env, &pending)); + if (!pending) { + napi_throw_error(env, nullptr, msg.c_str()); + } +} + +void InteropCtx::ThrowJSException(napi_env env, napi_value val) +{ + INTEROP_LOG(INFO) << "ThrowJSException"; + napi_throw(env, val); +} + +void InteropCtx::ForwardEtsException(EtsCoroutine *coro) +{ + auto env = GetJSEnv(); + ASSERT(coro->HasPendingException()); + auto exc = EtsObject::FromCoreType(coro->GetException()); + coro->ClearException(); + auto klass = exc->GetClass(); + if (LIKELY(klass->GetRuntimeClass() == JSExceptionClass())) { + napi_value js_exc = JSConvertJSException::Wrap(env, exc); + ThrowJSException(env, js_exc); + return; + } + // TODO(vpukhov): put proxy-object instead + ThrowJSError(env, klass->GetDescriptor()); +} + +void InteropCtx::ForwardJSException(EtsCoroutine *coro) +{ + napi_value excval; + NAPI_CHECK_FATAL(napi_get_and_clear_last_exception(GetJSEnv(), &excval)); + ThrowETSException(coro, excval); +} + +void JSConvertTypeCheckFailed(const char *type_name) +{ + auto ctx = InteropCtx::Current(); + auto env = ctx->GetJSEnv(); + std::string str = type_name + std::string(" expected"); + napi_value js_val; + NAPI_CHECK_FATAL(napi_create_string_utf8(env, str.data(), str.length(), &js_val)); + InteropCtx::ThrowJSException(env, js_val); +} + +[[noreturn]] void InteropCtx::Fatal(const char *msg) { - return JsPlugin::GetCurrent(coro)->GetContext(); + INTEROP_LOG(ERROR) << "InteropCtx::Fatal: " << msg; + napi_fatal_error("ets::interop::js", NAPI_AUTO_LENGTH, msg, NAPI_AUTO_LENGTH); + std::abort(); } } // namespace panda::ets::interop::js diff --git a/plugins/ets/runtime/interop_js/global_context.h b/plugins/ets/runtime/interop_js/interop_context.h similarity index 67% rename from plugins/ets/runtime/interop_js/global_context.h rename to plugins/ets/runtime/interop_js/interop_context.h index 159e80cd496cd88657a481f93af06163b4d4838d..b455c08ad8766aa543da206dc77285db75bc81d5 100644 --- a/plugins/ets/runtime/interop_js/global_context.h +++ b/plugins/ets/runtime/interop_js/interop_context.h @@ -13,16 +13,21 @@ * limitations under the License. */ -#ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_GLOBAL_CONTEXT_H_ -#define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_GLOBAL_CONTEXT_H_ +#ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_INTEROP_CONTEXT_H_ +#define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_INTEROP_CONTEXT_H_ +#include "plugins/ets/runtime/ets_vm.h" #include "plugins/ets/runtime/ets_coroutine.h" #include "plugins/ets/runtime/interop_js/js_refconvert.h" +#include "plugins/ets/runtime/interop_js/js_job_queue.h" +#include "plugins/ets/runtime/interop_js/intrinsics_api_impl.h" #include "libpandabase/macros.h" #include "runtime/include/value.h" #include #include +#include "plugins/ets/runtime/interop_js/intrinsics/std_js_jsruntime.h" + namespace panda { class Class; @@ -37,6 +42,8 @@ class Reference; namespace panda::ets::interop::js { +class JSValue; + // Work-around for String JSValue and node_api class JSValueStringStorage { public: @@ -80,16 +87,36 @@ private: using ArgValueBox = std::variant; -// TODO(vpukhov): move contents to JSPlugin -class GlobalCtx { +class InteropCtx { public: - static GlobalCtx *Current(EtsCoroutine *coro); + static void Init(EtsCoroutine *coro) + { + // Initialize InteropCtx in VM ExternalData + new (InteropCtx::Current(coro)) InteropCtx(coro); + } + + static InteropCtx *Current(PandaEtsVM *ets_vm) + { + static_assert(sizeof(PandaEtsVM::ExternalData) >= sizeof(InteropCtx)); + static_assert(alignof(PandaEtsVM::ExternalData) >= alignof(InteropCtx)); + return reinterpret_cast(ets_vm->GetExternalData()); + } + + static InteropCtx *Current(EtsCoroutine *coro) + { + return Current(coro->GetPandaVM()); + } - static GlobalCtx *Current() + static InteropCtx *Current() { return Current(EtsCoroutine::GetCurrent()); } + PandaEtsVM *GetPandaEtsVM() + { + return PandaEtsVM::FromExternalData(reinterpret_cast(this)); + } + napi_env GetJSEnv() const { return js_env_; @@ -161,8 +188,29 @@ public: return promise_class_; } + EtsObject *CreateJSException(EtsCoroutine *coro, JSValue *jsvalue); + + static void ThrowETSException(EtsCoroutine *coro, napi_value val); + static void ThrowETSException(EtsCoroutine *coro, const char *msg); + static void ThrowETSException(EtsCoroutine *coro, const std::string &msg) + { + ThrowETSException(coro, msg.c_str()); + } + + static void ThrowJSError(napi_env env, const std::string &msg); + static void ThrowJSException(napi_env env, napi_value val); + + void ForwardEtsException(EtsCoroutine *coro); + void ForwardJSException(EtsCoroutine *coro); + + [[noreturn]] static void Fatal(const char *msg); + [[noreturn]] static void Fatal(const std::string &msg) + { + Fatal(msg.c_str()); + } + private: - explicit GlobalCtx(EtsCoroutine *coro); + explicit InteropCtx(EtsCoroutine *coro); napi_env js_env_ {}; @@ -176,8 +224,6 @@ private: JSRefConvertCache refconvert_cache_; - void CacheClass(Class **klass, const char *descriptor); - Class *jsruntime_class_ {}; Class *jsvalue_class_ {}; Class *jsexception_class_ {}; @@ -186,10 +232,9 @@ private: Method *jsvalue_fqueue_register_ {}; - friend class JsPlugin; friend class EtsJSNapiEnvScope; }; } // namespace panda::ets::interop::js -#endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_GLOBAL_CONTEXT_H_ +#endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_INTEROP_CONTEXT_H_ diff --git a/plugins/ets/runtime/interop_js/intrinsics_api_impl.cpp b/plugins/ets/runtime/interop_js/intrinsics_api_impl.cpp index 195e5724836113071f97d7f7349f42787da3fa73..0aa243903301148229446e74913f12017b635f51 100644 --- a/plugins/ets/runtime/interop_js/intrinsics_api_impl.cpp +++ b/plugins/ets/runtime/interop_js/intrinsics_api_impl.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/js_value_call.h" #include "plugins/ets/runtime/interop_js/js_convert.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" @@ -27,14 +26,14 @@ namespace panda::ets::interop::js { static JSValue *JSRuntimeNewJSValueDouble(double v) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); return JSValue::CreateNumber(ctx, v); } static JSValue *JSRuntimeNewJSValueString(EtsString *v) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); return JSValue::CreateString(ctx, std::string(utf::Mutf8AsCString(v->GetDataMUtf8()))); } @@ -51,7 +50,7 @@ static uint8_t JSRuntimeGetValueBoolean(JSValue *ets_js_value) static EtsString *JSRuntimeGetValueString(JSValue *ets_js_value) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); @@ -59,7 +58,7 @@ static EtsString *JSRuntimeGetValueString(JSValue *ets_js_value) napi_value js_val = ets_js_value->GetNapiValue(env); auto res = JSConvertString::Unwrap(ctx, env, js_val); if (UNLIKELY(!res)) { - JsPlugin::ForwardJSException(coro); + ctx->ForwardJSException(coro); return {}; } @@ -70,14 +69,14 @@ template static typename T::cpptype JSValueNamedGetter(JSValue *ets_js_value, EtsString *ets_prop_name) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); PandaString prop_name = ets_prop_name->GetMutf8(); auto res = JSValueGetByName(ctx, ets_js_value, prop_name.c_str()); if (UNLIKELY(!res)) { - JsPlugin::ForwardJSException(coro); + ctx->ForwardJSException(coro); return {}; } return res.value(); @@ -87,32 +86,32 @@ template static void JSValueNamedSetter(JSValue *ets_js_value, EtsString *ets_prop_name, typename T::cpptype ets_prop_val) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); PandaString prop_name = ets_prop_name->GetMutf8(); bool res = JSValueSetByName(ctx, ets_js_value, prop_name.c_str(), ets_prop_val); if (UNLIKELY(!res)) { - JsPlugin::ForwardJSException(coro); + ctx->ForwardJSException(coro); } } static JSValue *JSRuntimeGetUndefined() { - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); return JSValue::CreateUndefined(ctx); } static JSValue *JSRuntimeGetNull() { - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); return JSValue::CreateNull(ctx); } static JSValue *JSRuntimeGetGlobal() { - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); auto env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); @@ -123,7 +122,7 @@ static JSValue *JSRuntimeGetGlobal() static JSValue *JSRuntimeCreateObject() { - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); auto env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); @@ -135,7 +134,7 @@ static JSValue *JSRuntimeCreateObject() static void FinalizeEtsGlobalRef([[maybe_unused]] napi_env env, void *fdata, [[maybe_unused]] void *fhint) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); ctx->Refstor()->Remove(static_cast(fdata)); } @@ -143,7 +142,7 @@ static void FinalizeEtsGlobalRef([[maybe_unused]] napi_env env, void *fdata, [[m static JSValue *JSRuntimeCreateLambdaProxy(EtsObject *callable) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); ASSERT(callable->GetClass()->GetMethod("invoke") != nullptr); @@ -190,7 +189,7 @@ static std::pair ResolveModuleName(std::stri static JSValue *JSRuntimeLoadModule(EtsString *module) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); PandaString module_name = module->GetMutf8(); diff --git a/plugins/ets/runtime/interop_js/js_convert.h b/plugins/ets/runtime/interop_js/js_convert.h index 8e2c74ae6d4fd24c9031afdd6f5d3bdc57ef675e..ad4a56dae5381fe0b47366e5a1e736dbdbf13c39 100644 --- a/plugins/ets/runtime/interop_js/js_convert.h +++ b/plugins/ets/runtime/interop_js/js_convert.h @@ -17,7 +17,6 @@ #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_JS_CONVERT_H_ #include "plugins/ets/runtime/ets_panda_file_items.h" -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" #include "plugins/ets/runtime/interop_js/js_value.h" #include "runtime/handle_scope-inl.h" @@ -60,7 +59,7 @@ void JSConvertTypeCheckFailed(const char *type_name); [[maybe_unused]] static inline napi_value Wrap([[maybe_unused]] napi_env env, \ [[maybe_unused]] cpptype ets_val); \ /* May fail */ \ - [[maybe_unused]] static inline std::optional Unwrap([[maybe_unused]] GlobalCtx *ctx, \ + [[maybe_unused]] static inline std::optional Unwrap([[maybe_unused]] InteropCtx *ctx, \ [[maybe_unused]] napi_env env, \ [[maybe_unused]] napi_value js_val); \ }; @@ -72,7 +71,7 @@ void JSConvertTypeCheckFailed(const char *type_name); // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define JSCONVERT_UNWRAP(type) \ inline std::optional JSConvert##type::Unwrap( \ - [[maybe_unused]] GlobalCtx *ctx, [[maybe_unused]] napi_env env, [[maybe_unused]] napi_value js_val) + [[maybe_unused]] InteropCtx *ctx, [[maybe_unused]] napi_env env, [[maybe_unused]] napi_value js_val) JSCONVERT_DEFINE_TYPE(U1, bool) JSCONVERT_WRAP(U1) @@ -196,7 +195,7 @@ JSCONVERT_DEFINE_TYPE(JSException, EtsObject *) // TODO(vpukhov): associate wit JSCONVERT_WRAP(JSException) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = JsPlugin::GetCurrent(coro)->GetContext(); + auto ctx = InteropCtx::Current(coro); auto klass = ets_val->GetClass(); NAPI_FATAL_IF(klass->GetRuntimeClass() != ctx->JSExceptionClass()); @@ -216,7 +215,7 @@ JSCONVERT_UNWRAP(JSException) if (UNLIKELY(value == nullptr)) { return {}; } - auto res = JsPlugin::FromContext(ctx)->CreateJSException(coro, value); + auto res = ctx->CreateJSException(coro, value); if (UNLIKELY(coro->HasPendingException())) { return {}; } @@ -234,7 +233,7 @@ JSCONVERT_WRAP(Promise) if (ets_val->GetState() != EtsPromise::STATE_PENDING) { EtsObject *value = ets_val->GetValue(coro); napi_value completion_value; - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); if (value == nullptr) { napi_get_null(env, &completion_value); } else if (value->GetClass()->IsStringClass()) { @@ -265,8 +264,8 @@ JSCONVERT_UNWRAP(Promise) #undef JSCONVERT_UNWRAP template -static ALWAYS_INLINE inline std::optional JSValueGetByName(GlobalCtx *ctx, JSValue *jsvalue, - char const *name) +static ALWAYS_INLINE inline std::optional JSValueGetByName(InteropCtx *ctx, JSValue *jsvalue, + const char *name) { auto env = ctx->GetJSEnv(); napi_value js_val = jsvalue->GetNapiValue(env); @@ -279,7 +278,7 @@ static ALWAYS_INLINE inline std::optional JSValueGetByName( } template -[[nodiscard]] static ALWAYS_INLINE inline bool JSValueSetByName(GlobalCtx *ctx, JSValue *jsvalue, char const *name, +[[nodiscard]] static ALWAYS_INLINE inline bool JSValueSetByName(InteropCtx *ctx, JSValue *jsvalue, const char *name, typename T::cpptype ets_prop_val) { auto env = ctx->GetJSEnv(); diff --git a/plugins/ets/runtime/interop_js/js_job_queue.cpp b/plugins/ets/runtime/interop_js/js_job_queue.cpp index c1f9961403d571af61226f1eab403e04359da135..84fcbc04411c2fb2e7bd637c0490f63cd63e9a23 100644 --- a/plugins/ets/runtime/interop_js/js_job_queue.cpp +++ b/plugins/ets/runtime/interop_js/js_job_queue.cpp @@ -21,7 +21,7 @@ #include "plugins/ets/runtime/types/ets_method.h" #include "plugins/ets/runtime/interop_js/js_job_queue.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" namespace panda::ets::interop::js { static napi_value ThenCallback(napi_env env, napi_callback_info info) @@ -51,7 +51,7 @@ void JsJobQueue::AddJob(EtsObject *callback) { EtsCoroutine *coro = EtsCoroutine::GetCurrent(); PandaEtsVM *vm = coro->GetPandaVM(); - napi_env env = GlobalCtx::Current(coro)->GetJSEnv(); + napi_env env = InteropCtx::Current(coro)->GetJSEnv(); napi_deferred deferred; napi_value undefined; napi_value js_promise; diff --git a/plugins/ets/runtime/interop_js/js_refconvert.h b/plugins/ets/runtime/interop_js/js_refconvert.h index 4337f2e3c4bd6b486af1122e690ad229d99b25e9..3e146e6825044d4f6e74a12b2c3af0ebe08910f7 100644 --- a/plugins/ets/runtime/interop_js/js_refconvert.h +++ b/plugins/ets/runtime/interop_js/js_refconvert.h @@ -23,19 +23,19 @@ namespace panda::ets::interop::js { -class JsPlugin; +class InteropCtx; // Conversion interface for some panda::Class objects class JSRefConvert { public: // Must not fail - napi_value Wrap(JsPlugin *ctx, EtsObject *obj) + napi_value Wrap(InteropCtx *ctx, EtsObject *obj) { return (this->*(this->wrap_))(ctx, obj); } // May fail - EtsObject *Unwrap(JsPlugin *ctx, napi_value js_value) + EtsObject *Unwrap(InteropCtx *ctx, napi_value js_value) { return (this->*(this->unwrap_))(ctx, js_value); } diff --git a/plugins/ets/runtime/interop_js/js_value.cpp b/plugins/ets/runtime/interop_js/js_value.cpp index 802fce72c544c4507ecbbe3dd39b47f71b7d4839..191b0bf931d65153a37b7c550c9dda1a5347fda0 100644 --- a/plugins/ets/runtime/interop_js/js_value.cpp +++ b/plugins/ets/runtime/interop_js/js_value.cpp @@ -15,7 +15,6 @@ #include "plugins/ets/runtime/interop_js/js_value.h" #include "plugins/ets/runtime/interop_js/js_convert.h" -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/types/ets_method.h" namespace panda::ets::interop::js { @@ -24,7 +23,7 @@ namespace panda::ets::interop::js { { ASSERT(JSValue::IsFinalizableType(js_value->GetType())); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); coro->PushLocalObject(reinterpret_cast(&js_value)); @@ -49,7 +48,7 @@ namespace panda::ets::interop::js { void JSValue::JSRuntimeFinalizationQueueCallback(EtsObject *obj) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto js_value = JSValue::FromEtsObject(obj); ASSERT(JSValue::IsFinalizableType(js_value->GetType())); @@ -67,12 +66,12 @@ void JSValue::JSRuntimeFinalizationQueueCallback(EtsObject *obj) napi_delete_reference(ctx->GetJSEnv(), js_value->GetNapiRef()); return; default: - JsPlugin::Fatal("Finalizer called for non-finalizable type: " + std::to_string(type)); + InteropCtx::Fatal("Finalizer called for non-finalizable type: " + std::to_string(type)); } UNREACHABLE(); } -JSValue *JSValue::CreateNapiValue(GlobalCtx *ctx, napi_value nvalue) +JSValue *JSValue::CreateNapiValue(InteropCtx *ctx, napi_value nvalue) { auto env = ctx->GetJSEnv(); napi_valuetype js_type = GetValueType(env, nvalue); @@ -116,7 +115,7 @@ JSValue *JSValue::CreateNapiValue(GlobalCtx *ctx, napi_value nvalue) return jsvalue; } default: { - JsPlugin::Fatal("Unsupported JSValue.Type: " + std::to_string(js_type)); + InteropCtx::Fatal("Unsupported JSValue.Type: " + std::to_string(js_type)); } } UNREACHABLE(); @@ -157,7 +156,7 @@ napi_value JSValue::GetNapiValue(napi_env env) return GetRefValue(env); } default: { - JsPlugin::Fatal("Unsupported JSValue.Type: " + std::to_string(type)); + InteropCtx::Fatal("Unsupported JSValue.Type: " + std::to_string(type)); return nullptr; } } diff --git a/plugins/ets/runtime/interop_js/js_value.h b/plugins/ets/runtime/interop_js/js_value.h index 1abe809319c3cb887d4ca622d9096ebbc3e0a573..f3865d97f52fac828c7d0f37e54fe0d9d1b317ae 100644 --- a/plugins/ets/runtime/interop_js/js_value.h +++ b/plugins/ets/runtime/interop_js/js_value.h @@ -18,7 +18,7 @@ #include "plugins/ets/runtime/ets_coroutine.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" #include "plugins/ets/runtime/types/ets_object.h" #include "runtime/include/coretypes/class.h" #include @@ -35,7 +35,7 @@ class JSValue : private EtsObject { public: static JSValue *FromEtsObject(EtsObject *ets_object) { - ASSERT(ets_object->GetClass() == EtsClass::FromRuntimeClass(GlobalCtx::Current()->JSValueClass())); + ASSERT(ets_object->GetClass() == EtsClass::FromRuntimeClass(InteropCtx::Current()->JSValueClass())); return static_cast(ets_object); } @@ -64,42 +64,42 @@ public: return bit_cast(type_); } - static JSValue *CreateNapiValue(GlobalCtx *ctx, napi_value nvalue); + static JSValue *CreateNapiValue(InteropCtx *ctx, napi_value nvalue); - static JSValue *CreateUndefined(GlobalCtx *ctx) + static JSValue *CreateUndefined(InteropCtx *ctx) { return AllocUndefined(ctx); } - static JSValue *CreateNull(GlobalCtx *ctx) + static JSValue *CreateNull(InteropCtx *ctx) { auto jsvalue = AllocUndefined(ctx); jsvalue->SetNull(); return jsvalue; } - static JSValue *CreateBoolean(GlobalCtx *ctx, bool value) + static JSValue *CreateBoolean(InteropCtx *ctx, bool value) { auto jsvalue = AllocUndefined(ctx); jsvalue->SetBoolean(value); return jsvalue; } - static JSValue *CreateNumber(GlobalCtx *ctx, double value) + static JSValue *CreateNumber(InteropCtx *ctx, double value) { auto jsvalue = AllocUndefined(ctx); jsvalue->SetNumber(value); return jsvalue; } - static JSValue *CreateString(GlobalCtx *ctx, std::string &&value) + static JSValue *CreateString(InteropCtx *ctx, std::string &&value) { auto jsvalue = AllocUndefined(ctx); jsvalue->SetString(ctx->GetStringStor()->Get(std::move(value))); return JSValue::AttachFinalizer(EtsCoroutine::GetCurrent(), jsvalue); } - static JSValue *CreateRefValue(GlobalCtx *ctx, napi_value value, napi_valuetype type) + static JSValue *CreateRefValue(InteropCtx *ctx, napi_value value, napi_valuetype type) { auto jsvalue = AllocUndefined(ctx); jsvalue->SetRefValue(ctx->GetJSEnv(), value, type); @@ -181,7 +181,7 @@ private: return val; } - static JSValue *AllocUndefined(GlobalCtx *ctx) + static JSValue *AllocUndefined(InteropCtx *ctx) { EtsClass *ets_class = EtsClass::FromRuntimeClass(ctx->JSValueClass()); JSValue *js_value; diff --git a/plugins/ets/runtime/interop_js/js_value_call.cpp b/plugins/ets/runtime/interop_js/js_value_call.cpp index 98eebbe3ab5793a5d79eb4070f4828ff49832626..0d8509d3b54a3c93c61258c54f39fbdb2d8d36ac 100644 --- a/plugins/ets/runtime/interop_js/js_value_call.cpp +++ b/plugins/ets/runtime/interop_js/js_value_call.cpp @@ -15,7 +15,6 @@ #include "plugins/ets/runtime/types/ets_string.h" #include "plugins/ets/runtime/types/ets_method.h" -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/js_value_call.h" #include "plugins/ets/runtime/interop_js/napi_env_scope.h" #include "plugins/ets/runtime/interop_js/js_convert.h" @@ -27,7 +26,7 @@ namespace panda::ets::interop::js { template -[[nodiscard]] static ALWAYS_INLINE inline bool ConvertNapiVal(GlobalCtx *ctx, FClsResolv &resolve_ref_cls, +[[nodiscard]] static ALWAYS_INLINE inline bool ConvertNapiVal(InteropCtx *ctx, FClsResolv &resolve_ref_cls, FStorePrim &store_prim, FStoreRef &store_ref, panda_file::Type type, napi_value js_val) { @@ -91,7 +90,7 @@ template if (UNLIKELY(refconv == nullptr)) { NapiFatal(std::string("ConvertNapiVal: unknown class: ") + utf::Mutf8AsCString(klass->GetDescriptor())); } - ObjectHeader *res = refconv->Unwrap(JsPlugin::FromContext(ctx), js_val)->GetCoreType(); + ObjectHeader *res = refconv->Unwrap(ctx, js_val)->GetCoreType(); if (UNLIKELY(res == nullptr)) { return false; } @@ -107,7 +106,7 @@ template } template -static ALWAYS_INLINE inline void ConvertEtsVal(GlobalCtx *ctx, [[maybe_unused]] FClsResolv &resolve_ref_cls, +static ALWAYS_INLINE inline void ConvertEtsVal(InteropCtx *ctx, [[maybe_unused]] FClsResolv &resolve_ref_cls, FStore &store_res, panda_file::Type type, FRead &read_val) { auto env = ctx->GetJSEnv(); @@ -170,7 +169,7 @@ static ALWAYS_INLINE inline void ConvertEtsVal(GlobalCtx *ctx, [[maybe_unused]] if (UNLIKELY(refconv == nullptr)) { NapiFatal(std::string("ConvertEtsVal: unknown class: ") + utf::Mutf8AsCString(klass->GetDescriptor())); } - store_res(refconv->Wrap(JsPlugin::FromContext(ctx), EtsObject::FromCoreType(ref))); + store_res(refconv->Wrap(ctx, EtsObject::FromCoreType(ref))); return; } default: { @@ -183,7 +182,7 @@ static ALWAYS_INLINE inline void ConvertEtsVal(GlobalCtx *ctx, [[maybe_unused]] using ArgValueBox = std::variant; template -static ALWAYS_INLINE inline napi_value EtsCallImpl(EtsCoroutine *coro, GlobalCtx *ctx, Method *method, +static ALWAYS_INLINE inline napi_value EtsCallImpl(EtsCoroutine *coro, InteropCtx *ctx, Method *method, Span jsargv, mem::Reference *ets_fnobj_ref) { ScopedManagedCodeThread managed_scope(coro); @@ -224,8 +223,7 @@ static ALWAYS_INLINE inline napi_value EtsCallImpl(EtsCoroutine *coro, GlobalCtx ets_boxed_args[arg_idx] = reinterpret_cast(addr); }; if (UNLIKELY(!ConvertNapiVal(ctx, cls_resolver, store_prim, store_ref, type, js_val))) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("EtsCall: exit with pending exception"); + INTEROP_LOG(DEBUG) << "EtsCall: exit with pending exception"; return nullptr; } } @@ -250,9 +248,8 @@ static ALWAYS_INLINE inline napi_value EtsCallImpl(EtsCoroutine *coro, GlobalCtx Value ets_res = method->Invoke(coro, ets_args.data()); if (UNLIKELY(coro->HasPendingException())) { - JsPlugin::ForwardEtsException(coro); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("EtsCall: exit with pending exception"); + ctx->ForwardEtsException(coro); + INTEROP_LOG(DEBUG) << "EtsCall: exit with pending exception"; return nullptr; } @@ -270,51 +267,47 @@ static ALWAYS_INLINE inline napi_value EtsCallImpl(EtsCoroutine *coro, GlobalCtx napi_value CallEtsFunctionImpl(napi_env env, Span jsargv) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); [[maybe_unused]] EtsJSNapiEnvScope scope(ctx, env); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("CallEtsFunction: enter"); + INTEROP_LOG(DEBUG) << "CallEtsFunction: enter"; // NOLINTNEXTLINE(readability-container-size-empty) if (UNLIKELY(jsargv.size() < 1)) { - JsPlugin::ThrowJSError(env, "CallEtsFunction: method name required"); + InteropCtx::ThrowJSError(env, "CallEtsFunction: method name required"); return nullptr; } if (UNLIKELY(GetValueType(env, jsargv[0]) != napi_string)) { - JsPlugin::ThrowJSError(env, "CallEtsFunction: method name is not a string"); + InteropCtx::ThrowJSError(env, "CallEtsFunction: method name is not a string"); return nullptr; } auto method_name = std::string("ETSGLOBAL::") + MakeString(env, jsargv[0]); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG_A("CallEtsFunction: method name: %s", method_name.c_str()); + INTEROP_LOG(DEBUG) << "CallEtsFunction: method name: " << method_name; auto method_res = Runtime::GetCurrent()->ResolveEntryPoint(method_name); if (UNLIKELY(!method_res)) { - JsPlugin::ThrowJSError(env, "CallEtsFunction: can't resolve method " + method_name); + InteropCtx::ThrowJSError(env, "CallEtsFunction: can't resolve method " + method_name); return nullptr; } auto method = method_res.Value(); auto const num_args = method->GetNumArgs(); if (UNLIKELY(num_args != jsargv.size() - 1)) { - JsPlugin::ThrowJSError(env, std::string("CallEtsFunction: wrong argc")); + InteropCtx::ThrowJSError(env, std::string("CallEtsFunction: wrong argc")); return nullptr; } auto js_ret = EtsCallImpl(coro, ctx, method, jsargv.SubSpan(1), nullptr); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("CallEtsFunction: exit"); + INTEROP_LOG(DEBUG) << "CallEtsFunction: exit"; return js_ret; } napi_value EtsLambdaProxyInvoke(napi_env env, napi_callback_info cbinfo) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); [[maybe_unused]] EtsJSNapiEnvScope envscope(ctx, env); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("EtsProxyInvoke: enter"); + INTEROP_LOG(DEBUG) << "EtsProxyInvoke: enter"; size_t argc; napi_value athis; @@ -330,21 +323,20 @@ napi_value EtsLambdaProxyInvoke(napi_env env, napi_callback_info cbinfo) ASSERT(method != nullptr); if (UNLIKELY(argc != method->GetNumArgs() - 1)) { - JsPlugin::ThrowJSError(env, std::string("EtsProxyInvoke: wrong argc")); + InteropCtx::ThrowJSError(env, std::string("EtsProxyInvoke: wrong argc")); return nullptr; } auto js_args_span = Span(js_args.data(), js_args.size()); auto js_ret = EtsCallImpl(coro, ctx, method->GetPandaMethod(), js_args_span, ets_ref); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("EtsProxyInvoke: exit"); + INTEROP_LOG(DEBUG) << "EtsProxyInvoke: exit"; return js_ret; } template static void WalkQualifiedName(std::string_view name, F const &f) { - for (char const *p = name.data(); *p == DELIM;) { + for (const char *p = name.data(); *p == DELIM;) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) auto e = ++p; while (*e != '\0' && *e != DELIM) { @@ -361,10 +353,9 @@ static inline std::pair ResolveQualifiedJSCall(napi_env napi_value js_this {}; auto qname = std::string_view(utf::Mutf8AsCString(qname_str->GetDataMUtf8()), qname_str->GetMUtf8Length()); - auto resolve_name = [&](std::string const &name) { + auto resolve_name = [&](const std::string &name) { js_this = js_val; - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG_A("JSValueJSCall: resolve name: %s", name.c_str()); + INTEROP_LOG(DEBUG) << "JSValueJSCall: resolve name: " << name; napi_status rc = napi_get_named_property(env, js_val, name.c_str(), &js_val); if (UNLIKELY(rc != napi_ok)) { NAPI_FATAL_IF(rc != napi_generic_failure); @@ -380,10 +371,9 @@ static inline std::pair ResolveQualifiedJSCall(napi_env template static ALWAYS_INLINE inline uint64_t JSValueJSCallImpl(Method *method, uint8_t *args, uint8_t *in_stack_args) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("JSValueJSCall: enter"); + INTEROP_LOG(DEBUG) << "JSValueJSCall: enter"; auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto class_linker = Runtime::GetCurrent()->GetClassLinker(); auto pf = method->GetPandaFile(); @@ -447,9 +437,8 @@ static ALWAYS_INLINE inline uint64_t JSValueJSCallImpl(Method *method, uint8_t * if (UNLIKELY(js_status != napi_ok)) { NAPI_FATAL_IF(js_status != napi_pending_exception); - JsPlugin::ForwardJSException(coro); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("JSValueJSCall: exit with pending exception"); + ctx->ForwardJSException(coro); + INTEROP_LOG(DEBUG) << "JSValueJSCall: exit with pending exception"; return 0; } @@ -468,15 +457,13 @@ static ALWAYS_INLINE inline uint64_t JSValueJSCallImpl(Method *method, uint8_t * auto store_prim = [&](uint64_t val) { ets_ret = Value(val); }; auto store_ref = [&](ObjectHeader *obj) { ets_ret = Value(obj); }; if (UNLIKELY(!ConvertNapiVal(ctx, cls_resolver, store_prim, store_ref, type, js_ret))) { - JsPlugin::ForwardJSException(coro); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("JSValueJSCall: exit with pending exception"); + ctx->ForwardJSException(coro); + INTEROP_LOG(DEBUG) << "JSValueJSCall: exit with pending exception"; return 0; } } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG("JSValueJSCall: exit"); + INTEROP_LOG(DEBUG) << "JSValueJSCall: exit"; return static_cast(ets_ret.GetAsLong()); } @@ -503,7 +490,7 @@ template static void InitJSCallSignatures(coretypes::String *cls_str) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto class_linker = Runtime::GetCurrent()->GetClassLinker(); const char *class_descriptor = utf::Mutf8AsCString(cls_str->GetDataMUtf8()); @@ -511,8 +498,7 @@ static void InitJSCallSignatures(coretypes::String *cls_str) NAPI_FATAL_IF(ets_class == nullptr); auto klass = ets_class->GetRuntimeClass(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_DEBUG_A("Bind bridge call methods for %s", klass->GetDescriptor()); + INTEROP_LOG(DEBUG) << "Bind bridge call methods for " << utf::Mutf8AsCString(klass->GetDescriptor()); for (auto &method : klass->GetMethods()) { if (method.IsConstructor()) { diff --git a/plugins/ets/runtime/interop_js/napi_env_scope.h b/plugins/ets/runtime/interop_js/napi_env_scope.h index 8cb80d5eaab2a51029921e167ef3e6759d81f762..1d60e3447daad55a784207bbd5fba2ddf7d2366b 100644 --- a/plugins/ets/runtime/interop_js/napi_env_scope.h +++ b/plugins/ets/runtime/interop_js/napi_env_scope.h @@ -17,14 +17,14 @@ #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_NAPI_ENV_SCOPE_H_ #include "libpandabase/macros.h" -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" #include namespace panda::ets::interop::js { class EtsJSNapiEnvScope { public: - explicit EtsJSNapiEnvScope(GlobalCtx *ctx, napi_env new_env) : ctx_(ctx) + explicit EtsJSNapiEnvScope(InteropCtx *ctx, napi_env new_env) : ctx_(ctx) { saved_ = ctx_->GetJSEnv(); ctx_->SetJSEnv(new_env); @@ -39,7 +39,7 @@ private: NO_COPY_SEMANTIC(EtsJSNapiEnvScope); NO_MOVE_SEMANTIC(EtsJSNapiEnvScope); - GlobalCtx *ctx_ {}; + InteropCtx *ctx_ {}; napi_env saved_ {}; }; diff --git a/plugins/ets/runtime/interop_js/pending_promise_listener.cpp b/plugins/ets/runtime/interop_js/pending_promise_listener.cpp index 49d8079eed3e4ad6c3528363185675af9594375c..2f57299f3f7ed9d07516096b638244549357454b 100644 --- a/plugins/ets/runtime/interop_js/pending_promise_listener.cpp +++ b/plugins/ets/runtime/interop_js/pending_promise_listener.cpp @@ -15,7 +15,7 @@ #include "plugins/ets/runtime/ets_coroutine.h" #include "plugins/ets/runtime/interop_js/js_convert.h" -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" #include "plugins/ets/runtime/interop_js/pending_promise_listener.h" namespace panda::ets::interop::js { @@ -31,7 +31,7 @@ void PendingPromiseListener::OnPromiseStateChanged(VMHandle &promise { ASSERT(promise->GetState() != EtsPromise::STATE_PENDING); auto *coro = EtsCoroutine::GetCurrent(); - auto *ctx = GlobalCtx::Current(coro); + auto *ctx = InteropCtx::Current(coro); EtsObject *value = promise->GetValue(coro); napi_env env = ctx->GetJSEnv(); napi_value completion_value; diff --git a/plugins/ets/runtime/interop_js/ts2ets_common.cpp b/plugins/ets/runtime/interop_js/ts2ets_common.cpp index bb68eeacdf4ae44509ed479023bb49626ee8f2e2..a4bcd4a3e1bae563950ede642b04b66ec1fb1c09 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_common.cpp +++ b/plugins/ets/runtime/interop_js/ts2ets_common.cpp @@ -13,27 +13,26 @@ * limitations under the License. */ -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" namespace panda::ets::interop::js { -[[noreturn]] void NapiFatal(char const *message) +[[noreturn]] void NapiFatal(const char *message) { - JsPlugin::Fatal(message); + InteropCtx::Fatal(message); UNREACHABLE(); } -[[noreturn]] void NapiFatal(std::string const &message) +[[noreturn]] void NapiFatal(const std::string &message) { - JsPlugin::Fatal(message.c_str()); + InteropCtx::Fatal(message.c_str()); UNREACHABLE(); } -void InteropTrace(char const *func, char const *file, int line) +void InteropTrace(const char *func, const char *file, int line) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - INTEROP_LOG_INFO_A("interop::js: %s %s:%d", func, file, line); + INTEROP_LOG(DEBUG) << "trace: " << func << file << line; } std::string MakeString(napi_env env, napi_value value) @@ -72,7 +71,7 @@ namespace panda::ets::ts2ets::GlobalCtx { // NOLINT(readability-identifier-nami void Init() { - interop::js::JsPlugin::Init(EtsCoroutine::GetCurrent()); + interop::js::InteropCtx::Init(EtsCoroutine::GetCurrent()); } } // namespace panda::ets::ts2ets::GlobalCtx diff --git a/plugins/ets/runtime/interop_js/ts2ets_common.h b/plugins/ets/runtime/interop_js/ts2ets_common.h index e23aaae6a13afe27b6678511d48dc4d2deb59500..4988e8ea479c1a29a44073ca63c3dfbe3d01c719 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_common.h +++ b/plugins/ets/runtime/interop_js/ts2ets_common.h @@ -21,6 +21,9 @@ #include +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define INTEROP_LOG(level) LOG(level, ETS_INTEROP_JS) + #ifdef PANDA_TARGET_OHOS #include @@ -78,8 +81,8 @@ inline std::string EtsLogMakeString(const char *fmt, ...) namespace panda::ets::interop::js { -[[noreturn]] void NapiFatal(char const *message); -[[noreturn]] void NapiFatal(std::string const &message); +[[noreturn]] void NapiFatal(const char *message); +[[noreturn]] void NapiFatal(const std::string &message); // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define NAPI_FATAL_IF(expr) \ @@ -107,7 +110,7 @@ namespace panda::ets::interop::js { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TYPEVIS_NAPI_CHECK(expr) TYPEVIS_CHECK_ERROR((expr) == napi_ok, #expr) -void InteropTrace(char const *func, char const *file, int line); +void InteropTrace(const char *func, const char *file, int line); #ifndef NDEBUG // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/plugins/ets/runtime/interop_js/ts2ets_copy.cpp b/plugins/ets/runtime/interop_js/ts2ets_copy.cpp index 15cbc910a7daf949e010e8093702c05ac639fa9b..2ec9b25ec0b28837c192ceee81870818e30f7b99 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_copy.cpp +++ b/plugins/ets/runtime/interop_js/ts2ets_copy.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" #include "plugins/ets/runtime/interop_js/js_value.h" #include "plugins/ets/runtime/interop_js/napi_env_scope.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" @@ -151,7 +150,7 @@ public: void VisitFieldReference(const panda::Field *field, panda::Class *klass) override { - auto fname = reinterpret_cast(field->GetName().data); + auto fname = reinterpret_cast(field->GetName().data); napi_value sub_val; TYPEVIS_NAPI_CHECK(napi_get_named_property(env_, js_value_, fname, &sub_val)); auto sub_vis = JsToEtsConvertor(env_, sub_val, owner_, field->GetOffset()); @@ -161,7 +160,7 @@ public: void VisitFieldPrimitive(const panda::Field *field, panda::panda_file::Type type) override { - auto fname = reinterpret_cast(field->GetName().data); + auto fname = reinterpret_cast(field->GetName().data); napi_value sub_val; TYPEVIS_NAPI_CHECK(napi_get_named_property(env_, js_value_, fname, &sub_val)); auto sub_vis = JsToEtsConvertor(env_, sub_val, owner_, field->GetOffset()); @@ -171,7 +170,7 @@ public: void VisitObject(panda::Class *klass) override { - ASSERT(klass != GlobalCtx::Current()->JSValueClass()); + ASSERT(klass != InteropCtx::Current()->JSValueClass()); TYPEVIS_CHECK_ERROR(GetValueType(env_, js_value_) == napi_object, "object expected"); auto coro = EtsCoroutine::GetCurrent(); @@ -258,7 +257,7 @@ public: void VisitString([[maybe_unused]] panda::Class *klass) override { auto ets_str = static_cast(loc_.LoadReference()); - TYPEVIS_NAPI_CHECK(napi_create_string_utf8(env_, reinterpret_cast(ets_str->GetDataMUtf8()), + TYPEVIS_NAPI_CHECK(napi_create_string_utf8(env_, reinterpret_cast(ets_str->GetDataMUtf8()), ets_str->GetMUtf8Length() - 1, &js_value_)); } @@ -289,7 +288,7 @@ public: auto sub_vis = EtsToJsConvertor(env_, owner_, field->GetOffset()); sub_vis.VisitReference(klass); TYPEVIS_CHECK_FORWARD_ERROR(sub_vis.Error()); - auto fname = reinterpret_cast(field->GetName().data); + auto fname = reinterpret_cast(field->GetName().data); napi_set_named_property(env_, js_value_, fname, sub_vis.js_value_); } @@ -298,15 +297,15 @@ public: auto sub_vis = EtsToJsConvertor(env_, owner_, field->GetOffset()); sub_vis.VisitPrimitive(type); TYPEVIS_CHECK_FORWARD_ERROR(sub_vis.Error()); - auto fname = reinterpret_cast(field->GetName().data); + auto fname = reinterpret_cast(field->GetName().data); napi_set_named_property(env_, js_value_, fname, sub_vis.js_value_); } void VisitObject(panda::Class *klass) override { - ASSERT(klass != GlobalCtx::Current()->JSValueClass()); + ASSERT(klass != InteropCtx::Current()->JSValueClass()); auto coro = EtsCoroutine::GetCurrent(); - if (klass == GlobalCtx::Current(coro)->GetPromiseClass()) { + if (klass == InteropCtx::Current(coro)->GetPromiseClass()) { VisitPromise(); return; } @@ -622,19 +621,19 @@ private: napi_value InvokeEtsMethodImpl(napi_env env, napi_value *jsargv, uint32_t jsargc, bool do_clscheck) { auto coro = EtsCoroutine::GetCurrent(); - [[maybe_unused]] EtsJSNapiEnvScope scope(GlobalCtx::Current(coro), env); + [[maybe_unused]] EtsJSNapiEnvScope scope(InteropCtx::Current(coro), env); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) INTEROP_LOG_INFO("InvokeEtsMethod: enter"); if (jsargc < 1) { - JsPlugin::ThrowJSError(env, "InvokeEtsMethod: method name required"); + InteropCtx::ThrowJSError(env, "InvokeEtsMethod: method name required"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (GetValueType(env, jsargv[0]) != napi_string) { - JsPlugin::ThrowJSError(env, "InvokeEtsMethod: method name is not a string"); + InteropCtx::ThrowJSError(env, "InvokeEtsMethod: method name is not a string"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -644,21 +643,21 @@ napi_value InvokeEtsMethodImpl(napi_env env, napi_value *jsargv, uint32_t jsargc auto method_res = panda::Runtime::GetCurrent()->ResolveEntryPoint(method_name); if (!method_res) { - JsPlugin::ThrowJSError(env, "InvokeEtsMethod: can't resolve method " + method_name); + InteropCtx::ThrowJSError(env, "InvokeEtsMethod: can't resolve method " + method_name); return nullptr; } auto method = method_res.Value(); auto num_args = method->GetNumArgs(); if (num_args != jsargc - 1) { - JsPlugin::ThrowJSError(env, std::string("InvokeEtsMethod: wrong argc")); + InteropCtx::ThrowJSError(env, std::string("InvokeEtsMethod: wrong argc")); return nullptr; } ScopedManagedCodeThread managed_scope(coro); if (do_clscheck && !EtsClassesRecursionChecker::CheckClasses(method)) { - JsPlugin::ThrowJSError(env, "InvokeEtsMethod: loops possible in args objects"); + InteropCtx::ThrowJSError(env, "InvokeEtsMethod: loops possible in args objects"); return nullptr; } @@ -672,7 +671,7 @@ napi_value InvokeEtsMethodImpl(napi_env env, napi_value *jsargv, uint32_t jsargc auto begin = std::chrono::steady_clock::now(); js2ets.Process(); if (js2ets.Error()) { - JsPlugin::ThrowJSError(env, std::string("InvokeEtsMethod: js2ets error: ") + js2ets.Error().value()); + InteropCtx::ThrowJSError(env, std::string("InvokeEtsMethod: js2ets error: ") + js2ets.Error().value()); return nullptr; } args = js2ets.GetResult(); @@ -696,12 +695,12 @@ napi_value InvokeEtsMethodImpl(napi_env env, napi_value *jsargv, uint32_t jsargc EtsToJsConvertor ets2js(env, &data); ets2js.VisitClass(klass); if (ets2js.Error()) { - JsPlugin::ThrowJSError(env, - std::string("InvokeEtsMethod: ets2js error while converting pending exception: " + - ets2js.Error().value())); + InteropCtx::ThrowJSError(env, + std::string("InvokeEtsMethod: ets2js error while converting pending exception: " + + ets2js.Error().value())); return nullptr; } - JsPlugin::ThrowJSException(env, ets2js.GetResult()); + InteropCtx::ThrowJSException(env, ets2js.GetResult()); return nullptr; } @@ -714,7 +713,7 @@ napi_value InvokeEtsMethodImpl(napi_env env, napi_value *jsargv, uint32_t jsargc EtsToJsRetConvertor ets2js(method, env, ets_res); ets2js.Process(); if (ets2js.Error()) { - JsPlugin::ThrowJSError(env, std::string("InvokeEtsMethod: ets2js error: ") + ets2js.Error().value()); + InteropCtx::ThrowJSError(env, std::string("InvokeEtsMethod: ets2js error: ") + ets2js.Error().value()); return nullptr; } js_res = ets2js.GetResult(); diff --git a/plugins/ets/runtime/interop_js/ts2ets_jsvalue.h b/plugins/ets/runtime/interop_js/ts2ets_jsvalue.h index bf843eb44f95c35d74cb083c5a9fba000a7a936c..ede5ce3258975d7000409bfa696be8a8851628ad 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_jsvalue.h +++ b/plugins/ets/runtime/interop_js/ts2ets_jsvalue.h @@ -18,7 +18,7 @@ #include "plugins/ets/runtime/interop_js/ts2ets_copy.h" -// This entire namespace is used for compatibility, use JSPlugin for new code instead +// This entire namespace is used for compatibility, use interop_context.h for new code instead namespace panda::ets::ts2ets { inline void InitJSValueExports() diff --git a/plugins/ets/runtime/interop_js/ts2ets_proxy.cpp b/plugins/ets/runtime/interop_js/ts2ets_proxy.cpp index 8f87ca1937e533a347decc1d74e55de73e3da680..86d110d14a6a0eaae337dbdbc1db309b6c35be48 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_proxy.cpp +++ b/plugins/ets/runtime/interop_js/ts2ets_proxy.cpp @@ -13,8 +13,7 @@ * limitations under the License. */ -#include "plugins/ets/runtime/interop_js/ets_vm_plugin.h" -#include "plugins/ets/runtime/interop_js/global_context.h" +#include "plugins/ets/runtime/interop_js/interop_context.h" #include "plugins/ets/runtime/interop_js/napi_env_scope.h" #include "plugins/ets/runtime/interop_js/ts2ets_common.h" #include "plugins/ets/runtime/interop_js/ets_type_visitor-inl.h" @@ -297,7 +296,7 @@ static inline WrapperRef *WrapperObjUnwrap(napi_env env, napi_value jsval, Wrapp auto wtag = MakeWrapperNapiTag(wclass); NAPI_CHECK_FATAL(napi_check_object_type_tag(env, jsval, &wtag, &match)); if (UNLIKELY(!match)) { - JsPlugin::ThrowJSError(env, "unwrap reftype mismatch, expected " + wclass->ets_klass->GetName()); + InteropCtx::ThrowJSError(env, "unwrap reftype mismatch, expected " + wclass->ets_klass->GetName()); return nullptr; } void *data; @@ -356,7 +355,7 @@ static bool WrapperFieldGetCheck(napi_env env, napi_callback_info cinfo, Wrapper void *data; NAPI_CHECK_FATAL(napi_get_cb_info(env, cinfo, &argc, nullptr, &athis, &data)); if (UNLIKELY(argc != 0)) { - JsPlugin::ThrowJSError(env, "getter called in wrong context"); + InteropCtx::ThrowJSError(env, "getter called in wrong context"); return false; } @@ -378,7 +377,7 @@ static bool WrapperFieldSetCheck(napi_env env, napi_callback_info cinfo, Wrapper void *data; NAPI_CHECK_FATAL(napi_get_cb_info(env, cinfo, &argc, &js_val, &athis, &data)); if (UNLIKELY(argc != 1)) { - JsPlugin::ThrowJSError(env, "setter called in wrong context"); + InteropCtx::ThrowJSError(env, "setter called in wrong context"); return false; } @@ -482,22 +481,22 @@ WrapperClass *WrapperClassLinkResolve(napi_env env, WrapperClassLink &link) // accessors for primitive fields // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define TS2ETS_WRAPPER_FIELD_ACCESSOR_PRIMITIVE(type, cpptype) \ - TS2ETS_WRAPPER_FIELD_GET(type) \ - { \ - auto ets_obj = GlobalCtx::Current()->Refstor()->Get(wref->ets_ref); \ - auto ets_val = ets_obj->GetFieldPrimitive(wfield->ets_offs); \ - return WrapperValueWrapImpl##type(env, nullptr, ets_val); \ - } \ - TS2ETS_WRAPPER_FIELD_SET(type) \ - { \ - cpptype ets_val; \ - if (UNLIKELY(!WrapperValueUnwrapImpl##type(env, nullptr, js_val, ets_val))) { \ - JsPlugin::ThrowJSError(env, "unwrap type mismatch, " #type " expected"); \ - return; \ - } \ - auto ets_obj = GlobalCtx::Current()->Refstor()->Get(wref->ets_ref); \ - ets_obj->SetFieldPrimitive(wfield->ets_offs, ets_val); \ +#define TS2ETS_WRAPPER_FIELD_ACCESSOR_PRIMITIVE(type, cpptype) \ + TS2ETS_WRAPPER_FIELD_GET(type) \ + { \ + auto ets_obj = InteropCtx::Current()->Refstor()->Get(wref->ets_ref); \ + auto ets_val = ets_obj->GetFieldPrimitive(wfield->ets_offs); \ + return WrapperValueWrapImpl##type(env, nullptr, ets_val); \ + } \ + TS2ETS_WRAPPER_FIELD_SET(type) \ + { \ + cpptype ets_val; \ + if (UNLIKELY(!WrapperValueUnwrapImpl##type(env, nullptr, js_val, ets_val))) { \ + InteropCtx::ThrowJSError(env, "unwrap type mismatch, " #type " expected"); \ + return; \ + } \ + auto ets_obj = InteropCtx::Current()->Refstor()->Get(wref->ets_ref); \ + ets_obj->SetFieldPrimitive(wfield->ets_offs, ets_val); \ } TS2ETS_WRAPPER_WRAP(VOID, int8_t) @@ -523,7 +522,7 @@ TS2ETS_WRAPPER_WRAP(F32, float) TS2ETS_WRAPPER_UNWRAP(F32, float) { if (UNLIKELY(GetValueType(env, js_val) != napi_number)) { - JsPlugin::ThrowJSError(env, "unwrap type mismatch, number expected"); + InteropCtx::ThrowJSError(env, "unwrap type mismatch, number expected"); return false; } double val; @@ -544,7 +543,7 @@ TS2ETS_WRAPPER_WRAP(I32, int32_t) TS2ETS_WRAPPER_UNWRAP(I32, int32_t) { if (UNLIKELY(GetValueType(env, js_val) != napi_number)) { - JsPlugin::ThrowJSError(env, "unwrap type mismatch, number expected"); + InteropCtx::ThrowJSError(env, "unwrap type mismatch, number expected"); return false; } int32_t val; @@ -565,7 +564,7 @@ TS2ETS_WRAPPER_WRAP(I64, int64_t) TS2ETS_WRAPPER_UNWRAP(I64, int64_t) { if (UNLIKELY(GetValueType(env, js_val) != napi_number)) { - JsPlugin::ThrowJSError(env, "unwrap type mismatch, number expected"); + InteropCtx::ThrowJSError(env, "unwrap type mismatch, number expected"); return false; } int64_t val; @@ -606,7 +605,7 @@ TS2ETS_WRAPPER_UNWRAP(OBJ, panda::ObjectHeader *) if (UNLIKELY(wref == nullptr)) { return false; } - ets_val = GlobalCtx::Current()->Refstor()->Get(wref->ets_ref); + ets_val = InteropCtx::Current()->Refstor()->Get(wref->ets_ref); return true; } @@ -618,7 +617,7 @@ TS2ETS_WRAPPER_FIELD_GET(OBJ) if (UNLIKELY(wclass_field == nullptr)) { return nullptr; } - auto ets_obj = GlobalCtx::Current()->Refstor()->Get(wref->ets_ref); + auto ets_obj = InteropCtx::Current()->Refstor()->Get(wref->ets_ref); auto ets_val = ets_obj->GetFieldObject(wfield->ets_offs); if (UNLIKELY(ets_val == nullptr)) { @@ -641,7 +640,7 @@ TS2ETS_WRAPPER_FIELD_SET(OBJ) return; } - auto ets_obj = GlobalCtx::Current()->Refstor()->Get(wref->ets_ref); + auto ets_obj = InteropCtx::Current()->Refstor()->Get(wref->ets_ref); if (ets_val == nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) PROXY_DLOG_A("TS2ETS_WRAPPER_FIELD_SET: null to wref=%p offs=%u", (void *)wref, wfield->ets_offs); @@ -656,7 +655,7 @@ static void WrapperFinalize([[maybe_unused]] napi_env env, void *data, [[maybe_u auto coro = EtsCoroutine::GetCurrent(); ScopedManagedCodeThreadSwitch managed_scope(coro); auto wref = reinterpret_cast(data); - GlobalCtx::Current(coro)->Refstor()->Remove(wref->ets_ref); + InteropCtx::Current(coro)->Refstor()->Remove(wref->ets_ref); WrapperRefCache::Free(wref); } @@ -665,7 +664,7 @@ static void WrapperFinalizeShareable([[maybe_unused]] napi_env env, void *data, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) PROXY_DLOG_A("WrapperFinalizeShareable: %p", (void *)data); auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); ScopedManagedCodeThreadSwitch managed_scope(coro); auto wref = reinterpret_cast(data); WrapperRef::UnlinkShareable(ctx->Refstor()->Get(wref->ets_ref)); @@ -691,7 +690,7 @@ static napi_value WrapperCtor(napi_env env, napi_callback_info cinfo) auto wclass = reinterpret_cast(data); panda::ObjectHeader *ets_obj; WrapperRef *wref = WrapperRefCache::Alloc(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); if (wclass->pending_ets_obj != nullptr) { // nonexisting ref for existing ets obj @@ -764,7 +763,7 @@ private: // TODO(vpukhov): napi_static fields are added to instance static constexpr auto STATIC_FIELD_ATTR = static_cast( napi_static | napi_writable | napi_enumerable); // NOLINT(hicpp-signed-bitwise) - static constexpr char const *INIT_NAME = ""; + static constexpr const char *INIT_NAME = ""; WrapperClass *ProcessInternal() { @@ -842,7 +841,7 @@ private: (void *)wclass_->wfields.back().wclass_field.GetUnresolved()); { napi_property_descriptor prop {}; - prop.utf8name = reinterpret_cast(ets_field_->GetName().data); + prop.utf8name = reinterpret_cast(ets_field_->GetName().data); prop.getter = getter; prop.setter = setter; prop.attributes = FIELD_ATTR; @@ -854,7 +853,7 @@ private: void AddMethod(panda::Method *method) { - auto name = reinterpret_cast(method->GetName().data); + auto name = reinterpret_cast(method->GetName().data); napi_callback impl; if (method->IsStatic()) { @@ -889,7 +888,7 @@ private: auto it = names.insert(name); NAPI_FATAL_IF(!it.second); // no overloading AddMethod(&method); - if (strcmp(reinterpret_cast(name), INIT_NAME) == 0) { + if (strcmp(reinterpret_cast(name), INIT_NAME) == 0) { wclass_->ets_init = WrapperMethodLink(&method); // lazy } } @@ -988,7 +987,7 @@ static WrapperClass *GetWrapperClass(napi_env env, panda::Class *klass) WrapperClassCreator creator(env, klass); wclass = creator.Process(); if (UNLIKELY(wclass == nullptr)) { - JsPlugin::ThrowJSError(env, "can't create proxy wrapper of class " + klass->GetName()); + InteropCtx::ThrowJSError(env, "can't create proxy wrapper of class " + klass->GetName()); return nullptr; } return wclass; @@ -1020,7 +1019,7 @@ static inline WrapperMethod *WrapperMethodLinkResolve(napi_env env, WrapperMetho [[maybe_unused]] static void DumpInvoke(WrapperMethod *wmethod, std::vector &args) { auto klass_name = wmethod->ets_method->GetClass()->GetName(); - auto method_name = reinterpret_cast(wmethod->ets_method->GetName().data); + auto method_name = reinterpret_cast(wmethod->ets_method->GetName().data); std::string msg = "DumpInvoke: " + klass_name + "::" + method_name + " with args:"; for (size_t i = 0; i < args.size(); ++i) { @@ -1037,7 +1036,7 @@ static bool WrapperCtorInit(napi_env env, napi_callback_info cinfo, size_t argc, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) PROXY_DLOG("WrapperCtorInit"); auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); [[maybe_unused]] EtsJSNapiEnvScope envscope(ctx, env); auto &wmethod_link = wclass->ets_init; auto wmethod = WrapperMethodLinkResolve(env, wmethod_link); @@ -1046,7 +1045,7 @@ static bool WrapperCtorInit(napi_env env, napi_callback_info cinfo, size_t argc, } if (UNLIKELY(wmethod->wclass_args.size() != argc)) { - JsPlugin::ThrowJSError(env, "constructor called in wrong context"); + InteropCtx::ThrowJSError(env, "constructor called in wrong context"); return false; } @@ -1079,7 +1078,7 @@ napi_value CallWrapperMethod(napi_env env, napi_callback_info cinfo) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) PROXY_DLOG_A("CallWrapperMethod static=%d", static_cast(IS_STATIC)); auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); [[maybe_unused]] EtsJSNapiEnvScope envscope(ctx, env); static constexpr auto ARGS_START = static_cast(!IS_STATIC); @@ -1104,10 +1103,10 @@ napi_value CallWrapperMethod(napi_env env, napi_callback_info cinfo) } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - PROXY_DLOG_A("CallWrapperMethod: %s", reinterpret_cast(wmethod->ets_method->GetName().data)); + PROXY_DLOG_A("CallWrapperMethod: %s", reinterpret_cast(wmethod->ets_method->GetName().data)); if (UNLIKELY(wmethod->wclass_args.size() != argc)) { - JsPlugin::ThrowJSError(env, "wrong argc: " + std::to_string(wmethod->wclass_args.size()) + " expected"); + InteropCtx::ThrowJSError(env, "wrong argc: " + std::to_string(wmethod->wclass_args.size()) + " expected"); return nullptr; } @@ -1175,7 +1174,7 @@ public: auto method = wmethod_->ets_method; auto const method_name = method->GetName(); napi_value js_func; - NAPI_CHECK_FATAL(napi_create_function(env_, reinterpret_cast(method_name.data), NAPI_AUTO_LENGTH, + NAPI_CHECK_FATAL(napi_create_function(env_, reinterpret_cast(method_name.data), NAPI_AUTO_LENGTH, &CallWrapperMethod, wmethod_, &js_func)); NAPI_CHECK_FATAL(napi_create_reference(env_, js_func, 1, &wmethod_->js_func)); return wmethod_; @@ -1275,8 +1274,8 @@ static WrapperMethod *GetWrapperFunction(napi_env env, panda::Method *method) WrapperMethodCreator creator(env, method); wmethod = creator.ProcessFunction(); if (UNLIKELY(wmethod == nullptr)) { - JsPlugin::ThrowJSError(env, std::string("can't create proxy wrapper of function ") + - reinterpret_cast(method->GetName().data)); + InteropCtx::ThrowJSError(env, std::string("can't create proxy wrapper of function ") + + reinterpret_cast(method->GetName().data)); return nullptr; } return wmethod; @@ -1292,8 +1291,8 @@ static WrapperMethod *GetWrapperMethod(napi_env env, panda::Method *method) WrapperMethodCreator creator(env, method); wmethod = creator.ProcessMethod(); if (UNLIKELY(wmethod == nullptr)) { - JsPlugin::ThrowJSError(env, std::string("can't create proxy wrapper of method ") + - reinterpret_cast(method->GetName().data)); + InteropCtx::ThrowJSError(env, std::string("can't create proxy wrapper of method ") + + reinterpret_cast(method->GetName().data)); return nullptr; } return wmethod; @@ -1307,13 +1306,13 @@ napi_value RegisterETSClassImpl(napi_env env, napi_value *jsargv, uint32_t jsarg PROXY_DLOG("RegisterETSClass: enter"); if (jsargc != 1) { - JsPlugin::ThrowJSError(env, "RegisterETSClass: bad args"); + InteropCtx::ThrowJSError(env, "RegisterETSClass: bad args"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (GetValueType(env, jsargv[0]) != napi_string) { - JsPlugin::ThrowJSError(env, "RegisterETSClass: class name is not a string"); + InteropCtx::ThrowJSError(env, "RegisterETSClass: class name is not a string"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -1322,7 +1321,7 @@ napi_value RegisterETSClassImpl(napi_env env, napi_value *jsargv, uint32_t jsarg auto coro = EtsCoroutine::GetCurrent(); auto ets_klass = coro->GetPandaVM()->GetClassLinker()->GetClass(klass_name.c_str()); if (UNLIKELY(ets_klass == nullptr)) { - JsPlugin::ThrowJSError(env, "RegisterETSClass: unresolved klass " + klass_name); + InteropCtx::ThrowJSError(env, "RegisterETSClass: unresolved klass " + klass_name); return nullptr; } @@ -1345,12 +1344,12 @@ napi_value RegisterETSFunctionImpl(napi_env env, napi_value *jsargv, uint32_t js PROXY_DLOG("RegisterETSFunction: enter"); if (jsargc != 1) { - JsPlugin::ThrowJSError(env, "RegisterETSFunction: bad args"); + InteropCtx::ThrowJSError(env, "RegisterETSFunction: bad args"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (GetValueType(env, jsargv[0]) != napi_string) { - JsPlugin::ThrowJSError(env, "RegisterETSFunction: function name is not a string"); + InteropCtx::ThrowJSError(env, "RegisterETSFunction: function name is not a string"); return nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -1363,7 +1362,7 @@ napi_value RegisterETSFunctionImpl(napi_env env, napi_value *jsargv, uint32_t js auto method_res = runtime->ResolveEntryPoint(method_name); if (!method_res) { - JsPlugin::ThrowJSError(env, "RegisterETSFunction: can't resolve method " + method_name); + InteropCtx::ThrowJSError(env, "RegisterETSFunction: can't resolve method " + method_name); return nullptr; } auto method = method_res.Value(); diff --git a/plugins/ets/runtime/interop_js/ts2ets_tstype.cpp b/plugins/ets/runtime/interop_js/ts2ets_tstype.cpp index 2b400dbd1c35777b2e3b64c266ca3ee462797db3..0ffabddcf70648daa1bd5268ef11ca01de6b81f1 100644 --- a/plugins/ets/runtime/interop_js/ts2ets_tstype.cpp +++ b/plugins/ets/runtime/interop_js/ts2ets_tstype.cpp @@ -55,7 +55,7 @@ extern "C" uint64_t TSTypeCallCtor([[maybe_unused]] Method *method, [[maybe_unus } static void *GetTSTypeGetterBridge(Method *method); -static napi_ref TSModuleRequire(napi_env env, std::string const &name) +static napi_ref TSModuleRequire(napi_env env, const std::string &name) { // requires module to be placed in global object napi_value js_glob; @@ -68,7 +68,7 @@ static napi_ref TSModuleRequire(napi_env env, std::string const &name) return js_ref; } -static napi_ref TSNapiModuleRequire(napi_env env, std::string const &name) +static napi_ref TSNapiModuleRequire(napi_env env, const std::string &name) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) TSTYPE_DLOG_A("TSNapiModuleRequire: %s", name.c_str()); @@ -91,9 +91,9 @@ static napi_ref TSNapiModuleRequire(napi_env env, std::string const &name) } struct TSTypeNamespace { - static constexpr char const *TSTYPE_DATA_FIELD = "__tstype"; - static constexpr char const *TSTYPE_PREFIX_GETTER = "_get_"; - static constexpr char const *TSTYPE_PREFIX_SETTER = "_set_"; + static constexpr const char *TSTYPE_DATA_FIELD = "__tstype"; + static constexpr const char *TSTYPE_PREFIX_GETTER = "_get_"; + static constexpr const char *TSTYPE_PREFIX_SETTER = "_set_"; static TSTypeNamespace *Create(panda::Class *klass, napi_ref toplevel); static TSTypeNamespace *Create(panda::Class *klass, TSTypeNamespace *upper); @@ -108,7 +108,7 @@ struct TSTypeNamespace { napi_value ResolveValue(napi_env env); private: - TSTypeNamespace(panda::Class *klass, napi_ref toplevel, std::vector &&resolv) + TSTypeNamespace(panda::Class *klass, napi_ref toplevel, std::vector &&resolv) : klass_(klass), toplevel_(toplevel), resolv_(resolv) { } @@ -117,7 +117,7 @@ private: panda::Class *klass_ {}; napi_ref toplevel_ {}; - std::vector resolv_; + std::vector resolv_; }; TSTypeNamespace *TSTypeNamespace::FromClass(Class *klass) @@ -139,7 +139,7 @@ TSTypeNamespace *TSTypeNamespace::Create(panda::Class *klass, napi_ref toplevel) TSTypeNamespace *TSTypeNamespace::Create(panda::Class *klass, TSTypeNamespace *upper) { - std::vector resolv; + std::vector resolv; resolv.reserve(upper->resolv_.size() + 1); resolv = upper->resolv_; resolv.push_back(klass->GetName().c_str()); @@ -205,7 +205,7 @@ static uint64_t TSTypeCCtor([[maybe_unused]] Method *method, coretypes::String * coretypes::String *enclosing_descriptor) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); auto env = ctx->GetJSEnv(); auto ets_class_linker = coro->GetPandaVM()->GetClassLinker(); auto tklass = ctx->LinkerCtx()->FindClass(descriptor->GetDataMUtf8()); @@ -237,7 +237,7 @@ ALWAYS_INLINE inline uint64_t TSTypeCall(Method *method, uint8_t *args, uint8_t // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) TSTYPE_DLOG("enter TSTypeCall"); auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); napi_env env = ctx->GetJSEnv(); NapiScope js_handle_scope(env); @@ -374,7 +374,7 @@ ALWAYS_INLINE inline uint64_t TSTypeCall(Method *method, uint8_t *args, uint8_t template static typename T::cpptype TSTypeGetter([[maybe_unused]] panda::Method *method, JSValue *jsvalue) { - auto ctx = GlobalCtx::Current(); + auto ctx = InteropCtx::Current(); constexpr auto METHOD_PREFIX_LEN = std::string_view(TSTypeNamespace::TSTYPE_PREFIX_GETTER).length(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) auto fname = utf::Mutf8AsCString(method->GetName().data + METHOD_PREFIX_LEN); @@ -386,7 +386,7 @@ static typename T::cpptype TSTypeGetter([[maybe_unused]] panda::Method *method, static void *GetTSTypeGetterBridge(Method *method) { auto coro = EtsCoroutine::GetCurrent(); - auto ctx = GlobalCtx::Current(coro); + auto ctx = InteropCtx::Current(coro); panda_file::Type type = method->GetReturnType(); switch (type.GetId()) {