• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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