1 /** 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_WRAPPER_H_ 17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_WRAPPER_H_ 18 19 #include "plugins/ets/runtime/interop_js/ets_proxy/typed_pointer.h" 20 #include "plugins/ets/runtime/interop_js/ets_proxy/wrappers_cache.h" 21 #include "plugins/ets/runtime/interop_js/ets_proxy/ets_method_set.h" 22 #include "plugins/ets/runtime/interop_js/interop_common.h" 23 #include "plugins/ets/runtime/types/ets_method.h" 24 25 #include <node_api.h> 26 27 namespace ark::ets::interop::js { 28 class InteropCtx; 29 } // namespace ark::ets::interop::js 30 31 namespace ark::ets::interop::js::ets_proxy { 32 33 class EtsMethodWrapper; 34 class EtsClassWrapper; 35 36 using LazyEtsMethodWrapperLink = TypedPointer<EtsMethodSet, EtsMethodWrapper>; 37 using EtsMethodWrappersCache = WrappersCache<EtsMethodSet *, EtsMethodWrapper>; 38 39 class EtsMethodWrapper { 40 public: 41 static EtsMethodWrapper *GetMethod(InteropCtx *ctx, EtsMethodSet *etsMethodSet); 42 GetJsValue(napi_env env)43 napi_value GetJsValue(napi_env env) const 44 { 45 ASSERT(jsRef_); 46 napi_value jsValue; 47 NAPI_CHECK_FATAL(napi_get_reference_value(env, jsRef_, &jsValue)); 48 return jsValue; 49 } 50 GetMethodSet()51 EtsMethodSet *GetMethodSet() const 52 { 53 return etsMethodSet_; 54 } 55 GetEtsMethod(uint32_t parametersNum)56 EtsMethod *GetEtsMethod(uint32_t parametersNum) const 57 { 58 return etsMethodSet_->GetMethod(parametersNum); 59 } 60 GetMethod(uint32_t parametersNum)61 Method *GetMethod(uint32_t parametersNum) const 62 { 63 EtsMethod *const etsMethod = etsMethodSet_->GetMethod(parametersNum); 64 return etsMethod != nullptr ? etsMethod->GetPandaMethod() : nullptr; 65 } 66 67 /** 68 * @param ctx - interop context 69 * @param lazy_link in/out lazy method wrapper link 70 */ ResolveLazyLink(InteropCtx * ctx,LazyEtsMethodWrapperLink & lazyLink)71 static inline EtsMethodWrapper *ResolveLazyLink(InteropCtx *ctx, LazyEtsMethodWrapperLink &lazyLink) 72 { 73 if (LIKELY(lazyLink.IsResolved())) { 74 return lazyLink.GetResolved(); 75 } 76 EtsMethodWrapper *wrapper = EtsMethodWrapper::GetMethod(ctx, lazyLink.GetUnresolved()); 77 if (UNLIKELY(wrapper == nullptr)) { 78 return nullptr; 79 } 80 ASSERT(wrapper->jsRef_ == nullptr); 81 // Update lazyLink 82 lazyLink = LazyEtsMethodWrapperLink(wrapper); 83 return wrapper; 84 } 85 86 static napi_property_descriptor MakeNapiProperty(EtsMethodSet *method, LazyEtsMethodWrapperLink *lazyLinkSpace); 87 88 template <bool IS_STATIC> 89 static napi_value EtsMethodCallHandler(napi_env env, napi_callback_info cinfo); 90 91 private: 92 static std::unique_ptr<EtsMethodWrapper> CreateMethod(EtsMethodSet *etsMethodSet, EtsClassWrapper *owner); 93 EtsMethodWrapper(EtsMethodSet * etsMethodSet,EtsClassWrapper * owner)94 EtsMethodWrapper(EtsMethodSet *etsMethodSet, EtsClassWrapper *owner) : etsMethodSet_(etsMethodSet), owner_(owner) {} 95 96 EtsMethodSet *const etsMethodSet_; 97 EtsClassWrapper *const owner_ {}; // only for instance methods 98 napi_ref jsRef_ {}; // only for functions (ETSGLOBAL::) 99 }; 100 101 } // namespace ark::ets::interop::js::ets_proxy 102 103 #endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_WRAPPER_H_ 104