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_COMPILER_CALL_SIGNATURE_H 17 #define ECMASCRIPT_COMPILER_CALL_SIGNATURE_H 18 19 #include <array> 20 #include <functional> 21 #include <memory> 22 23 #include "ecmascript/compiler/variable_type.h" 24 #include "ecmascript/compiler/test_stubs_signature.h" 25 26 #include "libpandabase/macros.h" 27 #include "libpandabase/utils/bit_field.h" 28 29 namespace panda::ecmascript::kungfu { 30 class Circuit; 31 32 enum class ArgumentsOrder { 33 DEFAULT_ORDER, // Push Arguments in stack from right -> left 34 }; 35 36 class CallSignature { 37 public: 38 using TargetConstructor = std::function<void *(void *)>; 39 enum class TargetKind : uint8_t { 40 COMMON_STUB = 0, 41 RUNTIME_STUB, 42 RUNTIME_STUB_VARARGS, 43 RUNTIME_STUB_NO_GC, 44 OPTIMIZED_STUB, 45 OPTIMIZED_FAST_CALL_STUB, 46 DEOPT_STUB, 47 BYTECODE_HANDLER, 48 BYTECODE_DEBUGGER_HANDLER, 49 BYTECODE_HELPER_HANDLER, 50 BYTECODE_PROFILE_HANDLER, 51 JSFUNCTION, 52 BUILTINS_STUB, 53 BUILTINS_WITH_ARGV_STUB, 54 55 STUB_BEGIN = COMMON_STUB, 56 STUB_END = BYTECODE_HANDLER, 57 BCHANDLER_BEGIN = BYTECODE_HANDLER, 58 BCHANDLER_END = JSFUNCTION 59 }; 60 enum class CallConv: uint8_t { 61 CCallConv = 0, 62 GHCCallConv = 1, 63 WebKitJSCallConv = 2, 64 }; 65 static constexpr size_t TARGET_KIND_BIT_LENGTH = 4; 66 static constexpr size_t CALL_CONV_BIT_LENGTH = 2; 67 using TargetKindBit = panda::BitField<TargetKind, 0, TARGET_KIND_BIT_LENGTH>; 68 using CallConvBit = TargetKindBit::NextField<CallConv, CALL_CONV_BIT_LENGTH>; 69 using VariadicArgsBit = CallConvBit::NextField<bool, 1>; 70 using TailCallBit = VariadicArgsBit::NextField<bool, 1>; 71 using GCLeafFunctionBit = TailCallBit::NextField<bool, 1>; 72 CallSignature(std::string name,int flags,size_t paramCounter,ArgumentsOrder order,VariableType returnType)73 CallSignature(std::string name, int flags, size_t paramCounter, ArgumentsOrder order, 74 VariableType returnType) 75 : name_(name), paramCounter_(paramCounter), order_(order), returnType_(returnType) 76 { 77 SetTargetKind(TargetKind::COMMON_STUB); 78 SetCallConv(CallSignature::CallConv::CCallConv); 79 SetTailCall(false); 80 SetGCLeafFunction(false); 81 SetVariadicArgs(flags); 82 } 83 84 CallSignature() = default; 85 86 ~CallSignature() = default; 87 CallSignature(CallSignature const & other)88 CallSignature(CallSignature const &other) 89 { 90 name_ = other.name_; 91 paramCounter_ = other.paramCounter_; 92 order_ = other.order_; 93 id_ = other.id_; 94 returnType_ = other.returnType_; 95 constructor_ = other.constructor_; 96 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 97 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 98 for (size_t i = 0; i < paramCounter_; i++) { 99 (*paramsType_)[i] = other.GetParametersType()[i]; 100 } 101 } 102 kind_ = other.kind_; 103 } 104 105 CallSignature &operator=(CallSignature const &other) 106 { 107 name_ = other.name_; 108 paramCounter_ = other.paramCounter_; 109 order_ = other.order_; 110 id_ = other.id_; 111 returnType_ = other.returnType_; 112 constructor_ = other.constructor_; 113 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 114 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 115 for (size_t i = 0; i < paramCounter_; i++) { 116 (*paramsType_)[i] = other.GetParametersType()[i]; 117 } 118 } 119 kind_ = other.kind_; 120 return *this; 121 } 122 IsCommonStub()123 bool IsCommonStub() const 124 { 125 return (GetTargetKind() == TargetKind::COMMON_STUB); 126 } 127 IsRuntimeVAStub()128 bool IsRuntimeVAStub() const 129 { 130 return (GetTargetKind() == TargetKind::RUNTIME_STUB_VARARGS); 131 } 132 IsRuntimeStub()133 bool IsRuntimeStub() const 134 { 135 return (GetTargetKind() == TargetKind::RUNTIME_STUB); 136 } 137 IsRuntimeNGCStub()138 bool IsRuntimeNGCStub() const 139 { 140 return (GetTargetKind() == TargetKind::RUNTIME_STUB_NO_GC); 141 } 142 IsOptimizedStub()143 bool IsOptimizedStub() const 144 { 145 return (GetTargetKind() == TargetKind::OPTIMIZED_STUB); 146 } 147 IsOptimizedFastCallStub()148 bool IsOptimizedFastCallStub() const 149 { 150 return (GetTargetKind() == TargetKind::OPTIMIZED_FAST_CALL_STUB); 151 } 152 IsBCDebuggerStub()153 bool IsBCDebuggerStub() const 154 { 155 return (GetTargetKind() == TargetKind::BYTECODE_DEBUGGER_HANDLER); 156 } 157 IsStub()158 bool IsStub() const 159 { 160 TargetKind targetKind = GetTargetKind(); 161 return TargetKind::STUB_BEGIN <= targetKind && targetKind < TargetKind::STUB_END; 162 } 163 IsBCStub()164 bool IsBCStub() const 165 { 166 TargetKind targetKind = GetTargetKind(); 167 return TargetKind::BCHANDLER_BEGIN <= targetKind && targetKind < TargetKind::BCHANDLER_END; 168 } 169 IsBuiltinsStub()170 bool IsBuiltinsStub() const 171 { 172 return (GetTargetKind() == TargetKind::BUILTINS_STUB); 173 } 174 IsBuiltinsWithArgvStub()175 bool IsBuiltinsWithArgvStub() const 176 { 177 return (GetTargetKind() == TargetKind::BUILTINS_WITH_ARGV_STUB); 178 } 179 IsBCHandlerStub()180 bool IsBCHandlerStub() const 181 { 182 return (GetTargetKind() == TargetKind::BYTECODE_HANDLER); 183 } 184 IsDeoptStub()185 bool IsDeoptStub() const 186 { 187 return (GetTargetKind() == TargetKind::DEOPT_STUB); 188 } 189 SetParameters(VariableType * paramsType)190 void SetParameters(VariableType *paramsType) 191 { 192 if (paramCounter_ > 0 && paramsType_ == nullptr) { 193 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 194 for (size_t i = 0; i < paramCounter_; i++) { 195 (*paramsType_)[i] = paramsType[i]; 196 } 197 } 198 } 199 GetParametersType()200 VariableType *GetParametersType() const 201 { 202 if (paramsType_ != nullptr) { 203 return paramsType_->data(); 204 } else { 205 return nullptr; 206 } 207 } 208 GetParametersCount()209 size_t GetParametersCount() const 210 { 211 return paramCounter_; 212 } 213 GetReturnType()214 VariableType GetReturnType() const 215 { 216 return returnType_; 217 } 218 GetArgumentsOrder()219 ArgumentsOrder GetArgumentsOrder() const 220 { 221 return order_; 222 } 223 IsVariadicArgs()224 bool IsVariadicArgs() const 225 { 226 return VariadicArgsBit::Decode(kind_); 227 } 228 SetVariadicArgs(bool variable)229 void SetVariadicArgs(bool variable) 230 { 231 VariadicArgsBit::Set<uint64_t>(variable, &kind_); 232 } 233 SetTailCall(bool tailCall)234 void SetTailCall(bool tailCall) 235 { 236 TailCallBit::Set<uint64_t>(tailCall, &kind_); 237 } 238 GetTailCall()239 bool GetTailCall() const 240 { 241 return TailCallBit::Decode(kind_); 242 } 243 SetGCLeafFunction(bool value)244 void SetGCLeafFunction(bool value) 245 { 246 GCLeafFunctionBit::Set<uint64_t>(value, &kind_); 247 } 248 GetGCLeafFunction()249 bool GetGCLeafFunction() const 250 { 251 return GCLeafFunctionBit::Decode(kind_); 252 } 253 GetTargetKind()254 TargetKind GetTargetKind() const 255 { 256 return TargetKindBit::Decode(kind_); 257 } 258 SetTargetKind(TargetKind kind)259 void SetTargetKind(TargetKind kind) 260 { 261 TargetKindBit::Set<uint64_t>(kind, &kind_); 262 } 263 GetCallConv()264 CallConv GetCallConv() const 265 { 266 return CallConvBit::Decode(kind_); 267 } 268 SetCallConv(CallConv cc)269 void SetCallConv(CallConv cc) 270 { 271 CallConvBit::Set<uint64_t>(cc, &kind_); 272 } 273 GetName()274 const std::string &GetName() const 275 { 276 return name_; 277 } 278 SetName(const std::string & str)279 void SetName(const std::string &str) 280 { 281 name_ = str; 282 } 283 SetConstructor(TargetConstructor ctor)284 void SetConstructor(TargetConstructor ctor) 285 { 286 constructor_ = ctor; 287 } 288 GetConstructor()289 TargetConstructor GetConstructor() const 290 { 291 return constructor_; 292 } 293 HasConstructor()294 bool HasConstructor() const 295 { 296 return constructor_ != nullptr; 297 } 298 GetID()299 int GetID() const 300 { 301 return id_; 302 } 303 SetID(int id)304 void SetID(int id) 305 { 306 id_ = id; 307 } 308 309 private: 310 std::string name_; 311 size_t paramCounter_ {0}; 312 int id_ {-1}; 313 ArgumentsOrder order_ {ArgumentsOrder::DEFAULT_ORDER}; 314 VariableType returnType_ {VariableType::VOID()}; 315 std::unique_ptr<std::vector<VariableType>> paramsType_ {nullptr}; 316 TargetConstructor constructor_ {nullptr}; 317 uint64_t kind_ {0}; 318 }; 319 320 #define EXPLICIT_CALL_SIGNATURE_LIST(V) \ 321 V(Add) \ 322 V(Sub) \ 323 V(Mul) \ 324 V(MulGCTest) \ 325 V(Div) \ 326 V(Mod) \ 327 V(TypeOf) \ 328 V(Equal) \ 329 V(NotEqual) \ 330 V(StrictEqual) \ 331 V(StrictNotEqual) \ 332 V(Less) \ 333 V(LessEq) \ 334 V(Greater) \ 335 V(GreaterEq) \ 336 V(Shl) \ 337 V(Shr) \ 338 V(Ashr) \ 339 V(And) \ 340 V(Or) \ 341 V(Xor) \ 342 V(Instanceof) \ 343 V(Inc) \ 344 V(Dec) \ 345 V(Neg) \ 346 V(Not) \ 347 V(ToBoolean) \ 348 V(SetPropertyByName) \ 349 V(DeprecatedSetPropertyByName) \ 350 V(SetPropertyByNameWithOwn) \ 351 V(SetPropertyByValue) \ 352 V(DeprecatedSetPropertyByValue) \ 353 V(TryLdGlobalByName) \ 354 V(TryStGlobalByName) \ 355 V(LdGlobalVar) \ 356 V(StGlobalVar) \ 357 V(SetPropertyByValueWithOwn) \ 358 V(GetPropertyByName) \ 359 V(DeprecatedGetPropertyByName) \ 360 V(GetPropertyByIndex) \ 361 V(SetPropertyByIndex) \ 362 V(SetPropertyByIndexWithOwn) \ 363 V(GetPropertyByValue) \ 364 V(DeprecatedGetPropertyByValue) \ 365 V(TryLoadICByName) \ 366 V(TryLoadICByValue) \ 367 V(TryStoreICByName) \ 368 V(TryStoreICByValue) \ 369 V(SetValueWithBarrier) \ 370 V(NewLexicalEnv) \ 371 V(GetUnmapedArgs) \ 372 V(NewThisObjectChecked) \ 373 V(ConstructorCheck) \ 374 V(CreateEmptyArray) \ 375 V(CreateArrayWithBuffer) \ 376 V(NewJSObject) \ 377 V(GetTaggedArrayPtrTest) \ 378 V(BytecodeHandler) \ 379 V(Builtins) \ 380 V(BuiltinsWithArgv) \ 381 V(BytecodeDebuggerHandler) \ 382 V(CallRuntime) \ 383 V(AsmInterpreterEntry) \ 384 V(GeneratorReEnterAsmInterp) \ 385 V(CallRuntimeWithArgv) \ 386 V(OptimizedCallAndPushUndefined) \ 387 V(OptimizedFastCallAndPushUndefined) \ 388 V(PushCallArg0AndDispatch) \ 389 V(PushCallArgsAndDispatchNative) \ 390 V(PushCallArg1AndDispatch) \ 391 V(PushCallArgs2AndDispatch) \ 392 V(PushCallArgs3AndDispatch) \ 393 V(PushCallRangeAndDispatch) \ 394 V(PushCallRangeAndDispatchNative) \ 395 V(PushCallThisRangeAndDispatch) \ 396 V(PushCallThisArg0AndDispatch) \ 397 V(PushCallThisArg1AndDispatch) \ 398 V(PushCallThisArgs2AndDispatch) \ 399 V(PushCallThisArgs3AndDispatch) \ 400 V(PushCallNewAndDispatchNative) \ 401 V(PushCallNewAndDispatch) \ 402 V(CallGetter) \ 403 V(CallSetter) \ 404 V(CallContainersArgs3) \ 405 V(JSCallWithArgV) \ 406 V(JSFastCallWithArgV) \ 407 V(JSFastCallWithArgVAndPushUndefined) \ 408 V(JSCallWithArgVAndPushUndefined) \ 409 V(ResumeRspAndDispatch) \ 410 V(ResumeRspAndReturn) \ 411 V(ResumeCaughtFrameAndDispatch) \ 412 V(ResumeUncaughtFrameAndReturn) \ 413 V(StringsAreEquals) \ 414 V(BigIntEquals) \ 415 V(DebugPrint) \ 416 V(DebugPrintInstruction) \ 417 V(Comment) \ 418 V(ProfileCall) \ 419 V(ProfileDefineClass) \ 420 V(ProfileCreateObject) \ 421 V(ProfileOpType) \ 422 V(ProfileObjLayout) \ 423 V(FatalPrint) \ 424 V(GetActualArgvNoGC) \ 425 V(InsertOldToNewRSet) \ 426 V(DoubleToInt) \ 427 V(FloatMod) \ 428 V(FloatSqrt) \ 429 V(FloatCos) \ 430 V(FloatSin) \ 431 V(FloatACos) \ 432 V(FloatATan) \ 433 V(FloatFloor) \ 434 V(FindElementWithCache) \ 435 V(MarkingBarrier) \ 436 V(StoreBarrier) \ 437 V(CallArg0) \ 438 V(CallArg1) \ 439 V(CallArgs2) \ 440 V(CallArgs3) \ 441 V(CallThisRange) \ 442 V(CallRange) \ 443 V(JSCall) \ 444 V(JSOptimizedCall) \ 445 V(JSOptimizedFastCall) \ 446 V(JSFunctionEntry) \ 447 V(OptimizedFastCallEntry) \ 448 V(JSProxyCallInternalWithArgV) \ 449 V(CreateArrayFromList) \ 450 V(JSObjectGetMethod) \ 451 V(JsProxyCallInternal) \ 452 V(JsBoundCallInternal) \ 453 V(DeoptHandlerAsm) \ 454 V(JSCallNew) \ 455 V(CallOptimized) \ 456 V(TimeClip) \ 457 V(SetDateValues) \ 458 V(CallReturnWithArgv) \ 459 V(StartCallTimer) \ 460 V(EndCallTimer) \ 461 TEST_STUB_SIGNATRUE_LIST(V) 462 463 #define DECL_CALL_SIGNATURE(name) \ 464 class name##CallSignature final { \ 465 public: \ 466 static void Initialize(CallSignature *descriptor); \ 467 }; 468 EXPLICIT_CALL_SIGNATURE_LIST(DECL_CALL_SIGNATURE) 469 470 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 471 #define DEF_CALL_SIGNATURE(name) \ 472 void name##CallSignature::Initialize([[maybe_unused]] CallSignature *callSign) 473 } // namespace panda::ecmascript::kungfu 474 #endif // ECMASCRIPT_COMPILER_CALL_SIGNATURE_H 475