• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 ECMASCRIPT_BASE_BUILTINS_BASE_H
17 #define ECMASCRIPT_BASE_BUILTINS_BASE_H
18 
19 #include "ecmascript/ecma_runtime_call_info.h"
20 #include "ecmascript/ecma_string.h"
21 #include "ecmascript/global_env_constants-inl.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/object_factory.h"
24 #include "ecmascript/runtime_call_id.h"
25 #include "ecmascript/tagged_array.h"
26 
27 namespace panda::ecmascript {
28 class JSArray;
29 namespace base {
30 class BuiltinConstantEntry {
31 public:
BuiltinConstantEntry(std::string_view name,JSTaggedValue value)32     constexpr BuiltinConstantEntry(std::string_view name, JSTaggedValue value)
33         : name_(name), rawTaggedValue_(value.GetRawData()) {}
34 
Create(std::string_view name,JSTaggedValue value)35     static constexpr BuiltinConstantEntry Create(std::string_view name, JSTaggedValue value)
36     {
37         return BuiltinConstantEntry(name, value);
38     }
39 
GetName()40     constexpr std::string_view GetName() const
41     {
42         return name_;
43     }
44 
GetTaggedValue()45     constexpr JSTaggedValue GetTaggedValue() const
46     {
47         return JSTaggedValue(rawTaggedValue_);
48     }
49 
50 private:
51     std::string_view name_;
52     JSTaggedType rawTaggedValue_;
53 };
54 
55 class BuiltinsPropertyConfig {
56 public:
BuiltinsPropertyConfig(std::string_view name,bool isAccessor,bool writable,bool enumerable,bool configurable)57     constexpr BuiltinsPropertyConfig(std::string_view name, bool isAccessor, bool writable,
58         bool enumerable, bool configurable)
59         : name_(name), isAccessor_(isAccessor), writable_(writable),
60           enumerable_(enumerable), configurable_(configurable) {}
61 
GetName()62     constexpr std::string_view GetName() const
63     {
64         return name_;
65     }
66 
GetIsAccessor()67     constexpr bool GetIsAccessor() const
68     {
69         return isAccessor_;
70     }
71 
GetWritable()72     constexpr bool GetWritable() const
73     {
74         return writable_;
75     }
76 
GetEnumerable()77     constexpr bool GetEnumerable() const
78     {
79         return enumerable_;
80     }
81 
GetConfigurable()82     constexpr bool GetConfigurable() const
83     {
84         return configurable_;
85     }
86 
87 private:
88     std::string_view name_;
89     bool isAccessor_ {false};
90     bool writable_ {false};
91     bool enumerable_ {false};
92     bool configurable_ {false};
93 };
94 
95 class BuiltinFunctionEntry {
96 public:
97     static constexpr int LENGTH_BITS_SIZE = 8;
98     static constexpr int BUILTIN_ID_BITS_SIZE = 16;
99     // Assures the bits are enough to represent all builtin stubs.
100     static_assert(kungfu::BuiltinsStubCSigns::NUM_OF_BUILTINS_STUBS <= (1u << BUILTIN_ID_BITS_SIZE));
101 
102     using LengthBits = panda::BitField<int, 0, LENGTH_BITS_SIZE>;
103     using BuiltinIdBits = LengthBits::NextField<kungfu::BuiltinsStubCSigns::ID, BUILTIN_ID_BITS_SIZE>;
104     using IsConstructorBit = BuiltinIdBits::NextFlag;
105     using IsAccessorBit = IsConstructorBit::NextFlag;
106 
107     template <class... BitFieldArgs>
Create(std::string_view name,EcmaEntrypoint entrypoint,int length,kungfu::BuiltinsStubCSigns::ID builtinId)108     static constexpr BuiltinFunctionEntry Create(std::string_view name, EcmaEntrypoint entrypoint,
109                                                  int length, kungfu::BuiltinsStubCSigns::ID builtinId)
110     {
111         static_assert((std::is_same_v<typename BitFieldArgs::ValueType, bool> && ...),
112                       "Only 1-bit fields are available in BitFieldArgs");
113         uint64_t bitfield = 0;
114         bitfield |= LengthBits::Encode(length);
115         bitfield |= BuiltinIdBits::Encode(builtinId);
116         // Traverses BitFieldArgs (IsConstructorBit, IsAccessorBit, etc.)
117         ((bitfield |= BitFieldArgs::Encode(true)), ...);
118         return BuiltinFunctionEntry(name, entrypoint, bitfield);
119     }
120 
GetName()121     constexpr std::string_view GetName() const
122     {
123         return name_;
124     }
125 
GetEntrypoint()126     constexpr EcmaEntrypoint GetEntrypoint() const
127     {
128         return entrypoint_;
129     }
130 
GetLength()131     constexpr int GetLength() const
132     {
133         return LengthBits::Decode(bitfield_);
134     }
135 
GetBuiltinStubId()136     constexpr kungfu::BuiltinsStubCSigns::ID GetBuiltinStubId() const
137     {
138         return BuiltinIdBits::Decode(bitfield_);
139     }
140 
IsConstructor()141     constexpr bool IsConstructor() const
142     {
143         return IsConstructorBit::Decode(bitfield_);
144     }
145 
IsAccessor()146     constexpr bool IsAccessor() const
147     {
148         return IsAccessorBit::Decode(bitfield_);
149     }
150 
151 private:
152     std::string_view name_;
153     EcmaEntrypoint entrypoint_;
154     uint64_t bitfield_;
155 
BuiltinFunctionEntry(std::string_view name,EcmaEntrypoint entrypoint,uint64_t bitfield)156     constexpr BuiltinFunctionEntry(std::string_view name, EcmaEntrypoint entrypoint, uint64_t bitfield)
157         : name_(name), entrypoint_(entrypoint), bitfield_(bitfield) {}
158 };
159 
160 class BuiltinsBase {
161 public:
162     enum ArgsPosition : uint32_t { FIRST = 0, SECOND, THIRD, FOURTH, FIFTH };
163     static JSHandle<TaggedArray> GetArgsArray(EcmaRuntimeCallInfo *msg);
GetConstructor(EcmaRuntimeCallInfo * msg)164     static inline JSHandle<JSTaggedValue> GetConstructor(EcmaRuntimeCallInfo *msg)
165     {
166         return msg->GetFunction();
167     }
168 
GetThis(EcmaRuntimeCallInfo * msg)169     static inline JSHandle<JSTaggedValue> GetThis(EcmaRuntimeCallInfo *msg)
170     {
171         return msg->GetThis();
172     }
173 
GetNewTarget(EcmaRuntimeCallInfo * msg)174     static inline JSHandle<JSTaggedValue> GetNewTarget(EcmaRuntimeCallInfo *msg)
175     {
176         return msg->GetNewTarget();
177     }
178 
GetCallArg(EcmaRuntimeCallInfo * msg,uint32_t position)179     static inline JSHandle<JSTaggedValue> GetCallArg(EcmaRuntimeCallInfo *msg, uint32_t position)
180     {
181         if (position >= msg->GetArgsNumber()) {
182             JSThread *thread = msg->GetThread();
183             return thread->GlobalConstants()->GetHandledUndefined();
184         }
185         return msg->GetCallArg(position);
186     }
187 
GetTaggedInt(int32_t value)188     static inline JSTaggedValue GetTaggedInt(int32_t value)
189     {
190         return JSTaggedValue(value);
191     }
192 
GetTaggedInt64(int64_t value)193     static inline JSTaggedValue GetTaggedInt64(int64_t value)
194     {
195         return JSTaggedValue(value);
196     }
197 
GetTaggedDouble(double value)198     static inline JSTaggedValue GetTaggedDouble(double value)
199     {
200         return JSTaggedValue(value);
201     }
202 
GetTaggedBoolean(bool value)203     static inline JSTaggedValue GetTaggedBoolean(bool value)
204     {
205         return JSTaggedValue(value);
206     }
207 
GetTaggedString(JSThread * thread,const char * str)208     static inline JSTaggedValue GetTaggedString(JSThread *thread, const char *str)
209     {
210         return thread->GetEcmaVM()->GetFactory()->NewFromASCII(str).GetTaggedValue();
211     }
212 };
213 }  // namespace base
214 }  // namespace panda::ecmascript
215 
216 #endif  // ECMASCRIPT_BASE_BUILTINS_BASE_H
217