• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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