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 25#include "libpandabase/macros.h" 26#include "libpandabase/utils/bit_field.h" 27 28namespace panda::ecmascript::kungfu { 29class Circuit; 30 31enum class ArgumentsOrder { 32 DEFAULT_ORDER, // Push Arguments in stack from right -> left 33}; 34 35class CallSignature { 36public: 37 using TargetConstructor = std::function<void *(void *)>; 38 enum class TargetKind : uint8_t { 39 COMMON_STUB = 0, 40 RUNTIME_STUB, 41 RUNTIME_STUB_VARARGS, 42 RUNTIME_STUB_NO_GC, 43 ASM_CALL_BARRIER_STUB, 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 BYTECODE_JIT_PROFILE_HANDLER, 52 JSFUNCTION, 53 BUILTINS_STUB, 54 BUILTINS_WITH_ARGV_STUB, 55 BASELINE_STUB, 56 57 STUB_BEGIN = COMMON_STUB, 58 STUB_END = BYTECODE_HANDLER, 59 BCHANDLER_BEGIN = BYTECODE_HANDLER, 60 BCHANDLER_END = JSFUNCTION 61 }; 62 enum class CallConv: uint8_t { 63 CCallConv = 0, 64 GHCCallConv = 1, 65 WebKitJSCallConv = 2, 66 }; 67 // ParamAttr only works for LLVM backend. 68 enum class ParamAttr: uint8_t { 69 NoAttr = 0, 70 Dead 71 }; 72 static constexpr size_t TARGET_KIND_BIT_LENGTH = 5; 73 static constexpr size_t CALL_CONV_BIT_LENGTH = 2; 74 using TargetKindBit = panda::BitField<TargetKind, 0, TARGET_KIND_BIT_LENGTH>; 75 using CallConvBit = TargetKindBit::NextField<CallConv, CALL_CONV_BIT_LENGTH>; 76 using VariadicArgsBit = CallConvBit::NextField<bool, 1>; 77 using TailCallBit = VariadicArgsBit::NextField<bool, 1>; 78 using GCLeafFunctionBit = TailCallBit::NextField<bool, 1>; 79 80 CallSignature(std::string name, int flags, size_t paramCounter, ArgumentsOrder order, 81 VariableType returnType) 82 : name_(name), paramCounter_(paramCounter), order_(order), returnType_(returnType) 83 { 84 SetTargetKind(TargetKind::COMMON_STUB); 85 SetCallConv(CallSignature::CallConv::CCallConv); 86 SetTailCall(false); 87 SetGCLeafFunction(false); 88 SetVariadicArgs(flags); 89 } 90 91 CallSignature(std::string name, int flags, ArgumentsOrder order, VariableType returnType, 92 std::initializer_list<VariableType> params) 93 : CallSignature(std::move(name), flags, params.size(), order, returnType) 94 { 95 paramsType_ = std::make_unique<std::vector<VariableType>>(params); 96 } 97 98 CallSignature() = default; 99 100 ~CallSignature() = default; 101 102 CallSignature(CallSignature const &other) 103 { 104 name_ = other.name_; 105 paramCounter_ = other.paramCounter_; 106 order_ = other.order_; 107 id_ = other.id_; 108 returnType_ = other.returnType_; 109 constructor_ = other.constructor_; 110 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 111 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 112 for (size_t i = 0; i < paramCounter_; i++) { 113 (*paramsType_)[i] = other.GetParametersType()[i]; 114 } 115 } 116 kind_ = other.kind_; 117 } 118 119 CallSignature &operator=(CallSignature const &other) 120 { 121 name_ = other.name_; 122 paramCounter_ = other.paramCounter_; 123 order_ = other.order_; 124 id_ = other.id_; 125 returnType_ = other.returnType_; 126 constructor_ = other.constructor_; 127 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 128 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 129 for (size_t i = 0; i < paramCounter_; i++) { 130 (*paramsType_)[i] = other.GetParametersType()[i]; 131 } 132 } 133 kind_ = other.kind_; 134 return *this; 135 } 136 137 bool IsCommonStub() const 138 { 139 return (GetTargetKind() == TargetKind::COMMON_STUB); 140 } 141 142 bool IsRuntimeVAStub() const 143 { 144 return (GetTargetKind() == TargetKind::RUNTIME_STUB_VARARGS); 145 } 146 147 bool IsRuntimeStub() const 148 { 149 return (GetTargetKind() == TargetKind::RUNTIME_STUB); 150 } 151 152 bool IsASMCallBarrierStub() const 153 { 154 return (GetTargetKind() == TargetKind::ASM_CALL_BARRIER_STUB); 155 } 156 157 bool IsRuntimeNGCStub() const 158 { 159 return (GetTargetKind() == TargetKind::RUNTIME_STUB_NO_GC); 160 } 161 162 bool IsOptimizedStub() const 163 { 164 return (GetTargetKind() == TargetKind::OPTIMIZED_STUB); 165 } 166 167 bool IsOptimizedFastCallStub() const 168 { 169 return (GetTargetKind() == TargetKind::OPTIMIZED_FAST_CALL_STUB); 170 } 171 172 bool IsBCDebuggerStub() const 173 { 174 return (GetTargetKind() == TargetKind::BYTECODE_DEBUGGER_HANDLER); 175 } 176 177 bool IsStub() const 178 { 179 TargetKind targetKind = GetTargetKind(); 180 return TargetKind::STUB_BEGIN <= targetKind && targetKind < TargetKind::STUB_END; 181 } 182 183 bool IsBCStub() const 184 { 185 TargetKind targetKind = GetTargetKind(); 186 return TargetKind::BCHANDLER_BEGIN <= targetKind && targetKind < TargetKind::BCHANDLER_END; 187 } 188 189 bool IsBuiltinsStub() const 190 { 191 return (GetTargetKind() == TargetKind::BUILTINS_STUB); 192 } 193 194 bool IsBuiltinsWithArgvStub() const 195 { 196 return (GetTargetKind() == TargetKind::BUILTINS_WITH_ARGV_STUB); 197 } 198 199 bool IsBCHandlerStub() const 200 { 201 return (GetTargetKind() == TargetKind::BYTECODE_HANDLER); 202 } 203 204 bool IsDeoptStub() const 205 { 206 return (GetTargetKind() == TargetKind::DEOPT_STUB); 207 } 208 209 bool IsBaselineStub() const 210 { 211 return (GetTargetKind() == TargetKind::BASELINE_STUB); 212 } 213 214 void SetParameters(VariableType *paramsType) 215 { 216 if (paramCounter_ > 0 && paramsType_ == nullptr) { 217 paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_); 218 for (size_t i = 0; i < paramCounter_; i++) { 219 (*paramsType_)[i] = paramsType[i]; 220 } 221 } 222 } 223 224 VariableType *GetParametersType() const 225 { 226 if (paramsType_ != nullptr) { 227 return paramsType_->data(); 228 } else { 229 return nullptr; 230 } 231 } 232 233 void SetParamAttr(std::vector<ParamAttr> &¶mAttr) 234 { 235 if (paramCounter_ > 0 && paramsAttr_ == nullptr) { 236 paramsAttr_ = std::make_unique<std::vector<ParamAttr>>(paramAttr); 237 } 238 } 239 240 std::vector<ParamAttr> *GetParamAttr() const 241 { 242 if (paramsAttr_ != nullptr) { 243 return paramsAttr_.get(); 244 } else { 245 return nullptr; 246 } 247 } 248 249 size_t GetParametersCount() const 250 { 251 return paramCounter_; 252 } 253 254 VariableType GetReturnType() const 255 { 256 return returnType_; 257 } 258 259 ArgumentsOrder GetArgumentsOrder() const 260 { 261 return order_; 262 } 263 264 bool IsVariadicArgs() const 265 { 266 return VariadicArgsBit::Decode(kind_); 267 } 268 269 void SetVariadicArgs(bool variable) 270 { 271 VariadicArgsBit::Set<uint64_t>(variable, &kind_); 272 } 273 274 void SetTailCall(bool tailCall) 275 { 276 TailCallBit::Set<uint64_t>(tailCall, &kind_); 277 } 278 279 bool GetTailCall() const 280 { 281 return TailCallBit::Decode(kind_); 282 } 283 284 void SetGCLeafFunction(bool value) 285 { 286 GCLeafFunctionBit::Set<uint64_t>(value, &kind_); 287 } 288 289 bool GetGCLeafFunction() const 290 { 291 return GCLeafFunctionBit::Decode(kind_); 292 } 293 294 TargetKind GetTargetKind() const 295 { 296 return TargetKindBit::Decode(kind_); 297 } 298 299 void SetTargetKind(TargetKind kind) 300 { 301 TargetKindBit::Set<uint64_t>(kind, &kind_); 302 } 303 304 CallConv GetCallConv() const 305 { 306 return CallConvBit::Decode(kind_); 307 } 308 309 void SetCallConv(CallConv cc) 310 { 311 CallConvBit::Set<uint64_t>(cc, &kind_); 312 } 313 314 const std::string &GetName() const 315 { 316 return name_; 317 } 318 319 void SetName(const std::string &str) 320 { 321 name_ = str; 322 } 323 324 void SetConstructor(TargetConstructor ctor) 325 { 326 constructor_ = ctor; 327 } 328 329 TargetConstructor GetConstructor() const 330 { 331 return constructor_; 332 } 333 334 bool HasConstructor() const 335 { 336 return constructor_ != nullptr; 337 } 338 339 int GetID() const 340 { 341 return id_; 342 } 343 344 void SetID(int id) 345 { 346 id_ = id; 347 } 348 349private: 350 std::string name_; 351 size_t paramCounter_ {0}; 352 int id_ {-1}; 353 ArgumentsOrder order_ {ArgumentsOrder::DEFAULT_ORDER}; 354 VariableType returnType_ {VariableType::VOID()}; 355 std::unique_ptr<std::vector<VariableType>> paramsType_ {nullptr}; 356 std::unique_ptr<std::vector<ParamAttr>> paramsAttr_ {nullptr}; 357 TargetConstructor constructor_ {nullptr}; 358 uint64_t kind_ {0}; 359}; 360 361#define EXPLICIT_CALL_SIGNATURE_LIST(V) \ 362 V(Add) \ 363 V(Sub) \ 364 V(Mul) \ 365 V(MulGCTest) \ 366 V(Div) \ 367 V(Mod) \ 368 V(TypeOf) \ 369 V(Equal) \ 370 V(NotEqual) \ 371 V(StrictEqual) \ 372 V(StrictNotEqual) \ 373 V(Less) \ 374 V(LessEq) \ 375 V(Greater) \ 376 V(GreaterEq) \ 377 V(Shl) \ 378 V(Shr) \ 379 V(Ashr) \ 380 V(And) \ 381 V(Or) \ 382 V(Xor) \ 383 V(Instanceof) \ 384 V(Inc) \ 385 V(Dec) \ 386 V(Neg) \ 387 V(Not) \ 388 V(ToBooleanTrue) \ 389 V(ToBooleanFalse) \ 390 V(SetPropertyByName) \ 391 V(DeprecatedSetPropertyByName) \ 392 V(SetPropertyByNameWithOwn) \ 393 V(SetPropertyByValue) \ 394 V(DeprecatedSetPropertyByValue) \ 395 V(TryLdGlobalByName) \ 396 V(TryStGlobalByName) \ 397 V(LdGlobalVar) \ 398 V(StGlobalVar) \ 399 V(StOwnByIndex) \ 400 V(StOwnByValue) \ 401 V(StOwnByName) \ 402 V(StOwnByValueWithNameSet) \ 403 V(StOwnByNameWithNameSet) \ 404 V(StObjByIndex) \ 405 V(LdObjByIndex) \ 406 V(SetPropertyByValueWithOwn) \ 407 V(GetPropertyByName) \ 408 V(DeprecatedGetPropertyByName) \ 409 V(GetPropertyByIndex) \ 410 V(SetPropertyByIndex) \ 411 V(SetPropertyByIndexWithOwn) \ 412 V(GetPropertyByValue) \ 413 V(DeprecatedGetPropertyByValue) \ 414 V(TryLoadICByName) \ 415 V(TryLoadICByValue) \ 416 V(TryStoreICByName) \ 417 V(TryStoreICByValue) \ 418 V(SetValueWithBarrier) \ 419 V(SetNonSValueWithBarrier) \ 420 V(SetValueWithEdenBarrier) \ 421 V(SetNonSValueWithEdenBarrier) \ 422 V(SetSValueWithBarrier) \ 423 V(NewLexicalEnv) \ 424 V(CopyRestArgs) \ 425 V(GetUnmappedArgs) \ 426 V(GetCallSpreadArgs) \ 427 V(NewThisObjectChecked) \ 428 V(ConstructorCheck) \ 429 V(CreateEmptyArray) \ 430 V(CreateArrayWithBuffer) \ 431 V(NewJSObject) \ 432 V(GetTaggedArrayPtrTest) \ 433 V(BytecodeHandler) \ 434 V(Builtins) \ 435 V(BuiltinsWithArgv) \ 436 V(BytecodeDebuggerHandler) \ 437 V(CallRuntime) \ 438 V(AsmInterpreterEntry) \ 439 V(CallArg0AndCheckToBaseline) \ 440 V(CallArg1AndCheckToBaseline) \ 441 V(CallArgs2AndCheckToBaseline) \ 442 V(CallArgs3AndCheckToBaseline) \ 443 V(CallThisArg0AndCheckToBaseline) \ 444 V(CallThisArg1AndCheckToBaseline) \ 445 V(CallThisArgs2AndCheckToBaseline) \ 446 V(CallThisArgs3AndCheckToBaseline) \ 447 V(CallRangeAndCheckToBaseline) \ 448 V(CallNewAndCheckToBaseline) \ 449 V(SuperCallAndCheckToBaseline) \ 450 V(CallThisRangeAndCheckToBaseline) \ 451 V(GeneratorReEnterAsmInterp) \ 452 V(CallRuntimeWithArgv) \ 453 V(OptimizedCallAndPushArgv) \ 454 V(OptimizedFastCallAndPushArgv) \ 455 V(AOTCallToAsmInterBridge) \ 456 V(FastCallToAsmInterBridge) \ 457 V(PushCallArg0AndDispatch) \ 458 V(PushCallArgsAndDispatchNative) \ 459 V(PushCallArg1AndDispatch) \ 460 V(PushCallArgs2AndDispatch) \ 461 V(PushCallArgs3AndDispatch) \ 462 V(PushCallRangeAndDispatch) \ 463 V(PushCallRangeAndDispatchNative) \ 464 V(PushCallThisRangeAndDispatch) \ 465 V(PushCallThisArg0AndDispatch) \ 466 V(PushCallThisArg1AndDispatch) \ 467 V(PushCallThisArgs2AndDispatch) \ 468 V(PushCallThisArgs3AndDispatch) \ 469 V(PushCallNewAndDispatchNative) \ 470 V(PushNewTargetAndDispatchNative) \ 471 V(PushCallNewAndDispatch) \ 472 V(PushSuperCallAndDispatch) \ 473 V(CallGetter) \ 474 V(CallSetter) \ 475 V(CallContainersArgs2) \ 476 V(CallContainersArgs3) \ 477 V(JSCallWithArgV) \ 478 V(JSFastCallWithArgV) \ 479 V(JSFastCallWithArgVAndPushArgv) \ 480 V(JSCallWithArgVAndPushArgv) \ 481 V(SuperCallWithArgV) \ 482 V(ResumeRspAndDispatch) \ 483 V(ResumeRspAndReturn) \ 484 V(ResumeRspAndReturnBaseline) \ 485 V(ResumeCaughtFrameAndDispatch) \ 486 V(ResumeUncaughtFrameAndReturn) \ 487 V(ResumeRspAndRollback) \ 488 V(StringsAreEquals) \ 489 V(BigIntEquals) \ 490 V(BigIntSameValueZero) \ 491 V(CallBigIntAsIntN) \ 492 V(CallBigIntAsUintN) \ 493 V(Dump) \ 494 V(DebugDump) \ 495 V(DumpWithHint) \ 496 V(DebugDumpWithHint) \ 497 V(DebugPrint) \ 498 V(DebugPrintCustom) \ 499 V(DebugPrintInstruction) \ 500 V(DebugOsrEntry) \ 501 V(Comment) \ 502 V(FatalPrint) \ 503 V(FatalPrintCustom) \ 504 V(GetActualArgvNoGC) \ 505 V(InsertNewToEdenRSet) \ 506 V(InsertOldToNewRSet) \ 507 V(InsertLocalToShareRSet) \ 508 V(SetBitAtomic) \ 509 V(DoubleToInt) \ 510 V(DoubleToLength) \ 511 V(FloatMod) \ 512 V(FloatAcos) \ 513 V(FloatAcosh) \ 514 V(FloatAsin) \ 515 V(FloatAsinh) \ 516 V(FloatAtan) \ 517 V(FloatAtan2) \ 518 V(FloatAtanh) \ 519 V(FloatCos) \ 520 V(FloatCosh) \ 521 V(FloatSin) \ 522 V(FloatSinh) \ 523 V(FloatTan) \ 524 V(FloatTanh) \ 525 V(FloatTrunc) \ 526 V(FloatLog) \ 527 V(FloatLog2) \ 528 V(FloatLog10) \ 529 V(FloatLog1p) \ 530 V(FloatExp) \ 531 V(FloatExpm1) \ 532 V(FloatCbrt) \ 533 V(FloatClz32) \ 534 V(FloatFloor) \ 535 V(FloatPow) \ 536 V(FloatCeil) \ 537 V(CallDateNow) \ 538 V(NumberIsFinite) \ 539 V(FindElementWithCache) \ 540 V(UpdateFieldType) \ 541 V(MarkingBarrier) \ 542 V(MarkingBarrierWithEden) \ 543 V(SharedGCMarkingBarrier) \ 544 V(StoreBarrier) \ 545 V(CallArg0) \ 546 V(CallArg1) \ 547 V(CallArgs2) \ 548 V(CallArgs3) \ 549 V(CallThisRange) \ 550 V(CallRange) \ 551 V(JSCall) \ 552 V(JSOptimizedCall) \ 553 V(JSOptimizedFastCall) \ 554 V(JSFunctionEntry) \ 555 V(OptimizedFastCallEntry) \ 556 V(JSProxyCallInternalWithArgV) \ 557 V(CreateArrayFromList) \ 558 V(JSObjectGetMethod) \ 559 V(JsProxyCallInternal) \ 560 V(JsBoundCallInternal) \ 561 V(DeoptHandlerAsm) \ 562 V(JSCallNew) \ 563 V(CallOptimized) \ 564 V(TimeClip) \ 565 V(SetDateValues) \ 566 V(CallReturnWithArgv) \ 567 V(StartCallTimer) \ 568 V(EndCallTimer) \ 569 V(GetSingleCharCodeByIndex) \ 570 V(CreateStringBySingleCharCode) \ 571 V(FastStringEqual) \ 572 V(FastStringAdd) \ 573 V(DeleteObjectProperty) \ 574 V(Getpropiterator) \ 575 V(Getnextpropname) \ 576 V(CreateJSSetIterator) \ 577 V(CreateJSMapIterator) \ 578 V(JSMapGet) \ 579 V(JSMapHas) \ 580 V(JSMapKeys) \ 581 V(JSMapValues) \ 582 V(JSSetHas) \ 583 V(JSSetAdd) \ 584 V(JSMapDelete) \ 585 V(JSSetDelete) \ 586 V(CreateJSTypedArrayEntries) \ 587 V(CreateJSTypedArrayKeys) \ 588 V(CreateJSTypedArrayValues) \ 589 V(JSSetEntries) \ 590 V(JSHClassFindProtoTransitions) \ 591 V(NumberHelperStringToDouble) \ 592 V(GetStringToListCacheArray) \ 593 V(FastArraySort) \ 594 V(FastArraySortString) \ 595 V(StringToNumber) \ 596 V(StringGetStart) \ 597 V(StringGetEnd) \ 598 V(ArrayTrim) \ 599 V(OptimizedFastJmp) \ 600 V(CopyTypedArrayBuffer) \ 601 V(CallArg0AndDispatchFromBaseline) \ 602 V(CallArg1AndDispatchFromBaseline) \ 603 V(CallArgs2AndDispatchFromBaseline) \ 604 V(CallArgs3AndDispatchFromBaseline) \ 605 V(CallThisArg0AndDispatchFromBaseline) \ 606 V(CallThisArg1AndDispatchFromBaseline) \ 607 V(CallThisArgs2AndDispatchFromBaseline) \ 608 V(CallThisArgs3AndDispatchFromBaseline) \ 609 V(CallRangeAndDispatchFromBaseline) \ 610 V(CallNewAndDispatchFromBaseline) \ 611 V(SuperCallAndDispatchFromBaseline) \ 612 V(CallThisRangeAndDispatchFromBaseline) \ 613 V(CallArg0AndCheckToBaselineFromBaseline) \ 614 V(CallArg1AndCheckToBaselineFromBaseline) \ 615 V(CallArgs2AndCheckToBaselineFromBaseline) \ 616 V(CallArgs3AndCheckToBaselineFromBaseline) \ 617 V(CallThisArg0AndCheckToBaselineFromBaseline) \ 618 V(CallThisArg1AndCheckToBaselineFromBaseline) \ 619 V(CallThisArgs2AndCheckToBaselineFromBaseline) \ 620 V(CallThisArgs3AndCheckToBaselineFromBaseline) \ 621 V(CallRangeAndCheckToBaselineFromBaseline) \ 622 V(CallNewAndCheckToBaselineFromBaseline) \ 623 V(SuperCallAndCheckToBaselineFromBaseline) \ 624 V(CallThisRangeAndCheckToBaselineFromBaseline) \ 625 V(SameValue) \ 626 V(GetBaselineBuiltinFp) \ 627 V(StringIteratorNext) \ 628 V(Definefunc) \ 629 V(DefineField) \ 630 V(ConvertCharToInt32) \ 631 V(ConvertCharToDouble) \ 632 V(ASMFastWriteBarrier) \ 633 V(ASMWriteBarrierWithEden) \ 634 V(VerifyBarrier) \ 635 V(IsFastRegExp) 636 637#define DECL_CALL_SIGNATURE(name) \ 638class name##CallSignature final { \ 639 public: \ 640 static void Initialize(CallSignature *descriptor); \ 641 }; 642EXPLICIT_CALL_SIGNATURE_LIST(DECL_CALL_SIGNATURE) 643 644// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 645#define DEF_CALL_SIGNATURE(name) \ 646 void name##CallSignature::Initialize([[maybe_unused]] CallSignature *callSign) 647} // namespace panda::ecmascript::kungfu 648#endif // ECMASCRIPT_COMPILER_CALL_SIGNATURE_H 649