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_CODEGEN_INTERFACE_DESCRIPTORS_H_
6 #define V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
7 
8 #include <memory>
9 
10 #include "src/codegen/machine-type.h"
11 #include "src/codegen/register-arch.h"
12 #include "src/codegen/tnode.h"
13 #include "src/common/globals.h"
14 #include "src/execution/isolate.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 #define TORQUE_BUILTIN_LIST_TFC(V)                                            \
20   BUILTIN_LIST_FROM_TORQUE(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
21                            IGNORE_BUILTIN, IGNORE_BUILTIN)
22 
23 #define INTERFACE_DESCRIPTOR_LIST(V)  \
24   V(Abort)                            \
25   V(Allocate)                         \
26   V(AllocateHeapNumber)               \
27   V(ApiCallback)                      \
28   V(ApiGetter)                        \
29   V(ArgumentsAdaptor)                 \
30   V(ArrayConstructor)                 \
31   V(ArrayNArgumentsConstructor)       \
32   V(ArrayNoArgumentConstructor)       \
33   V(ArraySingleArgumentConstructor)   \
34   V(AsyncFunctionStackParameter)      \
35   V(BigIntToI64)                      \
36   V(BigIntToI32Pair)                  \
37   V(I64ToBigInt)                      \
38   V(I32PairToBigInt)                  \
39   V(BinaryOp)                         \
40   V(CallForwardVarargs)               \
41   V(CallFunctionTemplate)             \
42   V(CallTrampoline)                   \
43   V(CallVarargs)                      \
44   V(CallWithArrayLike)                \
45   V(CallWithSpread)                   \
46   V(CEntry1ArgvOnStack)               \
47   V(CloneObjectWithVector)            \
48   V(Compare)                          \
49   V(ConstructForwardVarargs)          \
50   V(ConstructStub)                    \
51   V(ConstructVarargs)                 \
52   V(ConstructWithArrayLike)           \
53   V(ConstructWithSpread)              \
54   V(ContextOnly)                      \
55   V(CppBuiltinAdaptor)                \
56   V(EphemeronKeyBarrier)              \
57   V(FastNewFunctionContext)           \
58   V(FastNewObject)                    \
59   V(FrameDropperTrampoline)           \
60   V(GetIteratorStackParameter)        \
61   V(GetProperty)                      \
62   V(GrowArrayElements)                \
63   V(InterpreterCEntry1)               \
64   V(InterpreterCEntry2)               \
65   V(InterpreterDispatch)              \
66   V(InterpreterPushArgsThenCall)      \
67   V(InterpreterPushArgsThenConstruct) \
68   V(JSTrampoline)                     \
69   V(Load)                             \
70   V(LoadGlobal)                       \
71   V(LoadGlobalNoFeedback)             \
72   V(LoadNoFeedback)                   \
73   V(LoadGlobalWithVector)             \
74   V(LoadWithVector)                   \
75   V(NewArgumentsElements)             \
76   V(NoContext)                        \
77   V(RecordWrite)                      \
78   V(ResumeGenerator)                  \
79   V(RunMicrotasksEntry)               \
80   V(RunMicrotasks)                    \
81   V(Store)                            \
82   V(StoreGlobal)                      \
83   V(StoreGlobalWithVector)            \
84   V(StoreTransition)                  \
85   V(StoreWithVector)                  \
86   V(StringAt)                         \
87   V(StringAtAsString)                 \
88   V(StringSubstring)                  \
89   V(TypeConversion)                   \
90   V(TypeConversionStackParameter)     \
91   V(Typeof)                           \
92   V(Void)                             \
93   V(WasmAtomicNotify)                 \
94   V(WasmI32AtomicWait32)              \
95   V(WasmI32AtomicWait64)              \
96   V(WasmI64AtomicWait32)              \
97   V(WasmI64AtomicWait64)              \
98   V(WasmMemoryGrow)                   \
99   V(WasmTableInit)                    \
100   V(WasmTableCopy)                    \
101   V(WasmTableGet)                     \
102   V(WasmTableSet)                     \
103   V(WasmThrow)                        \
104   BUILTIN_LIST_TFS(V)                 \
105   TORQUE_BUILTIN_LIST_TFC(V)
106 
107 class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
108  public:
109   enum Flag {
110     kNoFlags = 0u,
111     kNoContext = 1u << 0,
112     // This indicates that the code uses a special frame that does not scan the
113     // stack arguments, e.g. EntryFrame. And this allows the code to use
114     // untagged stack arguments.
115     kNoStackScan = 1u << 1,
116     // In addition to the specified parameters, additional arguments can be
117     // passed on the stack.
118     // This does not indicate if arguments adaption is used or not.
119     kAllowVarArgs = 1u << 2,
120   };
121   using Flags = base::Flags<Flag>;
122 
123   CallInterfaceDescriptorData() = default;
124 
125   // A copy of the passed in registers and param_representations is made
126   // and owned by the CallInterfaceDescriptorData.
127 
128   void InitializePlatformSpecific(int register_parameter_count,
129                                   const Register* registers);
130 
131   // if machine_types is null, then an array of size
132   // (return_count + parameter_count) will be created with
133   // MachineType::AnyTagged() for each member.
134   //
135   // if machine_types is not null, then it should be of the size
136   // (return_count + parameter_count). Those members of the parameter array will
137   // be initialized from {machine_types}, and the rest initialized to
138   // MachineType::AnyTagged().
139   void InitializePlatformIndependent(Flags flags, int return_count,
140                                      int parameter_count,
141                                      const MachineType* machine_types,
142                                      int machine_types_length);
143 
144   void Reset();
145 
IsInitialized()146   bool IsInitialized() const {
147     return IsInitializedPlatformSpecific() &&
148            IsInitializedPlatformIndependent();
149   }
150 
flags()151   Flags flags() const { return flags_; }
return_count()152   int return_count() const { return return_count_; }
param_count()153   int param_count() const { return param_count_; }
register_param_count()154   int register_param_count() const { return register_param_count_; }
register_param(int index)155   Register register_param(int index) const { return register_params_[index]; }
register_params()156   Register* register_params() const { return register_params_; }
return_type(int index)157   MachineType return_type(int index) const {
158     DCHECK_LT(index, return_count_);
159     return machine_types_[index];
160   }
param_type(int index)161   MachineType param_type(int index) const {
162     DCHECK_LT(index, param_count_);
163     return machine_types_[return_count_ + index];
164   }
165 
RestrictAllocatableRegisters(const Register * registers,int num)166   void RestrictAllocatableRegisters(const Register* registers, int num) {
167     DCHECK_EQ(allocatable_registers_, 0);
168     for (int i = 0; i < num; ++i) {
169       allocatable_registers_ |= registers[i].bit();
170     }
171     DCHECK_GT(NumRegs(allocatable_registers_), 0);
172   }
173 
allocatable_registers()174   RegList allocatable_registers() const { return allocatable_registers_; }
175 
176  private:
IsInitializedPlatformSpecific()177   bool IsInitializedPlatformSpecific() const {
178     const bool initialized =
179         (register_param_count_ == 0 && register_params_ == nullptr) ||
180         (register_param_count_ > 0 && register_params_ != nullptr);
181     // Platform-specific initialization happens before platform-independent.
182     return initialized;
183   }
IsInitializedPlatformIndependent()184   bool IsInitializedPlatformIndependent() const {
185     const bool initialized =
186         return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
187     // Platform-specific initialization happens before platform-independent.
188     return initialized;
189   }
190 
191 #ifdef DEBUG
192   bool AllStackParametersAreTagged() const;
193 #endif  // DEBUG
194 
195   int register_param_count_ = -1;
196   int return_count_ = -1;
197   int param_count_ = -1;
198   Flags flags_ = kNoFlags;
199 
200   // Specifying the set of registers that could be used by the register
201   // allocator. Currently, it's only used by RecordWrite code stub.
202   RegList allocatable_registers_ = 0;
203 
204   // |registers_params_| defines registers that are used for parameter passing.
205   // |machine_types_| defines machine types for resulting values and incomping
206   // parameters.
207   // Both arrays are allocated dynamically by the InterfaceDescriptor and
208   // freed on destruction. This is because static arrays cause creation of
209   // runtime static initializers which we don't want.
210   Register* register_params_ = nullptr;
211   MachineType* machine_types_ = nullptr;
212 
213   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
214 };
215 
216 class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
217  public:
218   enum Key {
219 #define DEF_ENUM(name, ...) name,
220     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
221 #undef DEF_ENUM
222         NUMBER_OF_DESCRIPTORS
223   };
224 
225   static void InitializeOncePerProcess();
226   static void TearDown();
227 
call_descriptor_data(CallDescriptors::Key key)228   static CallInterfaceDescriptorData* call_descriptor_data(
229       CallDescriptors::Key key) {
230     return &call_descriptor_data_[key];
231   }
232 
GetKey(const CallInterfaceDescriptorData * data)233   static Key GetKey(const CallInterfaceDescriptorData* data) {
234     ptrdiff_t index = data - call_descriptor_data_;
235     DCHECK_LE(0, index);
236     DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
237     return static_cast<CallDescriptors::Key>(index);
238   }
239 
240  private:
241   static CallInterfaceDescriptorData
242       call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
243 };
244 
245 class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
246  public:
247   using Flags = CallInterfaceDescriptorData::Flags;
248 
CallInterfaceDescriptor()249   CallInterfaceDescriptor() : data_(nullptr) {}
250   virtual ~CallInterfaceDescriptor() = default;
251 
CallInterfaceDescriptor(CallDescriptors::Key key)252   explicit CallInterfaceDescriptor(CallDescriptors::Key key)
253       : data_(CallDescriptors::call_descriptor_data(key)) {}
254 
flags()255   Flags flags() const { return data()->flags(); }
256 
HasContextParameter()257   bool HasContextParameter() const {
258     return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
259   }
260 
AllowVarArgs()261   bool AllowVarArgs() const {
262     return flags() & CallInterfaceDescriptorData::kAllowVarArgs;
263   }
264 
GetReturnCount()265   int GetReturnCount() const { return data()->return_count(); }
266 
GetReturnType(int index)267   MachineType GetReturnType(int index) const {
268     DCHECK_LT(index, data()->return_count());
269     return data()->return_type(index);
270   }
271 
GetParameterCount()272   int GetParameterCount() const { return data()->param_count(); }
273 
GetRegisterParameterCount()274   int GetRegisterParameterCount() const {
275     return data()->register_param_count();
276   }
277 
GetStackParameterCount()278   int GetStackParameterCount() const {
279     return data()->param_count() - data()->register_param_count();
280   }
281 
GetRegisterParameter(int index)282   Register GetRegisterParameter(int index) const {
283     return data()->register_param(index);
284   }
285 
GetParameterType(int index)286   MachineType GetParameterType(int index) const {
287     DCHECK_LT(index, data()->param_count());
288     return data()->param_type(index);
289   }
290 
allocatable_registers()291   RegList allocatable_registers() const {
292     return data()->allocatable_registers();
293   }
294 
295   static const Register ContextRegister();
296 
297   const char* DebugName() const;
298 
299   bool operator==(const CallInterfaceDescriptor& other) const {
300     return data() == other.data();
301   }
302 
303  protected:
data()304   const CallInterfaceDescriptorData* data() const { return data_; }
305 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)306   virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
307     UNREACHABLE();
308   }
309 
InitializePlatformIndependent(CallInterfaceDescriptorData * data)310   virtual void InitializePlatformIndependent(
311       CallInterfaceDescriptorData* data) {
312     // Default descriptor configuration: one result, all parameters are passed
313     // in registers and all parameters have MachineType::AnyTagged() type.
314     data->InitializePlatformIndependent(CallInterfaceDescriptorData::kNoFlags,
315                                         1, data->register_param_count(),
316                                         nullptr, 0);
317   }
318 
319   // Initializes |data| using the platform dependent default set of registers.
320   // It is intended to be used for TurboFan stubs when particular set of
321   // registers does not matter.
322   static void DefaultInitializePlatformSpecific(
323       CallInterfaceDescriptorData* data, int register_parameter_count);
324 
325   // Initializes |data| using the platform dependent default set of registers
326   // for JavaScript-compatible calling convention.
327   // It is intended to be used for TurboFan stubs being called with JavaScript
328   // linkage + additional parameters on registers and stack.
329   static void JSDefaultInitializePlatformSpecific(
330       CallInterfaceDescriptorData* data, int non_js_register_parameter_count);
331 
332   // Checks if float parameters are not assigned invalid registers.
CheckFloatingPointParameters(CallInterfaceDescriptorData * data)333   bool CheckFloatingPointParameters(CallInterfaceDescriptorData* data) {
334     for (int i = 0; i < data->register_param_count(); i++) {
335       if (IsFloatingPoint(data->param_type(i).representation())) {
336         if (!IsValidFloatParameterRegister(data->register_param(i))) {
337           return false;
338         }
339       }
340     }
341     return true;
342   }
343 
344   bool IsValidFloatParameterRegister(Register reg);
345 
346  private:
347   // {CallDescriptors} is allowed to call the private {Initialize} method.
348   friend class CallDescriptors;
349 
350   const CallInterfaceDescriptorData* data_;
351 
Initialize(CallInterfaceDescriptorData * data)352   void Initialize(CallInterfaceDescriptorData* data) {
353     // The passed pointer should be a modifiable pointer to our own data.
354     DCHECK_EQ(data, data_);
355     DCHECK(!data->IsInitialized());
356     InitializePlatformSpecific(data);
357     InitializePlatformIndependent(data);
358     DCHECK(data->IsInitialized());
359     DCHECK(CheckFloatingPointParameters(data));
360   }
361 };
362 
363 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
364  public:                                         \
365   explicit name() : base(key()) {}               \
366   static inline CallDescriptors::Key key();
367 
368 #if defined(V8_TARGET_ARCH_IA32)
369 // To support all possible cases, we must limit the number of register args for
370 // TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
371 // as the context register and ebx is the root register. One register must
372 // remain available to store the jump/call target. Thus 3 registers remain for
373 // arguments. The reason this applies to TFS builtins specifically is because
374 // this becomes relevant for builtins used as targets of Torque function
375 // pointers (which must have a register available to store the target).
376 // TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
377 // that comes with its own set of complications. It's possible, but requires
378 // refactoring the calling convention of other existing stubs.
379 constexpr int kMaxBuiltinRegisterParams = 4;
380 constexpr int kMaxTFSBuiltinRegisterParams = 3;
381 #else
382 constexpr int kMaxBuiltinRegisterParams = 5;
383 constexpr int kMaxTFSBuiltinRegisterParams = kMaxBuiltinRegisterParams;
384 #endif
385 STATIC_ASSERT(kMaxTFSBuiltinRegisterParams <= kMaxBuiltinRegisterParams);
386 
387 #define DECLARE_DEFAULT_DESCRIPTOR(name, base)                                 \
388   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
389  protected:                                                                    \
390   static const int kRegisterParams =                                           \
391       kParameterCount > kMaxTFSBuiltinRegisterParams                           \
392           ? kMaxTFSBuiltinRegisterParams                                       \
393           : kParameterCount;                                                   \
394   static const int kStackParams = kParameterCount - kRegisterParams;           \
395   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)           \
396       override {                                                               \
397     DefaultInitializePlatformSpecific(data, kRegisterParams);                  \
398   }                                                                            \
399   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)        \
400       override {                                                               \
401     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
402                                         kParameterCount, nullptr, 0);          \
403   }                                                                            \
404   name(CallDescriptors::Key key) : base(key) {}                                \
405                                                                                \
406  public:
407 
408 #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base,                        \
409                                          non_js_reg_parameters_count)       \
410   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                  \
411  protected:                                                                 \
412   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)        \
413       override {                                                            \
414     JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
415   }                                                                         \
416   name(CallDescriptors::Key key) : base(key) {}                             \
417                                                                             \
418  public:
419 
420 #define DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(flags, return_count, ...) \
421   static constexpr int kDescriptorFlags = flags;                         \
422   static constexpr int kReturnCount = return_count;                      \
423   enum ParameterIndices {                                                \
424     __dummy = -1, /* to be able to pass zero arguments */                \
425     ##__VA_ARGS__,                                                       \
426                                                                          \
427     kParameterCount,                                                     \
428     kContext = kParameterCount /* implicit parameter */                  \
429   };
430 
431 #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
432   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(               \
433       CallInterfaceDescriptorData::kNoFlags, return_count, ##__VA_ARGS__)
434 
435 // This is valid only for builtins that use EntryFrame, which does not scan
436 // stack arguments on GC.
437 #define DEFINE_PARAMETERS_ENTRY(...)                      \
438   static constexpr int kDescriptorFlags =                 \
439       CallInterfaceDescriptorData::kNoContext |           \
440       CallInterfaceDescriptorData::kNoStackScan;          \
441   static constexpr int kReturnCount = 1;                  \
442   enum ParameterIndices {                                 \
443     __dummy = -1, /* to be able to pass zero arguments */ \
444     ##__VA_ARGS__,                                        \
445                                                           \
446     kParameterCount                                       \
447   };
448 
449 #define DEFINE_PARAMETERS(...)            \
450   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS( \
451       CallInterfaceDescriptorData::kNoFlags, 1, ##__VA_ARGS__)
452 
453 #define DEFINE_PARAMETERS_NO_CONTEXT(...) \
454   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS( \
455       CallInterfaceDescriptorData::kNoContext, 1, ##__VA_ARGS__)
456 
457 #define DEFINE_PARAMETERS_VARARGS(...)    \
458   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS( \
459       CallInterfaceDescriptorData::kAllowVarArgs, 1, ##__VA_ARGS__)
460 
461 #define DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(flag, ...)                \
462   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)       \
463       override {                                                              \
464     MachineType machine_types[] = {__VA_ARGS__};                              \
465     static_assert(                                                            \
466         kReturnCount + kParameterCount == arraysize(machine_types),           \
467         "Parameter names definition is not consistent with parameter types"); \
468     data->InitializePlatformIndependent(                                      \
469         Flags(flag | kDescriptorFlags), kReturnCount, kParameterCount,        \
470         machine_types, arraysize(machine_types));                             \
471   }
472 
473 #define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
474   DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG( \
475       CallInterfaceDescriptorData::kNoFlags, __VA_ARGS__)
476 
477 #define DEFINE_PARAMETER_TYPES(...)                                        \
478   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
479                                     ##__VA_ARGS__)
480 
481 #define DEFINE_JS_PARAMETERS(...)                       \
482   static constexpr int kDescriptorFlags =               \
483       CallInterfaceDescriptorData::kAllowVarArgs;       \
484   static constexpr int kReturnCount = 1;                \
485   enum ParameterIndices {                               \
486     kTarget,                                            \
487     kNewTarget,                                         \
488     kActualArgumentsCount,                              \
489     ##__VA_ARGS__,                                      \
490                                                         \
491     kParameterCount,                                    \
492     kContext = kParameterCount /* implicit parameter */ \
493   };
494 
495 #define DEFINE_JS_PARAMETER_TYPES(...)                                         \
496   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */               \
497                          MachineType::AnyTagged(), /* kNewTarget */            \
498                          MachineType::Int32(),     /* kActualArgumentsCount */ \
499                          ##__VA_ARGS__)
500 
501 #define DECLARE_DESCRIPTOR(name, base)                                         \
502   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
503  protected:                                                                    \
504   void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
505   name(CallDescriptors::Key key) : base(key) {}                                \
506                                                                                \
507  public:
508 
509 class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
510  public:
511   DEFINE_PARAMETERS()
512   DEFINE_PARAMETER_TYPES()
513   DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
514 };
515 
516 // This class is subclassed by Torque-generated call interface descriptors.
517 template <int parameter_count>
518 class TorqueInterfaceDescriptor : public CallInterfaceDescriptor {
519  public:
520   static constexpr int kDescriptorFlags = CallInterfaceDescriptorData::kNoFlags;
521   static constexpr int kParameterCount = parameter_count;
522   enum ParameterIndices { kContext = kParameterCount };
523   template <int i>
ParameterIndex()524   static ParameterIndices ParameterIndex() {
525     STATIC_ASSERT(0 <= i && i < kParameterCount);
526     return static_cast<ParameterIndices>(i);
527   }
528   static constexpr int kReturnCount = 1;
529 
530   using CallInterfaceDescriptor::CallInterfaceDescriptor;
531 
532  protected:
533   static const int kRegisterParams =
534       kParameterCount > kMaxTFSBuiltinRegisterParams
535           ? kMaxTFSBuiltinRegisterParams
536           : kParameterCount;
537   static const int kStackParams = kParameterCount - kRegisterParams;
538   virtual MachineType ReturnType() = 0;
539   virtual std::array<MachineType, kParameterCount> ParameterTypes() = 0;
InitializePlatformSpecific(CallInterfaceDescriptorData * data)540   void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override {
541     DefaultInitializePlatformSpecific(data, kRegisterParams);
542   }
InitializePlatformIndependent(CallInterfaceDescriptorData * data)543   void InitializePlatformIndependent(
544       CallInterfaceDescriptorData* data) override {
545     std::vector<MachineType> machine_types = {ReturnType()};
546     auto parameter_types = ParameterTypes();
547     machine_types.insert(machine_types.end(), parameter_types.begin(),
548                          parameter_types.end());
549     DCHECK_EQ(kReturnCount + kParameterCount, machine_types.size());
550     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount,
551                                         kParameterCount, machine_types.data(),
552                                         static_cast<int>(machine_types.size()));
553   }
554 };
555 
556 // Dummy descriptor used to mark builtins that don't yet have their proper
557 // descriptor associated.
558 using DummyDescriptor = VoidDescriptor;
559 
560 // Dummy descriptor that marks builtins with C calling convention.
561 using CCallDescriptor = VoidDescriptor;
562 
563 class AllocateDescriptor : public CallInterfaceDescriptor {
564  public:
565   DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
566   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
567                                     MachineType::IntPtr())  // kRequestedSize
568   DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
569 };
570 
571 // This descriptor defines the JavaScript calling convention that can be used
572 // by stubs: target, new.target, argc (not including the receiver) and context
573 // are passed in registers while receiver and the rest of the JS arguments are
574 // passed on the stack.
575 class JSTrampolineDescriptor : public CallInterfaceDescriptor {
576  public:
577   DEFINE_JS_PARAMETERS()
578   DEFINE_JS_PARAMETER_TYPES()
579 
580   DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
581                                    CallInterfaceDescriptor, 0)
582 };
583 
584 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
585  public:
586   DEFINE_PARAMETERS()
587   DEFINE_PARAMETER_TYPES()
588   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
589 };
590 
591 class NoContextDescriptor : public CallInterfaceDescriptor {
592  public:
593   DEFINE_PARAMETERS_NO_CONTEXT()
594   DEFINE_PARAMETER_TYPES()
595   DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
596 };
597 
598 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
599 class LoadDescriptor : public CallInterfaceDescriptor {
600  public:
601   DEFINE_PARAMETERS(kReceiver, kName, kSlot)
602   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
603                          MachineType::AnyTagged(),     // kName
604                          MachineType::TaggedSigned())  // kSlot
605   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
606 
607   static const Register ReceiverRegister();
608   static const Register NameRegister();
609   static const Register SlotRegister();
610 };
611 
612 class LoadGlobalNoFeedbackDescriptor : public CallInterfaceDescriptor {
613  public:
DEFINE_PARAMETERS(kName,kICKind)614   DEFINE_PARAMETERS(kName, kICKind)
615   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
616                          MachineType::TaggedSigned())  // kICKind
617   DECLARE_DESCRIPTOR(LoadGlobalNoFeedbackDescriptor, CallInterfaceDescriptor)
618 
619   static const Register NameRegister() {
620     return LoadDescriptor::NameRegister();
621   }
622 
ICKindRegister()623   static const Register ICKindRegister() {
624     return LoadDescriptor::SlotRegister();
625   }
626 };
627 
628 class LoadNoFeedbackDescriptor : public LoadGlobalNoFeedbackDescriptor {
629  public:
DEFINE_PARAMETERS(kReceiver,kName,kICKind)630   DEFINE_PARAMETERS(kReceiver, kName, kICKind)
631   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
632                          MachineType::AnyTagged(),     // kName
633                          MachineType::TaggedSigned())  // kICKind
634   DECLARE_DESCRIPTOR(LoadNoFeedbackDescriptor, LoadGlobalNoFeedbackDescriptor)
635 
636   static const Register ReceiverRegister() {
637     return LoadDescriptor::ReceiverRegister();
638   }
639 
NameRegister()640   static const Register NameRegister() {
641     return LoadGlobalNoFeedbackDescriptor::NameRegister();
642   }
643 
ICKindRegister()644   static const Register ICKindRegister() {
645     return LoadGlobalNoFeedbackDescriptor::ICKindRegister();
646   }
647 };
648 
649 class LoadGlobalDescriptor : public CallInterfaceDescriptor {
650  public:
DEFINE_PARAMETERS(kName,kSlot)651   DEFINE_PARAMETERS(kName, kSlot)
652   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
653                          MachineType::TaggedSigned())  // kSlot
654   DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
655 
656   static const Register NameRegister() {
657     return LoadDescriptor::NameRegister();
658   }
659 
SlotRegister()660   static const Register SlotRegister() {
661     return LoadDescriptor::SlotRegister();
662   }
663 };
664 
665 class StoreDescriptor : public CallInterfaceDescriptor {
666  public:
667   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
668   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
669                          MachineType::AnyTagged(),     // kName
670                          MachineType::AnyTagged(),     // kValue
671                          MachineType::TaggedSigned())  // kSlot
672   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
673 
674   static const Register ReceiverRegister();
675   static const Register NameRegister();
676   static const Register ValueRegister();
677   static const Register SlotRegister();
678 
679 #if V8_TARGET_ARCH_IA32
680   static const bool kPassLastArgsOnStack = true;
681 #else
682   static const bool kPassLastArgsOnStack = false;
683 #endif
684 
685   // Pass value and slot through the stack.
686   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
687 };
688 
689 class StoreTransitionDescriptor : public StoreDescriptor {
690  public:
691   DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
692   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
693                          MachineType::AnyTagged(),     // kName
694                          MachineType::AnyTagged(),     // kMap
695                          MachineType::AnyTagged(),     // kValue
696                          MachineType::TaggedSigned(),  // kSlot
697                          MachineType::AnyTagged())     // kVector
698   DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
699 
700   static const Register MapRegister();
701   static const Register SlotRegister();
702   static const Register VectorRegister();
703 
704   // Pass value, slot and vector through the stack.
705   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
706 };
707 
708 class StoreWithVectorDescriptor : public StoreDescriptor {
709  public:
710   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
711   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
712                          MachineType::AnyTagged(),     // kName
713                          MachineType::AnyTagged(),     // kValue
714                          MachineType::TaggedSigned(),  // kSlot
715                          MachineType::AnyTagged())     // kVector
716   DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
717 
718   static const Register VectorRegister();
719 
720   // Pass value, slot and vector through the stack.
721   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
722 };
723 
724 class StoreGlobalDescriptor : public CallInterfaceDescriptor {
725  public:
726   DEFINE_PARAMETERS(kName, kValue, kSlot)
727   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
728                          MachineType::AnyTagged(),     // kValue
729                          MachineType::TaggedSigned())  // kSlot
730   DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
731 
732   static const bool kPassLastArgsOnStack =
733       StoreDescriptor::kPassLastArgsOnStack;
734   // Pass value and slot through the stack.
735   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
736 
NameRegister()737   static const Register NameRegister() {
738     return StoreDescriptor::NameRegister();
739   }
740 
ValueRegister()741   static const Register ValueRegister() {
742     return StoreDescriptor::ValueRegister();
743   }
744 
SlotRegister()745   static const Register SlotRegister() {
746     return StoreDescriptor::SlotRegister();
747   }
748 };
749 
750 class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
751  public:
DEFINE_PARAMETERS(kName,kValue,kSlot,kVector)752   DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
753   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
754                          MachineType::AnyTagged(),     // kValue
755                          MachineType::TaggedSigned(),  // kSlot
756                          MachineType::AnyTagged())     // kVector
757   DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
758 
759   static const Register VectorRegister() {
760     return StoreWithVectorDescriptor::VectorRegister();
761   }
762 
763   // Pass value, slot and vector through the stack.
764   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
765 };
766 
767 class LoadWithVectorDescriptor : public LoadDescriptor {
768  public:
769   // TODO(v8:9497): Revert the Machine type for kSlot to the
770   // TaggedSigned once Torque can emit better call descriptors
771   DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
772   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
773                          MachineType::AnyTagged(),  // kName
774                          MachineType::AnyTagged(),  // kSlot
775                          MachineType::AnyTagged())  // kVector
776   DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
777 
778   static const Register VectorRegister();
779 
780 #if V8_TARGET_ARCH_IA32
781   static const bool kPassLastArgsOnStack = true;
782 #else
783   static const bool kPassLastArgsOnStack = false;
784 #endif
785 
786   // Pass vector through the stack.
787   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
788 };
789 
790 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
791  public:
DEFINE_PARAMETERS(kName,kSlot,kVector)792   DEFINE_PARAMETERS(kName, kSlot, kVector)
793   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
794                          MachineType::TaggedSigned(),  // kSlot
795                          MachineType::AnyTagged())     // kVector
796   DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
797 
798 #if V8_TARGET_ARCH_IA32
799   // On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
800   // need to choose a new register here.
801   static const Register VectorRegister() { return edx; }
802 #else
803   static const Register VectorRegister() {
804     return LoadWithVectorDescriptor::VectorRegister();
805   }
806 #endif
807 };
808 
809 class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor {
810  public:
811   DEFINE_PARAMETERS(kScopeInfo, kSlots)
812   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kScopeInfo
813                          MachineType::Uint32())     // kSlots
814   DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor)
815 
816   static const Register ScopeInfoRegister();
817   static const Register SlotsRegister();
818 };
819 
820 class FastNewObjectDescriptor : public CallInterfaceDescriptor {
821  public:
822   DEFINE_PARAMETERS(kTarget, kNewTarget)
823   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
824                          MachineType::AnyTagged())  // kNewTarget
825   DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
826   static const Register TargetRegister();
827   static const Register NewTargetRegister();
828 };
829 
830 class RecordWriteDescriptor final : public CallInterfaceDescriptor {
831  public:
832   DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
833   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
834                          MachineType::Pointer(),        // kSlot
835                          MachineType::TaggedSigned(),   // kRememberedSet
836                          MachineType::TaggedSigned())   // kFPMode
837 
838   DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
839 };
840 
841 class EphemeronKeyBarrierDescriptor final : public CallInterfaceDescriptor {
842  public:
843   DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress, kFPMode)
844   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
845                          MachineType::Pointer(),        // kSlotAddress
846                          MachineType::TaggedSigned())   // kFPMode
847 
848   DECLARE_DESCRIPTOR(EphemeronKeyBarrierDescriptor, CallInterfaceDescriptor)
849 };
850 
851 class TypeConversionDescriptor final : public CallInterfaceDescriptor {
852  public:
853   DEFINE_PARAMETERS(kArgument)
854   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
855   DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
856 
857   static const Register ArgumentRegister();
858 };
859 
860 class TypeConversionStackParameterDescriptor final
861     : public CallInterfaceDescriptor {
862  public:
863   DEFINE_PARAMETERS(kArgument)
864   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
865   DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor,
866                      CallInterfaceDescriptor)
867 };
868 
869 class AsyncFunctionStackParameterDescriptor final
870     : public CallInterfaceDescriptor {
871  public:
872   DEFINE_PARAMETERS(kPromise, kResult)
873   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
874   DECLARE_DESCRIPTOR(AsyncFunctionStackParameterDescriptor,
875                      CallInterfaceDescriptor)
876 };
877 
878 class GetIteratorStackParameterDescriptor final
879     : public CallInterfaceDescriptor {
880  public:
881   DEFINE_PARAMETERS(kReceiver, kCallSlot, kFeedback, kResult)
882   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::AnyTagged(),
883                          MachineType::AnyTagged(), MachineType::AnyTagged())
884   DECLARE_DESCRIPTOR(GetIteratorStackParameterDescriptor,
885                      CallInterfaceDescriptor)
886 };
887 
888 class GetPropertyDescriptor final : public CallInterfaceDescriptor {
889  public:
890   DEFINE_PARAMETERS(kObject, kKey)
891   DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
892 };
893 
894 class TypeofDescriptor : public CallInterfaceDescriptor {
895  public:
896   DEFINE_PARAMETERS(kObject)
897   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
898   DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
899 };
900 
901 class CallTrampolineDescriptor : public CallInterfaceDescriptor {
902  public:
903   DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount)
904   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
905                          MachineType::Int32())      // kActualArgumentsCount
906   DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
907 };
908 
909 class CallVarargsDescriptor : public CallInterfaceDescriptor {
910  public:
911   DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsLength,
912                     kArgumentsList)
913   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
914                          MachineType::Int32(),      // kActualArgumentsCount
915                          MachineType::Int32(),      // kArgumentsLength
916                          MachineType::AnyTagged())  // kArgumentsList
917   DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
918 };
919 
920 class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
921  public:
922   DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kStartIndex)
923   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
924                          MachineType::Int32(),      // kActualArgumentsCount
925                          MachineType::Int32())      // kStartIndex
926   DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
927 };
928 
929 class CallFunctionTemplateDescriptor : public CallInterfaceDescriptor {
930  public:
931   DEFINE_PARAMETERS_VARARGS(kFunctionTemplateInfo, kArgumentsCount)
932   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunctionTemplateInfo
933                          MachineType::IntPtr())     // kArgumentsCount
934   DECLARE_DESCRIPTOR(CallFunctionTemplateDescriptor, CallInterfaceDescriptor)
935 };
936 
937 class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
938  public:
939   DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread)
940   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
941                          MachineType::Int32(),      // kArgumentsCount
942                          MachineType::AnyTagged())  // kSpread
943   DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
944 };
945 
946 class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
947  public:
948   DEFINE_PARAMETERS(kTarget, kArgumentsList)
949   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
950                          MachineType::AnyTagged())  // kArgumentsList
951   DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
952 };
953 
954 class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
955  public:
956   DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
957   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(),      // kArgumentsLength
958                             MachineType::AnyTagged())  // kArgumentsList
959 
960   DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
961 };
962 
963 class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
964  public:
965   DEFINE_JS_PARAMETERS(kStartIndex)
966   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
967   DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
968 };
969 
970 class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
971  public:
972   DEFINE_JS_PARAMETERS(kSpread)
973   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
974   DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
975 };
976 
977 class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
978  public:
979   DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
980   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
981                          MachineType::AnyTagged(),  // kNewTarget
982                          MachineType::AnyTagged())  // kArgumentsList
983   DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
984 };
985 
986 // TODO(ishell): consider merging this with ArrayConstructorDescriptor
987 class ConstructStubDescriptor : public CallInterfaceDescriptor {
988  public:
989   // TODO(jgruber): Remove the unused allocation site parameter.
990   DEFINE_JS_PARAMETERS(kAllocationSite)
991   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
992 
993   // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
994   DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
995 };
996 
997 class AbortDescriptor : public CallInterfaceDescriptor {
998  public:
999   DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
1000   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1001   DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
1002 };
1003 
1004 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
1005  public:
1006   DEFINE_PARAMETERS_NO_CONTEXT()
1007   DEFINE_PARAMETER_TYPES()
1008   DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
1009 };
1010 
1011 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
1012  public:
1013   DEFINE_JS_PARAMETERS(kAllocationSite)
1014   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1015 
1016   DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
1017                                    CallInterfaceDescriptor, 1)
1018 };
1019 
1020 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
1021  public:
1022   // This descriptor declares only register arguments while respective number
1023   // of JS arguments stay on the expression stack.
1024   // The ArrayNArgumentsConstructor builtin does not access stack arguments
1025   // directly it just forwards them to the runtime function.
1026   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
1027   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction,
1028                          MachineType::AnyTagged(),  // kAllocationSite
1029                          MachineType::Int32())      // kActualArgumentsCount
1030   DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
1031                      CallInterfaceDescriptor)
1032 };
1033 
1034 class ArrayNoArgumentConstructorDescriptor
1035     : public ArrayNArgumentsConstructorDescriptor {
1036  public:
1037   // This descriptor declares same register arguments as the parent
1038   // ArrayNArgumentsConstructorDescriptor and it declares indices for
1039   // JS arguments passed on the expression stack.
1040   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1041                     kFunctionParameter)
1042   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1043                          MachineType::AnyTagged(),  // kAllocationSite
1044                          MachineType::Int32(),      // kActualArgumentsCount
1045                          MachineType::AnyTagged())  // kFunctionParameter
1046   DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
1047                      ArrayNArgumentsConstructorDescriptor)
1048 };
1049 
1050 #ifdef V8_REVERSE_JSARGS
1051 class ArraySingleArgumentConstructorDescriptor
1052     : public ArrayNArgumentsConstructorDescriptor {
1053  public:
1054   // This descriptor declares same register arguments as the parent
1055   // ArrayNArgumentsConstructorDescriptor and it declares indices for
1056   // JS arguments passed on the expression stack.
1057   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1058                     kArraySizeSmiParameter, kReceiverParameter)
1059   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1060                          MachineType::AnyTagged(),  // kAllocationSite
1061                          MachineType::Int32(),      // kActualArgumentsCount
1062                          // JS arguments on the stack
1063                          MachineType::AnyTagged(),  // kArraySizeSmiParameter
1064                          MachineType::AnyTagged())  // kReceiverParameter
1065   DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
1066                      ArrayNArgumentsConstructorDescriptor)
1067 };
1068 #else
1069 class ArraySingleArgumentConstructorDescriptor
1070     : public ArrayNArgumentsConstructorDescriptor {
1071  public:
1072   // This descriptor declares same register arguments as the parent
1073   // ArrayNArgumentsConstructorDescriptor and it declares indices for
1074   // JS arguments passed on the expression stack.
1075   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1076                     kReceiverParameter, kArraySizeSmiParameter)
1077   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1078                          MachineType::AnyTagged(),  // kAllocationSite
1079                          MachineType::Int32(),      // kActualArgumentsCount
1080                          // JS arguments on the stack
1081                          MachineType::AnyTagged(),  // kReceiverParameter
1082                          MachineType::AnyTagged())  // kArraySizeSmiParameter
1083   DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
1084                      ArrayNArgumentsConstructorDescriptor)
1085 };
1086 #endif
1087 
1088 class CompareDescriptor : public CallInterfaceDescriptor {
1089  public:
1090   DEFINE_PARAMETERS(kLeft, kRight)
1091   DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
1092 };
1093 
1094 class BinaryOpDescriptor : public CallInterfaceDescriptor {
1095  public:
1096   DEFINE_PARAMETERS(kLeft, kRight)
1097   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
1098 };
1099 
1100 // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
1101 // as they all have the same interface.
1102 class StringAtDescriptor final : public CallInterfaceDescriptor {
1103  public:
1104   DEFINE_PARAMETERS(kReceiver, kPosition)
1105   // TODO(turbofan): Return untagged value here.
1106   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(),  // result 1
1107                                     MachineType::AnyTagged(),     // kReceiver
1108                                     MachineType::IntPtr())        // kPosition
1109   DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
1110 };
1111 
1112 class StringAtAsStringDescriptor final : public CallInterfaceDescriptor {
1113  public:
1114   DEFINE_PARAMETERS(kReceiver, kPosition)
1115   // TODO(turbofan): Return untagged value here.
1116   DEFINE_RESULT_AND_PARAMETER_TYPES(
1117       MachineType::TaggedPointer(),  // result string
1118       MachineType::AnyTagged(),      // kReceiver
1119       MachineType::IntPtr())         // kPosition
1120   DECLARE_DESCRIPTOR(StringAtAsStringDescriptor, CallInterfaceDescriptor)
1121 };
1122 
1123 class StringSubstringDescriptor final : public CallInterfaceDescriptor {
1124  public:
1125   DEFINE_PARAMETERS(kString, kFrom, kTo)
1126   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kString
1127                          MachineType::IntPtr(),     // kFrom
1128                          MachineType::IntPtr())     // kTo
1129 
1130   // TODO(turbofan): Allow builtins to return untagged values.
1131   DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
1132 };
1133 
1134 class ArgumentsAdaptorDescriptor : public CallInterfaceDescriptor {
1135  public:
1136   DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
1137   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
1138   DECLARE_DESCRIPTOR(ArgumentsAdaptorDescriptor, CallInterfaceDescriptor)
1139 };
1140 
1141 class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
1142  public:
1143   DEFINE_JS_PARAMETERS(kCFunction)
1144   DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
1145   DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
1146                                    CallInterfaceDescriptor, 1)
1147 };
1148 
1149 class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
1150  public:
1151   DEFINE_PARAMETERS(kArity,          // register argument
1152                     kCFunction,      // register argument
1153                     kPadding,        // stack argument 1 (just padding)
1154                     kArgcSmi,        // stack argument 2
1155                     kTargetCopy,     // stack argument 3
1156                     kNewTargetCopy)  // stack argument 4
1157   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kArity
1158                          MachineType::Pointer(),    // kCFunction
1159                          MachineType::AnyTagged(),  // kPadding
1160                          MachineType::AnyTagged(),  // kArgcSmi
1161                          MachineType::AnyTagged(),  // kTargetCopy
1162                          MachineType::AnyTagged())  // kNewTargetCopy
1163   DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
1164 };
1165 
1166 class ApiCallbackDescriptor : public CallInterfaceDescriptor {
1167  public:
1168   DEFINE_PARAMETERS_VARARGS(kApiFunctionAddress, kActualArgumentsCount,
1169                             kCallData, kHolder)
1170   //                           receiver is implicit stack argument 1
1171   //                           argv are implicit stack arguments [2, 2 + kArgc[
1172   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),    // kApiFunctionAddress
1173                          MachineType::IntPtr(),     // kActualArgumentsCount
1174                          MachineType::AnyTagged(),  // kCallData
1175                          MachineType::AnyTagged())  // kHolder
1176   DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
1177 };
1178 
1179 class ApiGetterDescriptor : public CallInterfaceDescriptor {
1180  public:
1181   DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
1182   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
1183                          MachineType::AnyTagged(),  // kHolder
1184                          MachineType::AnyTagged())  // kCallback
1185   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
1186 
1187   static const Register ReceiverRegister();
1188   static const Register HolderRegister();
1189   static const Register CallbackRegister();
1190 };
1191 
1192 // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
1193 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
1194  public:
1195   DEFINE_PARAMETERS(kObject, kKey)
1196   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kObject
1197                          MachineType::AnyTagged())  // kKey
1198   DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
1199 
1200   static const Register ObjectRegister();
1201   static const Register KeyRegister();
1202 };
1203 
1204 class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
1205  public:
1206   DEFINE_PARAMETERS(kFrame, kLength, kMappedCount)
1207   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),       // kFrame
1208                          MachineType::TaggedSigned(),  // kLength
1209                          MachineType::TaggedSigned())  // kMappedCount
1210   DECLARE_DESCRIPTOR(NewArgumentsElementsDescriptor, CallInterfaceDescriptor)
1211 };
1212 
1213 class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
1214     : public CallInterfaceDescriptor {
1215  public:
1216   DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
1217                     kDispatchTable)
1218   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kAccumulator
1219                          MachineType::IntPtr(),     // kBytecodeOffset
1220                          MachineType::AnyTagged(),  // kBytecodeArray
1221                          MachineType::IntPtr())     // kDispatchTable
1222   DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
1223 };
1224 
1225 class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
1226  public:
1227   DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
1228   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
1229                          MachineType::Pointer(),    // kFirstArgument
1230                          MachineType::AnyTagged())  // kFunction
1231   DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
1232                      CallInterfaceDescriptor)
1233 };
1234 
1235 class InterpreterPushArgsThenConstructDescriptor
1236     : public CallInterfaceDescriptor {
1237  public:
1238   DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
1239                     kNewTarget, kFeedbackElement)
1240   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
1241                          MachineType::Pointer(),    // kFirstArgument
1242                          MachineType::AnyTagged(),  // kConstructor
1243                          MachineType::AnyTagged(),  // kNewTarget
1244                          MachineType::AnyTagged())  // kFeedbackElement
1245   DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
1246                      CallInterfaceDescriptor)
1247 
1248 #if V8_TARGET_ARCH_IA32
1249   static const bool kPassLastArgsOnStack = true;
1250 #else
1251   static const bool kPassLastArgsOnStack = false;
1252 #endif
1253 
1254   // Pass constructor, new target and feedback element through the stack.
1255   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
1256 };
1257 
1258 class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
1259  public:
1260   DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
1261                                kFunctionEntry)
1262   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1263                                     MachineType::Int32(),  // kNumberOfArguments
1264                                     MachineType::Pointer(),  // kFirstArgument
1265                                     MachineType::Pointer())  // kFunctionEntry
1266   DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
1267 };
1268 
1269 class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
1270  public:
1271   DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
1272                                kFunctionEntry)
1273   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1274                                     MachineType::AnyTagged(),  // result 2
1275                                     MachineType::Int32(),  // kNumberOfArguments
1276                                     MachineType::Pointer(),  // kFirstArgument
1277                                     MachineType::Pointer())  // kFunctionEntry
1278   DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
1279 };
1280 
1281 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
1282  public:
1283   DEFINE_PARAMETERS(kValue, kGenerator)
1284   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
1285                          MachineType::AnyTagged())  // kGenerator
1286   DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
1287 };
1288 
1289 class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
1290  public:
1291   DEFINE_PARAMETERS(kRestartFp)
1292   DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1293   DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
1294 };
1295 
1296 class RunMicrotasksEntryDescriptor final : public CallInterfaceDescriptor {
1297  public:
1298   DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
1299   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),  // kRootRegisterValue
1300                          MachineType::Pointer())  // kMicrotaskQueue
1301   DECLARE_DESCRIPTOR(RunMicrotasksEntryDescriptor, CallInterfaceDescriptor)
1302 };
1303 
1304 class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
1305  public:
1306   DEFINE_PARAMETERS(kMicrotaskQueue)
1307   DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1308   DECLARE_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)
1309 
1310   static Register MicrotaskQueueRegister();
1311 };
1312 
1313 class WasmMemoryGrowDescriptor final : public CallInterfaceDescriptor {
1314  public:
1315   DEFINE_PARAMETERS_NO_CONTEXT(kNumPages)
1316   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(),  // result 1
1317                                     MachineType::Int32())  // kNumPages
1318   DECLARE_DESCRIPTOR(WasmMemoryGrowDescriptor, CallInterfaceDescriptor)
1319 };
1320 
1321 class WasmTableInitDescriptor final : public CallInterfaceDescriptor {
1322  public:
1323   DEFINE_PARAMETERS_NO_CONTEXT(kDestination, kSource, kSize, kTableIndex,
1324                                kSegmentIndex)
1325   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kDestination
1326                          MachineType::Int32(),      // kSource
1327                          MachineType::Int32(),      // kSize
1328                          MachineType::AnyTagged(),  // kTableIndex
1329                          MachineType::AnyTagged(),  // kSegmentindex
1330   )
1331 
1332 #if V8_TARGET_ARCH_IA32
1333   static constexpr bool kPassLastArgOnStack = true;
1334 #else
1335   static constexpr bool kPassLastArgOnStack = false;
1336 #endif
1337 
1338   // Pass the last parameter through the stack.
1339   static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;
1340 
1341   DECLARE_DESCRIPTOR(WasmTableInitDescriptor, CallInterfaceDescriptor)
1342 };
1343 
1344 class WasmTableCopyDescriptor final : public CallInterfaceDescriptor {
1345  public:
1346   DEFINE_PARAMETERS_NO_CONTEXT(kDestination, kSource, kSize, kDestinationTable,
1347                                kSourceTable)
1348   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kDestination
1349                          MachineType::Int32(),      // kSource
1350                          MachineType::Int32(),      // kSize
1351                          MachineType::AnyTagged(),  // kDestinationTable
1352                          MachineType::AnyTagged(),  // kSourceTable
1353   )
1354 
1355 #if V8_TARGET_ARCH_IA32
1356   static constexpr bool kPassLastArgOnStack = true;
1357 #else
1358   static constexpr bool kPassLastArgOnStack = false;
1359 #endif
1360 
1361   // Pass the last parameter through the stack.
1362   static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;
1363 
1364   DECLARE_DESCRIPTOR(WasmTableCopyDescriptor, CallInterfaceDescriptor)
1365 };
1366 
1367 class WasmTableGetDescriptor final : public CallInterfaceDescriptor {
1368  public:
1369   DEFINE_PARAMETERS_NO_CONTEXT(kTableIndex, kEntryIndex)
1370   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),     // result 1
1371                                     MachineType::TaggedSigned(),  // kTableIndex
1372                                     MachineType::Int32())         // kEntryIndex
1373   DECLARE_DESCRIPTOR(WasmTableGetDescriptor, CallInterfaceDescriptor)
1374 };
1375 
1376 class WasmTableSetDescriptor final : public CallInterfaceDescriptor {
1377  public:
1378   DEFINE_PARAMETERS_NO_CONTEXT(kTableIndex, kEntryIndex, kValue)
1379   DEFINE_PARAMETER_TYPES(MachineType::TaggedSigned(),  // kTableIndex
1380                          MachineType::Int32(),         // kEntryIndex
1381                          MachineType::AnyTagged())     // kValue
1382   DECLARE_DESCRIPTOR(WasmTableSetDescriptor, CallInterfaceDescriptor)
1383 };
1384 
1385 class WasmThrowDescriptor final : public CallInterfaceDescriptor {
1386  public:
1387   DEFINE_PARAMETERS_NO_CONTEXT(kException)
1388   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1389                                     MachineType::AnyTagged())  // kException
1390   DECLARE_DESCRIPTOR(WasmThrowDescriptor, CallInterfaceDescriptor)
1391 };
1392 
1393 class V8_EXPORT_PRIVATE I64ToBigIntDescriptor final
1394     : public CallInterfaceDescriptor {
1395  public:
1396   DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
1397   DEFINE_PARAMETER_TYPES(MachineType::Int64())  // kArgument
1398   DECLARE_DESCRIPTOR(I64ToBigIntDescriptor, CallInterfaceDescriptor)
1399 };
1400 
1401 // 32 bits version of the I64ToBigIntDescriptor call interface descriptor
1402 class V8_EXPORT_PRIVATE I32PairToBigIntDescriptor final
1403     : public CallInterfaceDescriptor {
1404  public:
1405   DEFINE_PARAMETERS_NO_CONTEXT(kLow, kHigh)
1406   DEFINE_PARAMETER_TYPES(MachineType::Uint32(),  // kLow
1407                          MachineType::Uint32())  // kHigh
1408   DECLARE_DESCRIPTOR(I32PairToBigIntDescriptor, CallInterfaceDescriptor)
1409 };
1410 
1411 class V8_EXPORT_PRIVATE BigIntToI64Descriptor final
1412     : public CallInterfaceDescriptor {
1413  public:
1414   DEFINE_PARAMETERS(kArgument)
1415   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(),      // result 1
1416                                     MachineType::AnyTagged())  // kArgument
1417   DECLARE_DESCRIPTOR(BigIntToI64Descriptor, CallInterfaceDescriptor)
1418 };
1419 
1420 class V8_EXPORT_PRIVATE BigIntToI32PairDescriptor final
1421     : public CallInterfaceDescriptor {
1422  public:
1423   DEFINE_RESULT_AND_PARAMETERS(2, kArgument)
1424   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),     // result 1
1425                                     MachineType::Uint32(),     // result 2
1426                                     MachineType::AnyTagged())  // kArgument
1427   DECLARE_DESCRIPTOR(BigIntToI32PairDescriptor, CallInterfaceDescriptor)
1428 };
1429 
1430 class WasmAtomicNotifyDescriptor final : public CallInterfaceDescriptor {
1431  public:
1432   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kCount)
1433   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
1434                                     MachineType::Uint32(),  // kAddress
1435                                     MachineType::Uint32())  // kCount
1436   DECLARE_DESCRIPTOR(WasmAtomicNotifyDescriptor, CallInterfaceDescriptor)
1437 };
1438 
1439 class WasmI32AtomicWait32Descriptor final : public CallInterfaceDescriptor {
1440  public:
1441   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeoutLow,
1442                                kTimeoutHigh)
1443   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
1444                                     MachineType::Uint32(),  // kAddress
1445                                     MachineType::Int32(),   // kExpectedValue
1446                                     MachineType::Uint32(),  // kTimeoutLow
1447                                     MachineType::Uint32())  // kTimeoutHigh
1448   DECLARE_DESCRIPTOR(WasmI32AtomicWait32Descriptor, CallInterfaceDescriptor)
1449 };
1450 
1451 class WasmI64AtomicWait32Descriptor final : public CallInterfaceDescriptor {
1452  public:
1453   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValueLow, kExpectedValueHigh,
1454                                kTimeoutLow, kTimeoutHigh)
1455 
1456   DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(
1457       CallInterfaceDescriptorData::kNoStackScan,  // allow untagged stack params
1458       MachineType::Uint32(),                      // result 1
1459       MachineType::Uint32(),                      // kAddress
1460       MachineType::Uint32(),                      // kExpectedValueLow
1461       MachineType::Uint32(),                      // kExpectedValueHigh
1462       MachineType::Uint32(),                      // kTimeoutLow
1463       MachineType::Uint32())                      // kTimeoutHigh
1464 
1465 #if V8_TARGET_ARCH_IA32
1466   static constexpr bool kPassLastArgOnStack = true;
1467 #else
1468   static constexpr bool kPassLastArgOnStack = false;
1469 #endif
1470 
1471   // Pass the last parameter through the stack.
1472   static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;
1473 
1474   DECLARE_DESCRIPTOR(WasmI64AtomicWait32Descriptor, CallInterfaceDescriptor)
1475 };
1476 
1477 class WasmI32AtomicWait64Descriptor final : public CallInterfaceDescriptor {
1478  public:
1479   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
1480   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
1481                                     MachineType::Uint32(),  // kAddress
1482                                     MachineType::Int32(),   // kExpectedValue
1483                                     MachineType::Uint64())  // kTimeout
1484   DECLARE_DESCRIPTOR(WasmI32AtomicWait64Descriptor, CallInterfaceDescriptor)
1485 };
1486 
1487 class WasmI64AtomicWait64Descriptor final : public CallInterfaceDescriptor {
1488  public:
1489   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
1490   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
1491                                     MachineType::Uint32(),  // kAddress
1492                                     MachineType::Uint64(),  // kExpectedValue
1493                                     MachineType::Uint64())  // kTimeout
1494   DECLARE_DESCRIPTOR(WasmI64AtomicWait64Descriptor, CallInterfaceDescriptor)
1495 };
1496 
1497 class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
1498  public:
1499   DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
1500   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
1501                                     MachineType::AnyTagged(),      // kSource
1502                                     MachineType::TaggedSigned(),   // kFlags
1503                                     MachineType::TaggedSigned(),   // kSlot
1504                                     MachineType::AnyTagged())      // kVector
1505   DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
1506 };
1507 
1508 #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...)                          \
1509   class Name##Descriptor : public CallInterfaceDescriptor {               \
1510    public:                                                                \
1511     DEFINE_PARAMETERS(__VA_ARGS__)                                        \
1512     DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
1513   };
1514 BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
1515 #undef DEFINE_TFS_BUILTIN_DESCRIPTOR
1516 
1517 // This file contains interface descriptor class definitions for builtins
1518 // defined in Torque. It is included here because the class definitions need to
1519 // precede the definition of name##Descriptor::key() below.
1520 #include "torque-generated/interface-descriptors-tq.inc"
1521 
1522 #undef DECLARE_DEFAULT_DESCRIPTOR
1523 #undef DECLARE_DESCRIPTOR_WITH_BASE
1524 #undef DECLARE_DESCRIPTOR
1525 #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
1526 #undef DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS
1527 #undef DEFINE_RESULT_AND_PARAMETERS
1528 #undef DEFINE_PARAMETERS
1529 #undef DEFINE_PARAMETERS_VARARGS
1530 #undef DEFINE_PARAMETERS_NO_CONTEXT
1531 #undef DEFINE_RESULT_AND_PARAMETER_TYPES
1532 #undef DEFINE_PARAMETER_TYPES
1533 #undef DEFINE_JS_PARAMETERS
1534 #undef DEFINE_JS_PARAMETER_TYPES
1535 
1536 // We define the association between CallDescriptors::Key and the specialized
1537 // descriptor here to reduce boilerplate and mistakes.
1538 #define DEF_KEY(name, ...) \
1539   CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
1540 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
1541 #undef DEF_KEY
1542 }  // namespace internal
1543 }  // namespace v8
1544 
1545 #endif  // V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
1546