1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_INTERFACE_DESCRIPTORS_H_ 6 #define V8_INTERFACE_DESCRIPTORS_H_ 7 8 #include <memory> 9 10 #include "src/assembler.h" 11 #include "src/globals.h" 12 #include "src/isolate.h" 13 #include "src/macro-assembler.h" 14 15 namespace v8 { 16 namespace internal { 17 18 #define INTERFACE_DESCRIPTOR_LIST(V) \ 19 V(CppBuiltinAdaptor) \ 20 V(CEntry1ArgvOnStack) \ 21 V(Allocate) \ 22 V(Void) \ 23 V(ContextOnly) \ 24 V(NoContext) \ 25 V(Load) \ 26 V(LoadWithVector) \ 27 V(LoadGlobal) \ 28 V(LoadGlobalWithVector) \ 29 V(Store) \ 30 V(StoreWithVector) \ 31 V(StoreTransition) \ 32 V(StoreGlobal) \ 33 V(StoreGlobalWithVector) \ 34 V(FastNewFunctionContext) \ 35 V(FastNewObject) \ 36 V(RecordWrite) \ 37 V(TypeConversion) \ 38 V(TypeConversionStackParameter) \ 39 V(Typeof) \ 40 V(CallFunction) \ 41 V(CallVarargs) \ 42 V(CallForwardVarargs) \ 43 V(CallWithSpread) \ 44 V(CallWithArrayLike) \ 45 V(CallTrampoline) \ 46 V(ConstructStub) \ 47 V(ConstructVarargs) \ 48 V(ConstructForwardVarargs) \ 49 V(ConstructWithSpread) \ 50 V(ConstructWithArrayLike) \ 51 V(JSTrampoline) \ 52 V(Abort) \ 53 V(AllocateHeapNumber) \ 54 V(ArrayConstructor) \ 55 V(ArrayNoArgumentConstructor) \ 56 V(ArraySingleArgumentConstructor) \ 57 V(ArrayNArgumentsConstructor) \ 58 V(Compare) \ 59 V(BinaryOp) \ 60 V(StringAt) \ 61 V(StringSubstring) \ 62 V(GetProperty) \ 63 V(ArgumentAdaptor) \ 64 V(ApiCallback) \ 65 V(ApiGetter) \ 66 V(GrowArrayElements) \ 67 V(NewArgumentsElements) \ 68 V(InterpreterDispatch) \ 69 V(InterpreterPushArgsThenCall) \ 70 V(InterpreterPushArgsThenConstruct) \ 71 V(InterpreterCEntry1) \ 72 V(InterpreterCEntry2) \ 73 V(ResumeGenerator) \ 74 V(FrameDropperTrampoline) \ 75 V(RunMicrotasks) \ 76 V(WasmGrowMemory) \ 77 V(CloneObjectWithVector) \ 78 BUILTIN_LIST_TFS(V) 79 80 class V8_EXPORT_PRIVATE CallInterfaceDescriptorData { 81 public: 82 enum Flag { 83 kNoFlags = 0u, 84 kNoContext = 1u << 0, 85 }; 86 typedef base::Flags<Flag> Flags; 87 88 CallInterfaceDescriptorData() = default; 89 90 // A copy of the passed in registers and param_representations is made 91 // and owned by the CallInterfaceDescriptorData. 92 93 void InitializePlatformSpecific(int register_parameter_count, 94 const Register* registers); 95 96 // if machine_types is null, then an array of size 97 // (return_count + parameter_count) will be created with 98 // MachineType::AnyTagged() for each member. 99 // 100 // if machine_types is not null, then it should be of the size 101 // (return_count + parameter_count). Those members of the parameter array will 102 // be initialized from {machine_types}, and the rest initialized to 103 // MachineType::AnyTagged(). 104 void InitializePlatformIndependent(Flags flags, int return_count, 105 int parameter_count, 106 const MachineType* machine_types, 107 int machine_types_length); 108 109 void Reset(); 110 IsInitialized()111 bool IsInitialized() const { 112 return IsInitializedPlatformSpecific() && 113 IsInitializedPlatformIndependent(); 114 } 115 flags()116 Flags flags() const { return flags_; } return_count()117 int return_count() const { return return_count_; } param_count()118 int param_count() const { return param_count_; } register_param_count()119 int register_param_count() const { return register_param_count_; } register_param(int index)120 Register register_param(int index) const { return register_params_[index]; } register_params()121 Register* register_params() const { return register_params_; } return_type(int index)122 MachineType return_type(int index) const { 123 DCHECK_LT(index, return_count_); 124 return machine_types_[index]; 125 } param_type(int index)126 MachineType param_type(int index) const { 127 DCHECK_LT(index, param_count_); 128 return machine_types_[return_count_ + index]; 129 } 130 RestrictAllocatableRegisters(const Register * registers,int num)131 void RestrictAllocatableRegisters(const Register* registers, int num) { 132 DCHECK_EQ(allocatable_registers_, 0); 133 for (int i = 0; i < num; ++i) { 134 allocatable_registers_ |= registers[i].bit(); 135 } 136 DCHECK_GT(NumRegs(allocatable_registers_), 0); 137 } 138 allocatable_registers()139 RegList allocatable_registers() const { return allocatable_registers_; } 140 141 private: IsInitializedPlatformSpecific()142 bool IsInitializedPlatformSpecific() const { 143 const bool initialized = 144 register_param_count_ >= 0 && register_params_ != nullptr; 145 // Platform-specific initialization happens before platform-independent. 146 return initialized; 147 } IsInitializedPlatformIndependent()148 bool IsInitializedPlatformIndependent() const { 149 const bool initialized = 150 return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr; 151 // Platform-specific initialization happens before platform-independent. 152 return initialized; 153 } 154 155 #ifdef DEBUG 156 bool AllStackParametersAreTagged() const; 157 #endif // DEBUG 158 159 int register_param_count_ = -1; 160 int return_count_ = -1; 161 int param_count_ = -1; 162 Flags flags_ = kNoFlags; 163 164 // Specifying the set of registers that could be used by the register 165 // allocator. Currently, it's only used by RecordWrite code stub. 166 RegList allocatable_registers_ = 0; 167 168 // |registers_params_| defines registers that are used for parameter passing. 169 // |machine_types_| defines machine types for resulting values and incomping 170 // parameters. 171 // Both arrays are allocated dynamically by the InterfaceDescriptor and 172 // freed on destruction. This is because static arrays cause creation of 173 // runtime static initializers which we don't want. 174 Register* register_params_ = nullptr; 175 MachineType* machine_types_ = nullptr; 176 177 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); 178 }; 179 180 class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic { 181 public: 182 enum Key { 183 #define DEF_ENUM(name, ...) name, 184 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM) 185 #undef DEF_ENUM 186 NUMBER_OF_DESCRIPTORS 187 }; 188 189 static void InitializeOncePerProcess(); 190 static void TearDown(); 191 call_descriptor_data(CallDescriptors::Key key)192 static CallInterfaceDescriptorData* call_descriptor_data( 193 CallDescriptors::Key key) { 194 return &call_descriptor_data_[key]; 195 } 196 GetKey(const CallInterfaceDescriptorData * data)197 static Key GetKey(const CallInterfaceDescriptorData* data) { 198 ptrdiff_t index = data - call_descriptor_data_; 199 DCHECK_LE(0, index); 200 DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS); 201 return static_cast<CallDescriptors::Key>(index); 202 } 203 204 private: 205 static CallInterfaceDescriptorData 206 call_descriptor_data_[NUMBER_OF_DESCRIPTORS]; 207 }; 208 209 class V8_EXPORT_PRIVATE CallInterfaceDescriptor { 210 public: 211 typedef CallInterfaceDescriptorData::Flags Flags; 212 CallInterfaceDescriptor()213 CallInterfaceDescriptor() : data_(nullptr) {} ~CallInterfaceDescriptor()214 virtual ~CallInterfaceDescriptor() {} 215 CallInterfaceDescriptor(CallDescriptors::Key key)216 CallInterfaceDescriptor(CallDescriptors::Key key) 217 : data_(CallDescriptors::call_descriptor_data(key)) {} 218 flags()219 Flags flags() const { return data()->flags(); } 220 HasContextParameter()221 bool HasContextParameter() const { 222 return (flags() & CallInterfaceDescriptorData::kNoContext) == 0; 223 } 224 GetReturnCount()225 int GetReturnCount() const { return data()->return_count(); } 226 GetReturnType(int index)227 MachineType GetReturnType(int index) const { 228 DCHECK_LT(index, data()->return_count()); 229 return data()->return_type(index); 230 } 231 GetParameterCount()232 int GetParameterCount() const { return data()->param_count(); } 233 GetRegisterParameterCount()234 int GetRegisterParameterCount() const { 235 return data()->register_param_count(); 236 } 237 GetStackParameterCount()238 int GetStackParameterCount() const { 239 return data()->param_count() - data()->register_param_count(); 240 } 241 GetRegisterParameter(int index)242 Register GetRegisterParameter(int index) const { 243 return data()->register_param(index); 244 } 245 GetParameterType(int index)246 MachineType GetParameterType(int index) const { 247 DCHECK_LT(index, data()->param_count()); 248 return data()->param_type(index); 249 } 250 allocatable_registers()251 RegList allocatable_registers() const { 252 return data()->allocatable_registers(); 253 } 254 255 static const Register ContextRegister(); 256 257 const char* DebugName() const; 258 259 protected: data()260 const CallInterfaceDescriptorData* data() const { return data_; } 261 InitializePlatformSpecific(CallInterfaceDescriptorData * data)262 virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) { 263 UNREACHABLE(); 264 } 265 InitializePlatformIndependent(CallInterfaceDescriptorData * data)266 virtual void InitializePlatformIndependent( 267 CallInterfaceDescriptorData* data) { 268 // Default descriptor configuration: one result, all parameters are passed 269 // in registers and all parameters have MachineType::AnyTagged() type. 270 data->InitializePlatformIndependent(CallInterfaceDescriptorData::kNoFlags, 271 1, data->register_param_count(), 272 nullptr, 0); 273 } 274 275 // Initializes |data| using the platform dependent default set of registers. 276 // It is intended to be used for TurboFan stubs when particular set of 277 // registers does not matter. 278 static void DefaultInitializePlatformSpecific( 279 CallInterfaceDescriptorData* data, int register_parameter_count); 280 281 // Initializes |data| using the platform dependent default set of registers 282 // for JavaScript-compatible calling convention. 283 // It is intended to be used for TurboFan stubs being called with JavaScript 284 // linkage + additional parameters on registers and stack. 285 static void JSDefaultInitializePlatformSpecific( 286 CallInterfaceDescriptorData* data, int non_js_register_parameter_count); 287 288 private: 289 // {CallDescriptors} is allowed to call the private {Initialize} method. 290 friend class CallDescriptors; 291 292 const CallInterfaceDescriptorData* data_; 293 Initialize(CallInterfaceDescriptorData * data)294 void Initialize(CallInterfaceDescriptorData* data) { 295 // The passed pointer should be a modifiable pointer to our own data. 296 DCHECK_EQ(data, data_); 297 DCHECK(!data->IsInitialized()); 298 InitializePlatformSpecific(data); 299 InitializePlatformIndependent(data); 300 DCHECK(data->IsInitialized()); 301 } 302 }; 303 304 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 305 public: \ 306 explicit name() : base(key()) {} \ 307 static inline CallDescriptors::Key key(); 308 309 #if defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS) 310 // TODO(jgruber,v8:6666): Keep kRootRegister free unconditionally. 311 constexpr int kMaxBuiltinRegisterParams = 4; 312 #else 313 constexpr int kMaxBuiltinRegisterParams = 5; 314 #endif 315 316 #define DECLARE_DEFAULT_DESCRIPTOR(name, base) \ 317 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 318 protected: \ 319 static const int kRegisterParams = \ 320 kParameterCount > kMaxBuiltinRegisterParams ? kMaxBuiltinRegisterParams \ 321 : kParameterCount; \ 322 static const int kStackParams = kParameterCount - kRegisterParams; \ 323 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \ 324 override { \ 325 DefaultInitializePlatformSpecific(data, kRegisterParams); \ 326 } \ 327 void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \ 328 override { \ 329 data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \ 330 kParameterCount, nullptr, 0); \ 331 } \ 332 name(CallDescriptors::Key key) : base(key) {} \ 333 \ 334 public: 335 336 #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base, \ 337 non_js_reg_parameters_count) \ 338 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 339 protected: \ 340 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \ 341 override { \ 342 JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \ 343 } \ 344 name(CallDescriptors::Key key) : base(key) {} \ 345 \ 346 public: 347 348 #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \ 349 static constexpr int kDescriptorFlags = \ 350 CallInterfaceDescriptorData::kNoFlags; \ 351 static constexpr int kReturnCount = return_count; \ 352 enum ParameterIndices { \ 353 __dummy = -1, /* to be able to pass zero arguments */ \ 354 ##__VA_ARGS__, \ 355 \ 356 kParameterCount, \ 357 kContext = kParameterCount /* implicit parameter */ \ 358 }; 359 360 #define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \ 361 static constexpr int kDescriptorFlags = \ 362 CallInterfaceDescriptorData::kNoContext; \ 363 static constexpr int kReturnCount = return_count; \ 364 enum ParameterIndices { \ 365 __dummy = -1, /* to be able to pass zero arguments */ \ 366 ##__VA_ARGS__, \ 367 \ 368 kParameterCount \ 369 }; 370 371 #define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__) 372 373 #define DEFINE_PARAMETERS_NO_CONTEXT(...) \ 374 DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(1, ##__VA_ARGS__) 375 376 #define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \ 377 void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \ 378 override { \ 379 MachineType machine_types[] = {__VA_ARGS__}; \ 380 static_assert( \ 381 kReturnCount + kParameterCount == arraysize(machine_types), \ 382 "Parameter names definition is not consistent with parameter types"); \ 383 data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \ 384 kParameterCount, machine_types, \ 385 arraysize(machine_types)); \ 386 } 387 388 #define DEFINE_PARAMETER_TYPES(...) \ 389 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \ 390 ##__VA_ARGS__) 391 392 #define DEFINE_JS_PARAMETERS(...) \ 393 static constexpr int kDescriptorFlags = \ 394 CallInterfaceDescriptorData::kNoFlags; \ 395 static constexpr int kReturnCount = 1; \ 396 enum ParameterIndices { \ 397 kTarget, \ 398 kNewTarget, \ 399 kActualArgumentsCount, \ 400 ##__VA_ARGS__, \ 401 \ 402 kParameterCount, \ 403 kContext = kParameterCount /* implicit parameter */ \ 404 }; 405 406 #define DEFINE_JS_PARAMETER_TYPES(...) \ 407 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */ \ 408 MachineType::AnyTagged(), /* kNewTarget */ \ 409 MachineType::Int32(), /* kActualArgumentsCount */ \ 410 ##__VA_ARGS__) 411 412 #define DECLARE_DESCRIPTOR(name, base) \ 413 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 414 protected: \ 415 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \ 416 name(CallDescriptors::Key key) : base(key) {} \ 417 \ 418 public: 419 420 class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor { 421 public: 422 DEFINE_PARAMETERS() 423 DEFINE_PARAMETER_TYPES() 424 DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor) 425 }; 426 427 class AllocateDescriptor : public CallInterfaceDescriptor { 428 public: 429 DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize) 430 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1 431 MachineType::Int32()) // kRequestedSize 432 DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor) 433 }; 434 435 // This descriptor defines the JavaScript calling convention that can be used 436 // by stubs: target, new.target, argc (not including the receiver) and context 437 // are passed in registers while receiver and the rest of the JS arguments are 438 // passed on the stack. 439 class JSTrampolineDescriptor : public CallInterfaceDescriptor { 440 public: 441 DEFINE_JS_PARAMETERS() 442 DEFINE_JS_PARAMETER_TYPES() 443 444 DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor, 445 CallInterfaceDescriptor, 0) 446 }; 447 448 class ContextOnlyDescriptor : public CallInterfaceDescriptor { 449 public: 450 DEFINE_PARAMETERS() 451 DEFINE_PARAMETER_TYPES() 452 DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor) 453 }; 454 455 class NoContextDescriptor : public CallInterfaceDescriptor { 456 public: 457 DEFINE_PARAMETERS_NO_CONTEXT() 458 DEFINE_PARAMETER_TYPES() 459 DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor) 460 }; 461 462 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs. 463 class LoadDescriptor : public CallInterfaceDescriptor { 464 public: 465 DEFINE_PARAMETERS(kReceiver, kName, kSlot) 466 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 467 MachineType::AnyTagged(), // kName 468 MachineType::TaggedSigned()) // kSlot 469 DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor) 470 471 static const Register ReceiverRegister(); 472 static const Register NameRegister(); 473 static const Register SlotRegister(); 474 }; 475 476 class LoadGlobalDescriptor : public CallInterfaceDescriptor { 477 public: DEFINE_PARAMETERS(kName,kSlot)478 DEFINE_PARAMETERS(kName, kSlot) 479 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName 480 MachineType::TaggedSigned()) // kSlot 481 DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor) 482 483 static const Register NameRegister() { 484 return LoadDescriptor::NameRegister(); 485 } 486 SlotRegister()487 static const Register SlotRegister() { 488 return LoadDescriptor::SlotRegister(); 489 } 490 }; 491 492 class StoreDescriptor : public CallInterfaceDescriptor { 493 public: 494 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot) 495 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 496 MachineType::AnyTagged(), // kName 497 MachineType::AnyTagged(), // kValue 498 MachineType::TaggedSigned()) // kSlot 499 DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor) 500 501 static const Register ReceiverRegister(); 502 static const Register NameRegister(); 503 static const Register ValueRegister(); 504 static const Register SlotRegister(); 505 506 #if V8_TARGET_ARCH_IA32 507 static const bool kPassLastArgsOnStack = true; 508 #else 509 static const bool kPassLastArgsOnStack = false; 510 #endif 511 512 // Pass value and slot through the stack. 513 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0; 514 }; 515 516 class StoreTransitionDescriptor : public StoreDescriptor { 517 public: 518 DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector) 519 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 520 MachineType::AnyTagged(), // kName 521 MachineType::AnyTagged(), // kMap 522 MachineType::AnyTagged(), // kValue 523 MachineType::TaggedSigned(), // kSlot 524 MachineType::AnyTagged()) // kVector 525 DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor) 526 527 static const Register MapRegister(); 528 static const Register SlotRegister(); 529 static const Register VectorRegister(); 530 531 // Pass value, slot and vector through the stack. 532 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; 533 }; 534 535 class StoreWithVectorDescriptor : public StoreDescriptor { 536 public: 537 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector) 538 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 539 MachineType::AnyTagged(), // kName 540 MachineType::AnyTagged(), // kValue 541 MachineType::TaggedSigned(), // kSlot 542 MachineType::AnyTagged()) // kVector 543 DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor) 544 545 static const Register VectorRegister(); 546 547 // Pass value, slot and vector through the stack. 548 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; 549 }; 550 551 class StoreGlobalDescriptor : public CallInterfaceDescriptor { 552 public: 553 DEFINE_PARAMETERS(kName, kValue, kSlot) 554 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName 555 MachineType::AnyTagged(), // kValue 556 MachineType::TaggedSigned()) // kSlot 557 DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor) 558 559 static const bool kPassLastArgsOnStack = 560 StoreDescriptor::kPassLastArgsOnStack; 561 // Pass value and slot through the stack. 562 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0; 563 NameRegister()564 static const Register NameRegister() { 565 return StoreDescriptor::NameRegister(); 566 } 567 ValueRegister()568 static const Register ValueRegister() { 569 return StoreDescriptor::ValueRegister(); 570 } 571 SlotRegister()572 static const Register SlotRegister() { 573 return StoreDescriptor::SlotRegister(); 574 } 575 }; 576 577 class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor { 578 public: DEFINE_PARAMETERS(kName,kValue,kSlot,kVector)579 DEFINE_PARAMETERS(kName, kValue, kSlot, kVector) 580 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName 581 MachineType::AnyTagged(), // kValue 582 MachineType::TaggedSigned(), // kSlot 583 MachineType::AnyTagged()) // kVector 584 DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor) 585 586 static const Register VectorRegister() { 587 return StoreWithVectorDescriptor::VectorRegister(); 588 } 589 590 // Pass value, slot and vector through the stack. 591 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; 592 }; 593 594 class LoadWithVectorDescriptor : public LoadDescriptor { 595 public: 596 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector) 597 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 598 MachineType::AnyTagged(), // kName 599 MachineType::TaggedSigned(), // kSlot 600 MachineType::AnyTagged()) // kVector 601 DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor) 602 603 static const Register VectorRegister(); 604 }; 605 606 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor { 607 public: DEFINE_PARAMETERS(kName,kSlot,kVector)608 DEFINE_PARAMETERS(kName, kSlot, kVector) 609 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName 610 MachineType::TaggedSigned(), // kSlot 611 MachineType::AnyTagged()) // kVector 612 DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor) 613 614 static const Register VectorRegister() { 615 return LoadWithVectorDescriptor::VectorRegister(); 616 } 617 }; 618 619 class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor { 620 public: 621 DEFINE_PARAMETERS(kScopeInfo, kSlots) 622 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kScopeInfo 623 MachineType::Int32()) // kSlots 624 DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor) 625 626 static const Register ScopeInfoRegister(); 627 static const Register SlotsRegister(); 628 }; 629 630 class FastNewObjectDescriptor : public CallInterfaceDescriptor { 631 public: 632 DEFINE_PARAMETERS(kTarget, kNewTarget) 633 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 634 MachineType::AnyTagged()) // kNewTarget 635 DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor) 636 static const Register TargetRegister(); 637 static const Register NewTargetRegister(); 638 }; 639 640 class RecordWriteDescriptor final : public CallInterfaceDescriptor { 641 public: 642 DEFINE_PARAMETERS(kObject, kSlot, kIsolate, kRememberedSet, kFPMode) 643 DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject 644 MachineType::Pointer(), // kSlot 645 MachineType::Pointer(), // kIsolate 646 MachineType::TaggedSigned(), // kRememberedSet 647 MachineType::TaggedSigned()) // kFPMode 648 649 DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor) 650 }; 651 652 class TypeConversionDescriptor final : public CallInterfaceDescriptor { 653 public: 654 DEFINE_PARAMETERS(kArgument) 655 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged()) 656 DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor) 657 658 static const Register ArgumentRegister(); 659 }; 660 661 class TypeConversionStackParameterDescriptor final 662 : public CallInterfaceDescriptor { 663 public: 664 DEFINE_PARAMETERS(kArgument) 665 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged()) 666 DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor, 667 CallInterfaceDescriptor) 668 }; 669 670 class GetPropertyDescriptor final : public CallInterfaceDescriptor { 671 public: 672 DEFINE_PARAMETERS(kObject, kKey) 673 DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor) 674 }; 675 676 class TypeofDescriptor : public CallInterfaceDescriptor { 677 public: 678 DEFINE_PARAMETERS(kObject) 679 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged()) 680 DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor) 681 }; 682 683 class CallTrampolineDescriptor : public CallInterfaceDescriptor { 684 public: 685 DEFINE_PARAMETERS(kFunction, kActualArgumentsCount) 686 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction 687 MachineType::Int32()) // kActualArgumentsCount 688 DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor) 689 }; 690 691 class CallVarargsDescriptor : public CallInterfaceDescriptor { 692 public: 693 DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsList, 694 kArgumentsLength) 695 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 696 MachineType::Int32(), // kActualArgumentsCount 697 MachineType::AnyTagged(), // kArgumentsList 698 MachineType::Int32()) // kArgumentsLength 699 DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor) 700 }; 701 702 class CallForwardVarargsDescriptor : public CallInterfaceDescriptor { 703 public: 704 DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kStartIndex) 705 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 706 MachineType::Int32(), // kActualArgumentsCount 707 MachineType::Int32()) // kStartIndex 708 DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor) 709 }; 710 711 class CallWithSpreadDescriptor : public CallInterfaceDescriptor { 712 public: 713 DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread) 714 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 715 MachineType::Int32(), // kArgumentsCount 716 MachineType::AnyTagged()) // kSpread 717 DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor) 718 }; 719 720 class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor { 721 public: 722 DEFINE_PARAMETERS(kTarget, kArgumentsList) 723 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 724 MachineType::AnyTagged()) // kArgumentsList 725 DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor) 726 }; 727 728 class ConstructVarargsDescriptor : public CallInterfaceDescriptor { 729 public: 730 DEFINE_JS_PARAMETERS(kArgumentsList, kArgumentsLength) 731 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged(), // kArgumentsList 732 MachineType::Int32()) // kArgumentsLength 733 DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor) 734 }; 735 736 class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor { 737 public: 738 DEFINE_JS_PARAMETERS(kStartIndex) 739 DEFINE_JS_PARAMETER_TYPES(MachineType::Int32()) 740 DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor) 741 }; 742 743 class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor { 744 public: 745 DEFINE_JS_PARAMETERS(kSpread) 746 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged()) 747 DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor) 748 }; 749 750 class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor { 751 public: 752 DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList) 753 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget 754 MachineType::AnyTagged(), // kNewTarget 755 MachineType::AnyTagged()) // kArgumentsList 756 DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor) 757 }; 758 759 // TODO(ishell): consider merging this with ArrayConstructorDescriptor 760 class ConstructStubDescriptor : public CallInterfaceDescriptor { 761 public: 762 DEFINE_JS_PARAMETERS(kAllocationSite) 763 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged()); 764 765 // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match 766 DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor) 767 }; 768 769 class CallFunctionDescriptor : public CallInterfaceDescriptor { 770 public: 771 DEFINE_PARAMETERS(kTarget) 772 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged()) 773 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor) 774 }; 775 776 class AbortDescriptor : public CallInterfaceDescriptor { 777 public: 778 DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId) 779 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged()) 780 DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor) 781 }; 782 783 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor { 784 public: 785 DEFINE_PARAMETERS_NO_CONTEXT() 786 DEFINE_PARAMETER_TYPES() 787 DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor) 788 }; 789 790 class ArrayConstructorDescriptor : public CallInterfaceDescriptor { 791 public: 792 DEFINE_JS_PARAMETERS(kAllocationSite) 793 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged()); 794 795 DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor, 796 CallInterfaceDescriptor, 1) 797 }; 798 799 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor { 800 public: 801 // This descriptor declares only register arguments while respective number 802 // of JS arguments stay on the expression stack. 803 // The ArrayNArgumentsConstructor builtin does not access stack arguments 804 // directly it just forwards them to the runtime function. 805 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount) 806 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction, 807 MachineType::AnyTagged(), // kAllocationSite 808 MachineType::Int32()) // kActualArgumentsCount 809 DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor, 810 CallInterfaceDescriptor) 811 }; 812 813 class ArrayNoArgumentConstructorDescriptor 814 : public ArrayNArgumentsConstructorDescriptor { 815 public: 816 // This descriptor declares same register arguments as the parent 817 // ArrayNArgumentsConstructorDescriptor and it declares indices for 818 // JS arguments passed on the expression stack. 819 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount, 820 kFunctionParameter) 821 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction 822 MachineType::AnyTagged(), // kAllocationSite 823 MachineType::Int32(), // kActualArgumentsCount 824 MachineType::AnyTagged()) // kFunctionParameter 825 DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor, 826 ArrayNArgumentsConstructorDescriptor) 827 }; 828 829 class ArraySingleArgumentConstructorDescriptor 830 : public ArrayNArgumentsConstructorDescriptor { 831 public: 832 // This descriptor declares same register arguments as the parent 833 // ArrayNArgumentsConstructorDescriptor and it declares indices for 834 // JS arguments passed on the expression stack. 835 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount, 836 kFunctionParameter, kArraySizeSmiParameter) 837 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction 838 MachineType::AnyTagged(), // kAllocationSite 839 MachineType::Int32(), // kActualArgumentsCount 840 MachineType::AnyTagged(), // kFunctionParameter 841 MachineType::AnyTagged()) // kArraySizeSmiParameter 842 DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor, 843 ArrayNArgumentsConstructorDescriptor) 844 }; 845 846 class CompareDescriptor : public CallInterfaceDescriptor { 847 public: 848 DEFINE_PARAMETERS(kLeft, kRight) 849 DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor) 850 }; 851 852 853 class BinaryOpDescriptor : public CallInterfaceDescriptor { 854 public: 855 DEFINE_PARAMETERS(kLeft, kRight) 856 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor) 857 }; 858 859 // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt 860 // as they all have the same interface. 861 class StringAtDescriptor final : public CallInterfaceDescriptor { 862 public: 863 DEFINE_PARAMETERS(kReceiver, kPosition) 864 // TODO(turbofan): Return untagged value here. 865 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(), // result 1 866 MachineType::AnyTagged(), // kReceiver 867 MachineType::IntPtr()) // kPosition 868 DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor) 869 }; 870 871 class StringSubstringDescriptor final : public CallInterfaceDescriptor { 872 public: 873 DEFINE_PARAMETERS(kString, kFrom, kTo) 874 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kString 875 MachineType::IntPtr(), // kFrom 876 MachineType::IntPtr()) // kTo 877 878 // TODO(turbofan): Allow builtins to return untagged values. 879 DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor) 880 }; 881 882 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { 883 public: 884 DEFINE_JS_PARAMETERS(kExpectedArgumentsCount) 885 DEFINE_JS_PARAMETER_TYPES(MachineType::Int32()) 886 DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor) 887 }; 888 889 class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor { 890 public: 891 DEFINE_JS_PARAMETERS(kCFunction) 892 DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer()) 893 DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor, 894 CallInterfaceDescriptor, 1) 895 }; 896 897 class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor { 898 public: 899 DEFINE_PARAMETERS(kArity, // register argument 900 kCFunction, // register argument 901 kPadding, // stack argument 1 (just padding) 902 kArgcSmi, // stack argument 2 903 kTargetCopy, // stack argument 3 904 kNewTargetCopy) // stack argument 4 905 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kArity 906 MachineType::Pointer(), // kCFunction 907 MachineType::AnyTagged(), // kPadding 908 MachineType::AnyTagged(), // kArgcSmi 909 MachineType::AnyTagged(), // kTargetCopy 910 MachineType::AnyTagged()) // kNewTargetCopy 911 DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor) 912 }; 913 914 class ApiCallbackDescriptor : public CallInterfaceDescriptor { 915 public: 916 DEFINE_PARAMETERS_NO_CONTEXT(kTargetContext, kCallData, kHolder, 917 kApiFunctionAddress) 918 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTargetContext 919 MachineType::AnyTagged(), // kCallData 920 MachineType::AnyTagged(), // kHolder 921 MachineType::Pointer()) // kApiFunctionAddress 922 DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor) 923 }; 924 925 class ApiGetterDescriptor : public CallInterfaceDescriptor { 926 public: 927 DEFINE_PARAMETERS(kReceiver, kHolder, kCallback) 928 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver 929 MachineType::AnyTagged(), // kHolder 930 MachineType::AnyTagged()) // kCallback 931 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor) 932 933 static const Register ReceiverRegister(); 934 static const Register HolderRegister(); 935 static const Register CallbackRegister(); 936 }; 937 938 // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor. 939 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor { 940 public: 941 DEFINE_PARAMETERS(kObject, kKey) 942 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kObject 943 MachineType::AnyTagged()) // kKey 944 DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor) 945 946 static const Register ObjectRegister(); 947 static const Register KeyRegister(); 948 }; 949 950 class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor { 951 public: 952 DEFINE_PARAMETERS(kFrame, kLength, kMappedCount) 953 DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kFrame 954 MachineType::TaggedSigned(), // kLength 955 MachineType::TaggedSigned()) // kMappedCount 956 DECLARE_DESCRIPTOR(NewArgumentsElementsDescriptor, CallInterfaceDescriptor) 957 }; 958 959 class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor 960 : public CallInterfaceDescriptor { 961 public: 962 DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray, 963 kDispatchTable) 964 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kAccumulator 965 MachineType::IntPtr(), // kBytecodeOffset 966 MachineType::AnyTagged(), // kBytecodeArray 967 MachineType::IntPtr()) // kDispatchTable 968 DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor) 969 }; 970 971 class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor { 972 public: 973 DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction) 974 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments 975 MachineType::Pointer(), // kFirstArgument 976 MachineType::AnyTagged()) // kFunction 977 DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor, 978 CallInterfaceDescriptor) 979 }; 980 981 class InterpreterPushArgsThenConstructDescriptor 982 : public CallInterfaceDescriptor { 983 public: 984 DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor, 985 kFeedbackElement, kFirstArgument) 986 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments 987 MachineType::AnyTagged(), // kNewTarget 988 MachineType::AnyTagged(), // kConstructor 989 MachineType::AnyTagged(), // kFeedbackElement 990 MachineType::Pointer()) // kFirstArgument 991 DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor, 992 CallInterfaceDescriptor) 993 }; 994 995 class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor { 996 public: 997 DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument, 998 kFunctionEntry) 999 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1 1000 MachineType::Int32(), // kNumberOfArguments 1001 MachineType::Pointer(), // kFirstArgument 1002 MachineType::Pointer()) // kFunctionEntry 1003 DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor) 1004 }; 1005 1006 class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor { 1007 public: 1008 DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument, 1009 kFunctionEntry) 1010 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1 1011 MachineType::AnyTagged(), // result 2 1012 MachineType::Int32(), // kNumberOfArguments 1013 MachineType::Pointer(), // kFirstArgument 1014 MachineType::Pointer()) // kFunctionEntry 1015 DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor) 1016 }; 1017 1018 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor { 1019 public: 1020 DEFINE_PARAMETERS(kValue, kGenerator) 1021 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue 1022 MachineType::AnyTagged()) // kGenerator 1023 DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor) 1024 }; 1025 1026 class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor { 1027 public: 1028 DEFINE_PARAMETERS(kRestartFp) 1029 DEFINE_PARAMETER_TYPES(MachineType::Pointer()) 1030 DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor) 1031 }; 1032 1033 class RunMicrotasksDescriptor final : public CallInterfaceDescriptor { 1034 public: 1035 DEFINE_PARAMETERS() 1036 DECLARE_DEFAULT_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor) 1037 }; 1038 1039 class WasmGrowMemoryDescriptor final : public CallInterfaceDescriptor { 1040 public: 1041 DEFINE_PARAMETERS_NO_CONTEXT(kNumPages) 1042 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(), // result 1 1043 MachineType::Int32()) // kNumPages 1044 DECLARE_DESCRIPTOR(WasmGrowMemoryDescriptor, CallInterfaceDescriptor) 1045 }; 1046 1047 class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor { 1048 public: 1049 DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector) 1050 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1 1051 MachineType::AnyTagged(), // kSource 1052 MachineType::TaggedSigned(), // kFlags 1053 MachineType::TaggedSigned(), // kSlot 1054 MachineType::AnyTagged()) // kVector 1055 DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor) 1056 }; 1057 1058 #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...) \ 1059 class Name##Descriptor : public CallInterfaceDescriptor { \ 1060 public: \ 1061 DEFINE_PARAMETERS(__VA_ARGS__) \ 1062 DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \ 1063 }; 1064 BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR) 1065 #undef DEFINE_TFS_BUILTIN_DESCRIPTOR 1066 1067 #undef DECLARE_DEFAULT_DESCRIPTOR 1068 #undef DECLARE_DESCRIPTOR_WITH_BASE 1069 #undef DECLARE_DESCRIPTOR 1070 #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR 1071 #undef DEFINE_RESULT_AND_PARAMETERS 1072 #undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT 1073 #undef DEFINE_PARAMETERS 1074 #undef DEFINE_PARAMETERS_NO_CONTEXT 1075 #undef DEFINE_RESULT_AND_PARAMETER_TYPES 1076 #undef DEFINE_PARAMETER_TYPES 1077 #undef DEFINE_JS_PARAMETERS 1078 #undef DEFINE_JS_PARAMETER_TYPES 1079 1080 // We define the association between CallDescriptors::Key and the specialized 1081 // descriptor here to reduce boilerplate and mistakes. 1082 #define DEF_KEY(name, ...) \ 1083 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; } 1084 INTERFACE_DESCRIPTOR_LIST(DEF_KEY) 1085 #undef DEF_KEY 1086 } // namespace internal 1087 } // namespace v8 1088 1089 #endif // V8_INTERFACE_DESCRIPTORS_H_ 1090