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