1 /**
2 * Copyright (c) 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_SET_H
17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_SET_H
18
19 #include "runtime/include/runtime.h"
20 #include "plugins/ets/runtime/types/ets_method.h"
21
22 namespace ark::ets {
23 class EtsClass;
24 } // namespace ark::ets
25
26 namespace ark::ets::interop::js::ets_proxy {
27
28 // Set of methods that have the same name but different signatures
29 class EtsMethodSet {
30 public:
31 static EtsMethodSet Create(EtsMethod *singleMethod);
32
Create(Method * singleMethod)33 static EtsMethodSet Create(Method *singleMethod)
34 {
35 return Create(EtsMethod::FromRuntimeMethod(singleMethod));
36 }
37
38 const char *GetName() const;
39
IsValid()40 bool IsValid() const
41 {
42 return isValid_;
43 }
44
IsSetter()45 bool IsSetter()
46 {
47 return strncmp(GetName(), SETTER_BEGIN, strlen(SETTER_BEGIN)) == 0;
48 }
49
IsGetter()50 bool IsGetter()
51 {
52 return strncmp(GetName(), GETTER_BEGIN, strlen(GETTER_BEGIN)) == 0;
53 }
54
IsStatic()55 bool IsStatic() const
56 {
57 return anyMethod_->IsStatic();
58 }
59
IsConstructor()60 bool IsConstructor() const
61 {
62 return anyMethod_->IsConstructor();
63 }
64
GetMethod(uint32_t parametersNum)65 ALWAYS_INLINE EtsMethod *GetMethod(uint32_t parametersNum) const
66 {
67 // Try optional parameters
68 uint32_t tempParameter = parametersNum;
69 while (LIKELY(tempParameter < entries_.size())) {
70 if (LIKELY(entries_[tempParameter] != nullptr)) {
71 return entries_[tempParameter];
72 }
73 tempParameter++;
74 }
75 // Try rest params
76 for (size_t params = std::min(static_cast<size_t>(parametersNum), entries_.size() - 1); params > 0; params--) {
77 if (entries_[params] != nullptr && entries_[params]->GetPandaMethod()->HasVarArgs()) {
78 return entries_[params];
79 }
80 }
81 return entries_.front();
82 }
83
84 template <typename Callback>
EnumerateMethods(const Callback & callback)85 void EnumerateMethods(const Callback &callback) const
86 {
87 for (auto m : entries_) {
88 if (nullptr != m) {
89 callback(m);
90 }
91 }
92 }
93
GetEnclosingClass()94 EtsClass *GetEnclosingClass() const
95 {
96 return enclosingClass_;
97 }
98
SetBaseMethodSet(EtsMethodSet * baseMethodSet)99 void SetBaseMethodSet(EtsMethodSet *baseMethodSet)
100 {
101 baseMethodSet_ = baseMethodSet;
102 }
103
GetBaseMethodSet()104 EtsMethodSet *GetBaseMethodSet() const
105 {
106 return baseMethodSet_;
107 }
108
109 void MergeWith(const EtsMethodSet &other);
110
111 private:
EtsMethodSet(EtsMethod * singleMethod,EtsClass * enclosingClass)112 explicit EtsMethodSet(EtsMethod *singleMethod, EtsClass *enclosingClass)
113 : enclosingClass_(enclosingClass),
114 #ifndef NDEBUG
115 name_(singleMethod->GetFullName(false)),
116 #endif
117 entries_(PandaVector<EtsMethod *>(singleMethod->GetParametersNum() + 1)),
118 anyMethod_(singleMethod)
119 {
120 entries_[singleMethod->GetParametersNum() -
121 static_cast<unsigned int>(singleMethod->GetPandaMethod()->HasVarArgs())] = singleMethod;
122 }
123
124 EtsClass *const enclosingClass_;
125
126 #ifndef NDEBUG
127 std::string name_; // just for GDB
128 #endif
129
130 // Index number in vector is a number of paramaters for O(1) lookup
131 PandaVector<EtsMethod *> entries_;
132
133 // Abritrary item from set to get common properties
134 const EtsMethod *const anyMethod_;
135
136 bool isValid_ = true;
137
138 EtsMethodSet *baseMethodSet_ = nullptr;
139 };
140
141 template <class Iterator>
CollectAllPandaMethods(Iterator begin,Iterator end)142 PandaVector<Method *> CollectAllPandaMethods(Iterator begin, Iterator end)
143 {
144 PandaVector<Method *> allMethods;
145 for (Iterator it = begin; it != end; ++it) {
146 const EtsMethodSet *methodSet = *it;
147 const auto pushAllPandaMethods = [&allMethods](EtsMethod *m) { allMethods.push_back(m->GetPandaMethod()); };
148 methodSet->EnumerateMethods(pushAllPandaMethods);
149 }
150 return allMethods;
151 }
152
153 } // namespace ark::ets::interop::js::ets_proxy
154
155 #endif // PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_SET_H
156