1 /* 2 * Copyright (c) 2022 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_COMPILER_BUILTINS_CALL_SIGNATURE_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_CALL_SIGNATURE_H 18 19 #include "ecmascript/base/config.h" 20 #include "ecmascript/compiler/rt_call_signature.h" 21 #include "ecmascript/global_env_constants.h" 22 23 namespace panda::ecmascript::kungfu { 24 25 #define PADDING_BUILTINS_STUB_LIST(V) \ 26 V(NONE) 27 28 // BUILTINS_STUB_LIST is shared both ASM Interpreter and AOT. 29 // AOT_BUILTINS_STUB_LIST is used in AOT only. 30 #define BUILTINS_STUB_LIST(V) \ 31 BUILTINS_METHOD_STUB_LIST(V) \ 32 BUILTINS_CONSTRUCTOR_STUB_LIST(V) \ 33 AOT_AND_BUILTINS_STUB_LIST(V) 34 35 #define BUILTINS_METHOD_STUB_LIST(V) \ 36 V(StringCharCodeAt) \ 37 V(StringIndexOf) \ 38 V(StringSubstring) \ 39 V(StringReplace) \ 40 V(StringCharAt) \ 41 V(StringFromCharCode) \ 42 V(StringTrim) \ 43 V(StringSlice) \ 44 V(ObjectToString) \ 45 V(ObjectCreate) \ 46 V(ObjectAssign) \ 47 V(ObjectHasOwnProperty) \ 48 V(ObjectKeys) \ 49 V(VectorForEach) \ 50 V(VectorReplaceAllElements) \ 51 V(StackForEach) \ 52 V(PlainArrayForEach) \ 53 V(QueueForEach) \ 54 V(DequeForEach) \ 55 V(LightWeightMapForEach) \ 56 V(LightWeightSetForEach) \ 57 V(HashMapForEach) \ 58 V(HashSetForEach) \ 59 V(LinkedListForEach) \ 60 V(ListForEach) \ 61 V(ArrayListForEach) \ 62 V(ArrayListReplaceAllElements) \ 63 V(FunctionPrototypeApply) \ 64 V(ArrayConcat) \ 65 V(ArrayFilter) \ 66 V(ArrayFind) \ 67 V(ArrayFindIndex) \ 68 V(ArrayForEach) \ 69 V(ArrayIndexOf) \ 70 V(ArrayLastIndexOf) \ 71 V(ArrayPop) \ 72 V(ArraySlice) \ 73 V(ArrayValues) \ 74 V(ArrayReduce) \ 75 V(ArrayReverse) \ 76 V(ArrayPush) \ 77 V(ArrayIncludes) \ 78 V(ArrayFrom) \ 79 V(ArraySplice) \ 80 V(SetClear) \ 81 V(SetValues) \ 82 V(SetEntries) \ 83 V(SetForEach) \ 84 V(SetAdd) \ 85 V(SetDelete) \ 86 V(SetHas) \ 87 V(MapClear) \ 88 V(MapValues) \ 89 V(MapEntries) \ 90 V(MapKeys) \ 91 V(MapForEach) \ 92 V(MapSet) \ 93 V(MapDelete) \ 94 V(MapHas) \ 95 V(NumberParseFloat) \ 96 V(TypedArraySubArray) 97 98 #define BUILTINS_CONSTRUCTOR_STUB_LIST(V) \ 99 V(BooleanConstructor) \ 100 V(NumberConstructor) \ 101 V(DateConstructor) \ 102 V(ArrayConstructor) 103 104 #define AOT_AND_BUILTINS_STUB_LIST(V) \ 105 V(LocaleCompare) \ 106 V(SORT) 107 108 #define AOT_BUILTINS_STUB_LIST(V) \ 109 V(SQRT) /* list start and math list start */ \ 110 V(COS) \ 111 V(SIN) \ 112 V(ACOS) \ 113 V(ATAN) \ 114 V(ABS) \ 115 V(FLOOR) /* math list end */ \ 116 V(STRINGIFY) \ 117 V(MAP_PROTO_ITERATOR) \ 118 V(SET_PROTO_ITERATOR) \ 119 V(STRING_PROTO_ITERATOR) \ 120 V(ARRAY_PROTO_ITERATOR) \ 121 V(TYPED_ARRAY_PROTO_ITERATOR) \ 122 V(MAP_ITERATOR_PROTO_NEXT) \ 123 V(SET_ITERATOR_PROTO_NEXT) \ 124 V(STRING_ITERATOR_PROTO_NEXT) \ 125 V(ARRAY_ITERATOR_PROTO_NEXT) 126 127 class BuiltinsStubCSigns { 128 public: 129 enum ID { 130 #define DEF_STUB_ID(name) name, 131 PADDING_BUILTINS_STUB_LIST(DEF_STUB_ID) 132 BUILTINS_STUB_LIST(DEF_STUB_ID) 133 #undef DEF_STUB_ID 134 NUM_OF_BUILTINS_STUBS, 135 #define DEF_STUB_ID(name) name, 136 AOT_BUILTINS_STUB_LIST(DEF_STUB_ID) 137 #undef DEF_STUB_ID 138 BUILTINS_CONSTRUCTOR_STUB_FIRST = BooleanConstructor, 139 TYPED_BUILTINS_FIRST = SQRT, 140 TYPED_BUILTINS_LAST = ARRAY_ITERATOR_PROTO_NEXT, 141 TYPED_BUILTINS_MATH_FIRST = SQRT, 142 TYPED_BUILTINS_MATH_LAST = FLOOR, 143 INVALID = 0xFF, 144 }; 145 static_assert(ID::NONE == 0); 146 147 static void Initialize(); 148 149 static void GetCSigns(std::vector<const CallSignature*>& callSigns); 150 Get(size_t index)151 static const CallSignature *Get(size_t index) 152 { 153 ASSERT(index < NUM_OF_BUILTINS_STUBS); 154 return &callSigns_[index]; 155 } 156 GetName(int index)157 static const std::string &GetName(int index) 158 { 159 ASSERT(index < NUM_OF_BUILTINS_STUBS); 160 return callSigns_[index].GetName(); 161 } 162 BuiltinsCSign()163 static const CallSignature* BuiltinsCSign() 164 { 165 return &builtinsCSign_; 166 } 167 BuiltinsWithArgvCSign()168 static const CallSignature* BuiltinsWithArgvCSign() 169 { 170 return &builtinsWithArgvCSign_; 171 } 172 IsFastBuiltin(ID builtinId)173 static bool IsFastBuiltin(ID builtinId) 174 { 175 return builtinId > NONE && builtinId < NUM_OF_BUILTINS_STUBS; 176 } 177 IsTypedBuiltin(ID builtinId)178 static bool IsTypedBuiltin(ID builtinId) 179 { 180 return (BuiltinsStubCSigns::ID::LocaleCompare == builtinId) || 181 (BuiltinsStubCSigns::ID::SORT == builtinId) || 182 ((BuiltinsStubCSigns::ID::TYPED_BUILTINS_FIRST <= builtinId) && 183 (builtinId <= BuiltinsStubCSigns::ID::TYPED_BUILTINS_LAST)); 184 } 185 IsTypedInlineBuiltin(ID builtinId)186 static bool IsTypedInlineBuiltin(ID builtinId) 187 { 188 return BuiltinsStubCSigns::ID::StringFromCharCode == builtinId; 189 } 190 IsTypedBuiltinMath(ID builtinId)191 static bool IsTypedBuiltinMath(ID builtinId) 192 { 193 return (BuiltinsStubCSigns::ID::TYPED_BUILTINS_MATH_FIRST <= builtinId) && 194 (builtinId <= BuiltinsStubCSigns::ID::TYPED_BUILTINS_MATH_LAST); 195 } 196 IsTypedBuiltinNumber(ID builtinId)197 static bool IsTypedBuiltinNumber(ID builtinId) 198 { 199 return BuiltinsStubCSigns::ID::NumberConstructor == builtinId; 200 } 201 IsTypedBuiltinCallThis0(ID builtinId)202 static bool IsTypedBuiltinCallThis0(ID builtinId) 203 { 204 switch (builtinId) { 205 case BuiltinsStubCSigns::ID::MAP_ITERATOR_PROTO_NEXT: 206 case BuiltinsStubCSigns::ID::SET_ITERATOR_PROTO_NEXT: 207 case BuiltinsStubCSigns::ID::STRING_ITERATOR_PROTO_NEXT: 208 case BuiltinsStubCSigns::ID::ARRAY_ITERATOR_PROTO_NEXT: 209 return true; 210 default: 211 return false; 212 } 213 } 214 IsTypedBuiltinCallThis3(ID builtinId)215 static bool IsTypedBuiltinCallThis3(ID builtinId) 216 { 217 switch (builtinId) { 218 case BuiltinsStubCSigns::ID::LocaleCompare: 219 return true; 220 default: 221 return false; 222 } 223 } 224 GetConstantIndex(ID builtinId)225 static ConstantIndex GetConstantIndex(ID builtinId) 226 { 227 switch (builtinId) { 228 case BuiltinsStubCSigns::ID::COS: 229 return ConstantIndex::MATH_COS_FUNCTION_INDEX; 230 case BuiltinsStubCSigns::ID::SIN: 231 return ConstantIndex::MATH_SIN_FUNCTION_INDEX; 232 case BuiltinsStubCSigns::ID::ACOS: 233 return ConstantIndex::MATH_ACOS_FUNCTION_INDEX; 234 case BuiltinsStubCSigns::ID::ATAN: 235 return ConstantIndex::MATH_ATAN_FUNCTION_INDEX; 236 case BuiltinsStubCSigns::ID::ABS: 237 return ConstantIndex::MATH_ABS_FUNCTION_INDEX; 238 case BuiltinsStubCSigns::ID::FLOOR: 239 return ConstantIndex::MATH_FLOOR_FUNCTION_INDEX; 240 case BuiltinsStubCSigns::ID::SQRT: 241 return ConstantIndex::MATH_SQRT_FUNCTION_INDEX; 242 case BuiltinsStubCSigns::ID::LocaleCompare: 243 return ConstantIndex::LOCALE_COMPARE_FUNCTION_INDEX; 244 case BuiltinsStubCSigns::ID::SORT: 245 return ConstantIndex::ARRAY_SORT_FUNCTION_INDEX; 246 case BuiltinsStubCSigns::ID::STRINGIFY: 247 return ConstantIndex::JSON_STRINGIFY_FUNCTION_INDEX; 248 case BuiltinsStubCSigns::ID::MAP_ITERATOR_PROTO_NEXT: 249 return ConstantIndex::MAP_ITERATOR_PROTO_NEXT_INDEX; 250 case BuiltinsStubCSigns::ID::SET_ITERATOR_PROTO_NEXT: 251 return ConstantIndex::SET_ITERATOR_PROTO_NEXT_INDEX; 252 case BuiltinsStubCSigns::ID::STRING_ITERATOR_PROTO_NEXT: 253 return ConstantIndex::STRING_ITERATOR_PROTO_NEXT_INDEX; 254 case BuiltinsStubCSigns::ID::ARRAY_ITERATOR_PROTO_NEXT: 255 return ConstantIndex::ARRAY_ITERATOR_PROTO_NEXT_INDEX; 256 case BuiltinsStubCSigns::ID::StringFromCharCode: 257 return ConstantIndex::STRING_FROM_CHAR_CODE_INDEX; 258 default: 259 LOG_COMPILER(FATAL) << "this branch is unreachable"; 260 UNREACHABLE(); 261 } 262 } 263 264 static size_t GetGlobalEnvIndex(ID builtinId); 265 GetBuiltinId(std::string idStr)266 static ID GetBuiltinId(std::string idStr) 267 { 268 const std::map<std::string, BuiltinsStubCSigns::ID> str2BuiltinId = { 269 {"sqrt", SQRT}, 270 {"cos", COS}, 271 {"sin", SIN}, 272 {"acos", ACOS}, 273 {"atan", ATAN}, 274 {"abs", ABS}, 275 {"floor", FLOOR}, 276 {"localeCompare", LocaleCompare}, 277 {"sort", SORT}, 278 {"stringify", STRINGIFY}, 279 }; 280 if (str2BuiltinId.count(idStr) > 0) { 281 return str2BuiltinId.at(idStr); 282 } 283 return NONE; 284 } 285 286 private: 287 static CallSignature callSigns_[NUM_OF_BUILTINS_STUBS]; 288 static CallSignature builtinsCSign_; 289 static CallSignature builtinsWithArgvCSign_; 290 }; 291 292 enum class BuiltinsArgs : size_t { 293 GLUE = 0, 294 NATIVECODE, 295 FUNC, 296 NEWTARGET, 297 THISVALUE, 298 NUMARGS, 299 ARG0_OR_ARGV, 300 ARG1, 301 ARG2, 302 NUM_OF_INPUTS, 303 }; 304 305 #define BUILTINS_STUB_ID(name) kungfu::BuiltinsStubCSigns::name 306 // to distinguish with the positive method offset of js function 307 #define PGO_BUILTINS_STUB_ID(name) ((-1) * kungfu::BuiltinsStubCSigns::name) 308 #define IS_TYPED_BUILTINS_ID(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltin(id) 309 #define IS_TYPED_INLINE_BUILTINS_ID(id) kungfu::BuiltinsStubCSigns::IsTypedInlineBuiltin(id) 310 #define IS_TYPED_BUILTINS_MATH_ID(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltinMath(id) 311 #define IS_TYPED_BUILTINS_NUMBER_ID(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltinNumber(id) 312 #define IS_TYPED_BUILTINS_ID_CALL_THIS0(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltinCallThis0(id) 313 #define IS_TYPED_BUILTINS_ID_CALL_THIS3(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltinCallThis3(id) 314 #define GET_TYPED_CONSTANT_INDEX(id) kungfu::BuiltinsStubCSigns::GetConstantIndex(id) 315 #define GET_TYPED_GLOBAL_ENV_INDEX(id) kungfu::BuiltinsStubCSigns::GetGlobalEnvIndex(id) 316 } // namespace panda::ecmascript::kungfu 317 #endif // ECMASCRIPT_COMPILER_BUILTINS_CALL_SIGNATURE_H 318