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