1 /** 2 * Copyright (c) 2023-2025 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_field_wrapper.h" 22 #include "plugins/ets/runtime/interop_js/ets_proxy/ets_method_set.h" 23 #include "plugins/ets/runtime/interop_js/interop_common.h" 24 #include "plugins/ets/runtime/types/ets_method.h" 25 26 #include <node_api.h> 27 28 namespace ark::ets::interop::js { 29 class InteropCtx; 30 } // namespace ark::ets::interop::js 31 32 namespace ark::ets::interop::js::ets_proxy { 33 34 class EtsMethodWrapper; 35 class EtsClassWrapper; 36 37 using LazyEtsMethodWrapperLink = TypedPointer<EtsMethodSet, EtsMethodWrapper>; 38 using EtsMethodWrappersCache = WrappersCache<EtsMethodSet *, EtsMethodWrapper>; 39 using EtsMethodAndClassWrapper = std::tuple<EtsMethod *, const char *, EtsClassWrapper *>; 40 using FindMethodFunc = std::function<std::tuple<EtsMethod *, const char *, EtsClassWrapper *>(void *, size_t)>; 41 42 class EtsMethodWrapper { 43 public: 44 static EtsMethodWrapper *GetMethod(InteropCtx *ctx, EtsMethodSet *etsMethodSet); 45 GetJsValue(napi_env env)46 napi_value GetJsValue(napi_env env) const 47 { 48 ASSERT(jsRef_); 49 napi_value jsValue; 50 NAPI_CHECK_FATAL(napi_get_reference_value(env, jsRef_, &jsValue)); 51 return jsValue; 52 } 53 GetMethodSet()54 EtsMethodSet *GetMethodSet() const 55 { 56 return etsMethodSet_; 57 } 58 GetEtsMethod(uint32_t parametersNum)59 EtsMethod *GetEtsMethod(uint32_t parametersNum) const 60 { 61 return etsMethodSet_->GetMethod(parametersNum); 62 } 63 GetMethod(uint32_t parametersNum)64 Method *GetMethod(uint32_t parametersNum) const 65 { 66 EtsMethod *const etsMethod = etsMethodSet_->GetMethod(parametersNum); 67 return etsMethod != nullptr ? etsMethod->GetPandaMethod() : nullptr; 68 } 69 70 /** 71 * @param ctx - interop context 72 * @param lazy_link in/out lazy method wrapper link 73 */ ResolveLazyLink(InteropCtx * ctx,LazyEtsMethodWrapperLink & lazyLink)74 static inline EtsMethodWrapper *ResolveLazyLink(InteropCtx *ctx, LazyEtsMethodWrapperLink &lazyLink) 75 { 76 if (LIKELY(lazyLink.IsResolved())) { 77 return lazyLink.GetResolved(); 78 } 79 EtsMethodWrapper *wrapper = EtsMethodWrapper::GetMethod(ctx, lazyLink.GetUnresolved()); 80 if (UNLIKELY(wrapper == nullptr)) { 81 return nullptr; 82 } 83 ASSERT(wrapper->jsRef_ == nullptr); 84 // Update lazyLink 85 lazyLink = LazyEtsMethodWrapperLink(wrapper); 86 return wrapper; 87 } 88 89 static napi_property_descriptor MakeNapiProperty(EtsMethodSet *method, LazyEtsMethodWrapperLink *lazyLinkSpace); 90 static void AttachGetterSetterToProperty(EtsMethodSet *method, napi_property_descriptor &property); 91 92 static napi_property_descriptor MakeNapiIteratorProperty(napi_value &iterator, EtsMethodSet *method, 93 LazyEtsMethodWrapperLink *lazyLinkSpace); 94 95 template <bool IS_STATIC> 96 static napi_value EtsMethodCallHandler(napi_env env, napi_callback_info cinfo); 97 98 template <bool IS_STATIC> 99 static napi_value GetterSetterCallHandler(napi_env env, napi_callback_info cinfo); 100 101 private: 102 static std::unique_ptr<EtsMethodWrapper> CreateMethod(EtsMethodSet *etsMethodSet, EtsClassWrapper *owner); 103 EtsMethodWrapper(EtsMethodSet * etsMethodSet,EtsClassWrapper * owner)104 explicit EtsMethodWrapper(EtsMethodSet *etsMethodSet, EtsClassWrapper *owner) 105 : etsMethodSet_(etsMethodSet), owner_(owner) 106 { 107 } 108 109 template <bool IS_STATIC> 110 static napi_value DoEtsMethodCall(napi_env env, napi_callback_info cinfo, FindMethodFunc &findMethodFunc); 111 112 EtsMethodSet *const etsMethodSet_; 113 EtsClassWrapper *const owner_ {}; // only for instance methods 114 napi_ref jsRef_ {}; // only for functions (ETSGLOBAL::) 115 }; 116 117 } // namespace ark::ets::interop::js::ets_proxy 118 119 #endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_WRAPPER_H_ 120