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