1 /** 2 * Copyright (c) 2023 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/interop_common.h" 22 #include "plugins/ets/runtime/types/ets_method.h" 23 24 #include <node_api.h> 25 26 namespace panda::ets::interop::js { 27 class InteropCtx; 28 } // namespace panda::ets::interop::js 29 30 namespace panda::ets::interop::js::ets_proxy { 31 32 class EtsMethodWrapper; 33 class EtsClassWrapper; 34 35 using LazyEtsMethodWrapperLink = TypedPointer<Method, EtsMethodWrapper>; 36 using EtsMethodWrappersCache = WrappersCache<EtsMethod *, EtsMethodWrapper>; 37 38 class EtsMethodWrapper { 39 public: 40 static EtsMethodWrapper *GetMethod(InteropCtx *ctx, EtsMethod *etsMethod); 41 static EtsMethodWrapper *GetFunction(InteropCtx *ctx, EtsMethod *etsMethod); 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 GetEtsMethod()51 EtsMethod *GetEtsMethod() const 52 { 53 return etsMethod_; 54 } 55 GetMethod()56 Method *GetMethod() const 57 { 58 return etsMethod_->GetPandaMethod(); 59 } 60 61 /** 62 * @param ctx - interop context 63 * @param lazy_link in/out lazy method wrapper link 64 */ ResolveLazyLink(InteropCtx * ctx,LazyEtsMethodWrapperLink & lazyLink)65 static inline EtsMethodWrapper *ResolveLazyLink(InteropCtx *ctx, LazyEtsMethodWrapperLink &lazyLink) 66 { 67 if (LIKELY(lazyLink.IsResolved())) { 68 return lazyLink.GetResolved(); 69 } 70 EtsMethod *etsMethod = EtsMethod::FromRuntimeMethod(lazyLink.GetUnresolved()); 71 EtsMethodWrapper *wrapper = EtsMethodWrapper::GetMethod(ctx, etsMethod); 72 if (UNLIKELY(wrapper == nullptr)) { 73 return nullptr; 74 } 75 ASSERT(wrapper->jsRef_ == nullptr); 76 // Update lazyLink 77 lazyLink = LazyEtsMethodWrapperLink(wrapper); 78 return wrapper; 79 } 80 81 static napi_property_descriptor MakeNapiProperty(Method *method, LazyEtsMethodWrapperLink *lazyLinkSpace); 82 83 template <bool IS_STATIC, bool IS_FUNC> 84 static napi_value EtsMethodCallHandler(napi_env env, napi_callback_info cinfo); 85 86 private: 87 static std::unique_ptr<EtsMethodWrapper> CreateMethod(EtsMethod *method, EtsClassWrapper *owner); 88 static std::unique_ptr<EtsMethodWrapper> CreateFunction(InteropCtx *ctx, EtsMethod *method); 89 EtsMethodWrapper(EtsMethod * method,EtsClassWrapper * owner)90 EtsMethodWrapper(EtsMethod *method, EtsClassWrapper *owner) : etsMethod_(method), owner_(owner) {} 91 92 EtsMethod *const etsMethod_ {}; 93 EtsClassWrapper *const owner_ {}; // only for instance methods 94 napi_ref jsRef_ {}; // only for functions (ETSGLOBAL::) 95 }; 96 97 } // namespace panda::ets::interop::js::ets_proxy 98 99 #endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_WRAPPER_H 100