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