1 /**
2 * Copyright (c) 2024 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
IsStatic()45 bool IsStatic() const
46 {
47 return anyMethod_->IsStatic();
48 }
49
IsConstructor()50 bool IsConstructor() const
51 {
52 return anyMethod_->IsConstructor();
53 }
54
GetMethod(uint32_t parametersNum)55 ALWAYS_INLINE EtsMethod *GetMethod(uint32_t parametersNum) const
56 {
57 if (LIKELY(parametersNum < entries_.size())) {
58 if (LIKELY(entries_[parametersNum] != nullptr)) {
59 return entries_[parametersNum];
60 }
61 }
62 // Try rest params
63 for (size_t params = std::min(static_cast<size_t>(parametersNum), entries_.size() - 1); params > 0; params--) {
64 if (entries_[params] != nullptr && entries_[params]->GetPandaMethod()->HasVarArgs()) {
65 return entries_[params];
66 }
67 }
68 return entries_.front();
69 }
70
71 template <typename Callback>
EnumerateMethods(const Callback & callback)72 void EnumerateMethods(const Callback &callback) const
73 {
74 for (auto m : entries_) {
75 if (nullptr != m) {
76 callback(m);
77 }
78 }
79 }
80
GetEnclosingClass()81 EtsClass *GetEnclosingClass() const
82 {
83 return enclosingClass_;
84 }
85
SetBaseMethodSet(EtsMethodSet * baseMethodSet)86 void SetBaseMethodSet(EtsMethodSet *baseMethodSet)
87 {
88 baseMethodSet_ = baseMethodSet;
89 }
90
GetBaseMethodSet()91 EtsMethodSet *GetBaseMethodSet() const
92 {
93 return baseMethodSet_;
94 }
95
96 void MergeWith(const EtsMethodSet &other);
97
98 private:
EtsMethodSet(EtsMethod * singleMethod,EtsClass * enclosingClass)99 explicit EtsMethodSet(EtsMethod *singleMethod, EtsClass *enclosingClass)
100 : enclosingClass_(enclosingClass),
101 #ifndef NDEBUG
102 name_(singleMethod->GetFullName(false)),
103 #endif
104 entries_(PandaVector<EtsMethod *>(singleMethod->GetParametersNum() + 1)),
105 anyMethod_(singleMethod)
106 {
107 entries_[singleMethod->GetParametersNum() -
108 static_cast<unsigned int>(singleMethod->GetPandaMethod()->HasVarArgs())] = singleMethod;
109 }
110
111 EtsClass *const enclosingClass_;
112
113 #ifndef NDEBUG
114 std::string name_; // just for GDB
115 #endif
116
117 // Index number in vector is a number of paramaters for O(1) lookup
118 PandaVector<EtsMethod *> entries_;
119
120 // Abritrary item from set to get common properties
121 const EtsMethod *const anyMethod_;
122
123 bool isValid_ = true;
124
125 EtsMethodSet *baseMethodSet_ = nullptr;
126 };
127
128 template <class Iterator>
CollectAllPandaMethods(Iterator begin,Iterator end)129 PandaVector<Method *> CollectAllPandaMethods(Iterator begin, Iterator end)
130 {
131 PandaVector<Method *> allMethods;
132 for (Iterator it = begin; it != end; ++it) {
133 const EtsMethodSet *methodSet = *it;
134 const auto pushAllPandaMethods = [&allMethods](EtsMethod *m) { allMethods.push_back(m->GetPandaMethod()); };
135 methodSet->EnumerateMethods(pushAllPandaMethods);
136 }
137 return allMethods;
138 }
139
140 } // namespace ark::ets::interop::js::ets_proxy
141
142 #endif // PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_METHOD_SET_H
143