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_CALL_INTERFACE_DESCRIPTOR_H_
6#define V8_CALL_INTERFACE_DESCRIPTOR_H_
7
8#include <memory>
9
10#include "src/assembler.h"
11#include "src/globals.h"
12#include "src/macro-assembler.h"
13
14namespace v8 {
15namespace internal {
16
17class PlatformInterfaceDescriptor;
18
19#define INTERFACE_DESCRIPTOR_LIST(V)      \
20  V(Void)                                 \
21  V(ContextOnly)                          \
22  V(Load)                                 \
23  V(LoadWithVector)                       \
24  V(LoadField)                            \
25  V(LoadICProtoArray)                     \
26  V(LoadGlobal)                           \
27  V(LoadGlobalWithVector)                 \
28  V(Store)                                \
29  V(StoreWithVector)                      \
30  V(StoreNamedTransition)                 \
31  V(StoreTransition)                      \
32  V(VarArgFunction)                       \
33  V(FastNewClosure)                       \
34  V(FastNewFunctionContext)               \
35  V(FastNewObject)                        \
36  V(FastNewArguments)                     \
37  V(TypeConversion)                       \
38  V(Typeof)                               \
39  V(FastCloneRegExp)                      \
40  V(FastCloneShallowArray)                \
41  V(FastCloneShallowObject)               \
42  V(CreateAllocationSite)                 \
43  V(CreateWeakCell)                       \
44  V(CallFunction)                         \
45  V(CallIC)                               \
46  V(CallICTrampoline)                     \
47  V(CallForwardVarargs)                   \
48  V(CallConstruct)                        \
49  V(CallTrampoline)                       \
50  V(ConstructStub)                        \
51  V(ConstructTrampoline)                  \
52  V(RegExpExec)                           \
53  V(RegExpReplace)                        \
54  V(RegExpSplit)                          \
55  V(CopyFastSmiOrObjectElements)          \
56  V(TransitionElementsKind)               \
57  V(AllocateHeapNumber)                   \
58  V(Builtin)                              \
59  V(ArrayConstructor)                     \
60  V(ForEach)                              \
61  V(ArrayNoArgumentConstructor)           \
62  V(ArraySingleArgumentConstructor)       \
63  V(ArrayNArgumentsConstructor)           \
64  V(Compare)                              \
65  V(BinaryOp)                             \
66  V(BinaryOpWithAllocationSite)           \
67  V(BinaryOpWithVector)                   \
68  V(CountOp)                              \
69  V(StringAdd)                            \
70  V(StringCharAt)                         \
71  V(StringCharCodeAt)                     \
72  V(StringCompare)                        \
73  V(StringIndexOf)                        \
74  V(SubString)                            \
75  V(Keyed)                                \
76  V(Named)                                \
77  V(CreateIterResultObject)               \
78  V(HasProperty)                          \
79  V(ForInFilter)                          \
80  V(ForInNext)                            \
81  V(ForInPrepare)                         \
82  V(GetProperty)                          \
83  V(CallHandler)                          \
84  V(ArgumentAdaptor)                      \
85  V(ApiCallback)                          \
86  V(ApiGetter)                            \
87  V(MathPowTagged)                        \
88  V(MathPowInteger)                       \
89  V(GrowArrayElements)                    \
90  V(NewArgumentsElements)                 \
91  V(InterpreterDispatch)                  \
92  V(InterpreterPushArgsAndCall)           \
93  V(InterpreterPushArgsAndConstruct)      \
94  V(InterpreterPushArgsAndConstructArray) \
95  V(InterpreterCEntry)                    \
96  V(ResumeGenerator)                      \
97  V(FrameDropperTrampoline)               \
98  V(PromiseHandleReject)                  \
99  V(WasmRuntimeCall)
100
101class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
102 public:
103  CallInterfaceDescriptorData() : register_param_count_(-1), param_count_(-1) {}
104
105  // A copy of the passed in registers and param_representations is made
106  // and owned by the CallInterfaceDescriptorData.
107
108  void InitializePlatformSpecific(
109      int register_parameter_count, const Register* registers,
110      PlatformInterfaceDescriptor* platform_descriptor = NULL);
111
112  // if machine_types is null, then an array of size
113  // (register_parameter_count + extra_parameter_count) will be created
114  // with MachineType::AnyTagged() for each member.
115  //
116  // if machine_types is not null, then it should be of the size
117  // register_parameter_count. Those members of the parameter array
118  // will be initialized from {machine_types}, and the rest initialized
119  // to MachineType::AnyTagged().
120  void InitializePlatformIndependent(int parameter_count,
121                                     int extra_parameter_count,
122                                     const MachineType* machine_types);
123
124  bool IsInitialized() const {
125    return register_param_count_ >= 0 && param_count_ >= 0;
126  }
127
128  int param_count() const { return param_count_; }
129  int register_param_count() const { return register_param_count_; }
130  Register register_param(int index) const { return register_params_[index]; }
131  Register* register_params() const { return register_params_.get(); }
132  MachineType param_type(int index) const { return machine_types_[index]; }
133  PlatformInterfaceDescriptor* platform_specific_descriptor() const {
134    return platform_specific_descriptor_;
135  }
136
137 private:
138  int register_param_count_;
139  int param_count_;
140
141  // The Register params are allocated dynamically by the
142  // InterfaceDescriptor, and freed on destruction. This is because static
143  // arrays of Registers cause creation of runtime static initializers
144  // which we don't want.
145  std::unique_ptr<Register[]> register_params_;
146  std::unique_ptr<MachineType[]> machine_types_;
147
148  PlatformInterfaceDescriptor* platform_specific_descriptor_;
149
150  DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
151};
152
153
154class CallDescriptors {
155 public:
156  enum Key {
157#define DEF_ENUM(name) name,
158    INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
159#undef DEF_ENUM
160    NUMBER_OF_DESCRIPTORS
161  };
162};
163
164class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
165 public:
166  CallInterfaceDescriptor() : data_(NULL) {}
167  virtual ~CallInterfaceDescriptor() {}
168
169  CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
170      : data_(isolate->call_descriptor_data(key)) {}
171
172  int GetParameterCount() const { return data()->param_count(); }
173
174  int GetRegisterParameterCount() const {
175    return data()->register_param_count();
176  }
177
178  int GetStackParameterCount() const {
179    return data()->param_count() - data()->register_param_count();
180  }
181
182  Register GetRegisterParameter(int index) const {
183    return data()->register_param(index);
184  }
185
186  MachineType GetParameterType(int index) const {
187    DCHECK(index < data()->param_count());
188    return data()->param_type(index);
189  }
190
191  // Some platforms have extra information to associate with the descriptor.
192  PlatformInterfaceDescriptor* platform_specific_descriptor() const {
193    return data()->platform_specific_descriptor();
194  }
195
196  static const Register ContextRegister();
197
198  const char* DebugName(Isolate* isolate) const;
199
200 protected:
201  const CallInterfaceDescriptorData* data() const { return data_; }
202
203  virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
204    UNREACHABLE();
205  }
206
207  virtual void InitializePlatformIndependent(
208      CallInterfaceDescriptorData* data) {
209    data->InitializePlatformIndependent(data->register_param_count(), 0, NULL);
210  }
211
212  void Initialize(Isolate* isolate, CallDescriptors::Key key) {
213    if (!data()->IsInitialized()) {
214      // We should only initialize descriptors on the isolate's main thread.
215      DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
216      CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key);
217      DCHECK(d == data());  // d should be a modifiable pointer to data().
218      InitializePlatformSpecific(d);
219      InitializePlatformIndependent(d);
220    }
221  }
222
223  // Initializes |data| using the platform dependent default set of registers.
224  // It is intended to be used for TurboFan stubs when particular set of
225  // registers does not matter.
226  static void DefaultInitializePlatformSpecific(
227      CallInterfaceDescriptorData* data, int register_parameter_count);
228
229 private:
230  const CallInterfaceDescriptorData* data_;
231};
232
233#define DECLARE_DESCRIPTOR_WITH_BASE(name, base)           \
234 public:                                                   \
235  explicit name(Isolate* isolate) : base(isolate, key()) { \
236    Initialize(isolate, key());                            \
237  }                                                        \
238  static inline CallDescriptors::Key key();
239
240#define DECLARE_DEFAULT_DESCRIPTOR(name, base, parameter_count)            \
241  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                 \
242 protected:                                                                \
243  void InitializePlatformSpecific(CallInterfaceDescriptorData* data)       \
244      override {                                                           \
245    DefaultInitializePlatformSpecific(data, parameter_count);              \
246  }                                                                        \
247  name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
248                                                                           \
249 public:
250
251#define DECLARE_DESCRIPTOR(name, base)                                         \
252  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
253 protected:                                                                    \
254  void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
255  name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {}     \
256                                                                               \
257 public:
258
259#define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base)        \
260  DECLARE_DESCRIPTOR(name, base)                                        \
261 protected:                                                             \
262  void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
263      override;                                                         \
264                                                                        \
265 public:
266
267#define DECLARE_DESCRIPTOR_WITH_STACK_ARGS(name, base)                  \
268  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                              \
269 protected:                                                             \
270  void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
271      override {                                                        \
272    data->InitializePlatformIndependent(0, kParameterCount, NULL);      \
273  }                                                                     \
274  void InitializePlatformSpecific(CallInterfaceDescriptorData* data)    \
275      override {                                                        \
276    data->InitializePlatformSpecific(0, nullptr);                       \
277  }                                                                     \
278                                                                        \
279 public:
280
281#define DEFINE_PARAMETERS(...)                          \
282  enum ParameterIndices {                               \
283    __VA_ARGS__,                                        \
284                                                        \
285    kParameterCount,                                    \
286    kContext = kParameterCount /* implicit parameter */ \
287  };
288
289#define DECLARE_BUILTIN_DESCRIPTOR(name)                                \
290  DECLARE_DESCRIPTOR_WITH_BASE(name, BuiltinDescriptor)                 \
291 protected:                                                             \
292  void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
293      override {                                                        \
294    MachineType machine_types[] = {MachineType::AnyTagged(),            \
295                                   MachineType::AnyTagged(),            \
296                                   MachineType::Int32()};               \
297    int argc = kStackParameterCount + 1 - arraysize(machine_types);     \
298    data->InitializePlatformIndependent(arraysize(machine_types), argc, \
299                                        machine_types);                 \
300  }                                                                     \
301  void InitializePlatformSpecific(CallInterfaceDescriptorData* data)    \
302      override {                                                        \
303    Register registers[] = {TargetRegister(), NewTargetRegister(),      \
304                            ArgumentsCountRegister()};                  \
305    data->InitializePlatformSpecific(arraysize(registers), registers);  \
306  }                                                                     \
307                                                                        \
308 public:
309
310#define DEFINE_BUILTIN_PARAMETERS(...)                             \
311  enum ParameterIndices {                                          \
312    kReceiver,                                                     \
313    kBeforeFirstStackParameter = kReceiver,                        \
314    __VA_ARGS__,                                                   \
315    kAfterLastStackParameter,                                      \
316    kNewTarget = kAfterLastStackParameter,                         \
317    kArgumentsCount,                                               \
318    kContext, /* implicit parameter */                             \
319    kParameterCount = kContext,                                    \
320    kStackParameterCount =                                         \
321        kAfterLastStackParameter - kBeforeFirstStackParameter - 1, \
322  };
323
324class VoidDescriptor : public CallInterfaceDescriptor {
325 public:
326  DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
327};
328
329class ContextOnlyDescriptor : public CallInterfaceDescriptor {
330 public:
331  DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
332};
333
334// LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
335class LoadDescriptor : public CallInterfaceDescriptor {
336 public:
337  DEFINE_PARAMETERS(kReceiver, kName, kSlot)
338  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadDescriptor,
339                                               CallInterfaceDescriptor)
340
341  static const Register ReceiverRegister();
342  static const Register NameRegister();
343  static const Register SlotRegister();
344};
345
346// LoadFieldDescriptor is used by the shared handler that loads a field from an
347// object based on the smi-encoded field description.
348class LoadFieldDescriptor : public CallInterfaceDescriptor {
349 public:
350  DEFINE_PARAMETERS(kReceiver, kSmiHandler)
351  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadFieldDescriptor,
352                                               CallInterfaceDescriptor)
353
354  static const Register ReceiverRegister();
355  static const Register SmiHandlerRegister();
356};
357
358class LoadGlobalDescriptor : public CallInterfaceDescriptor {
359 public:
360  DEFINE_PARAMETERS(kName, kSlot)
361  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalDescriptor,
362                                               CallInterfaceDescriptor)
363
364  static const Register NameRegister() {
365    return LoadDescriptor::NameRegister();
366  }
367
368  static const Register SlotRegister() {
369    return LoadDescriptor::SlotRegister();
370  }
371};
372
373class StoreDescriptor : public CallInterfaceDescriptor {
374 public:
375  DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
376  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreDescriptor,
377                                               CallInterfaceDescriptor)
378
379  static const Register ReceiverRegister();
380  static const Register NameRegister();
381  static const Register ValueRegister();
382  static const Register SlotRegister();
383
384#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
385  static const bool kPassLastArgsOnStack = true;
386#else
387  static const bool kPassLastArgsOnStack = false;
388#endif
389
390  // Pass value and slot through the stack.
391  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
392};
393
394class StoreTransitionDescriptor : public StoreDescriptor {
395 public:
396  DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
397  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreTransitionDescriptor,
398                                               StoreDescriptor)
399
400  static const Register MapRegister();
401  static const Register SlotRegister();
402  static const Register VectorRegister();
403
404  // Pass value, slot and vector through the stack.
405  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
406};
407
408class StoreNamedTransitionDescriptor : public StoreTransitionDescriptor {
409 public:
410  DEFINE_PARAMETERS(kReceiver, kFieldOffset, kMap, kValue, kSlot, kVector,
411                    kName)
412  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreNamedTransitionDescriptor,
413                                               StoreTransitionDescriptor)
414
415  // Always pass name on the stack.
416  static const bool kPassLastArgsOnStack = true;
417  static const int kStackArgumentsCount =
418      StoreTransitionDescriptor::kStackArgumentsCount + 1;
419
420  static const Register NameRegister() { return no_reg; }
421  static const Register FieldOffsetRegister() {
422    return StoreTransitionDescriptor::NameRegister();
423  }
424};
425
426class StoreWithVectorDescriptor : public StoreDescriptor {
427 public:
428  DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
429  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreWithVectorDescriptor,
430                                               StoreDescriptor)
431
432  static const Register VectorRegister();
433
434  // Pass value, slot and vector through the stack.
435  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
436};
437
438class LoadWithVectorDescriptor : public LoadDescriptor {
439 public:
440  DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
441  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadWithVectorDescriptor,
442                                               LoadDescriptor)
443
444  static const Register VectorRegister();
445};
446
447class LoadICProtoArrayDescriptor : public LoadWithVectorDescriptor {
448 public:
449  DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector, kHandler)
450  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadICProtoArrayDescriptor,
451                                               LoadWithVectorDescriptor)
452
453  static const Register HandlerRegister();
454};
455
456class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
457 public:
458  DEFINE_PARAMETERS(kName, kSlot, kVector)
459  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalWithVectorDescriptor,
460                                               LoadGlobalDescriptor)
461
462  static const Register VectorRegister() {
463    return LoadWithVectorDescriptor::VectorRegister();
464  }
465};
466
467class FastNewClosureDescriptor : public CallInterfaceDescriptor {
468 public:
469  DEFINE_PARAMETERS(kSharedFunctionInfo, kVector, kSlot)
470  DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
471};
472
473class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor {
474 public:
475  DEFINE_PARAMETERS(kFunction, kSlots)
476  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastNewFunctionContextDescriptor,
477                                               CallInterfaceDescriptor)
478
479  static const Register FunctionRegister();
480  static const Register SlotsRegister();
481};
482
483class FastNewObjectDescriptor : public CallInterfaceDescriptor {
484 public:
485  DEFINE_PARAMETERS(kTarget, kNewTarget)
486  DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
487  static const Register TargetRegister();
488  static const Register NewTargetRegister();
489};
490
491class FastNewArgumentsDescriptor : public CallInterfaceDescriptor {
492 public:
493  DEFINE_PARAMETERS(kFunction)
494  DECLARE_DESCRIPTOR(FastNewArgumentsDescriptor, CallInterfaceDescriptor)
495  static const Register TargetRegister();
496};
497
498class TypeConversionDescriptor final : public CallInterfaceDescriptor {
499 public:
500  DEFINE_PARAMETERS(kArgument)
501  DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
502
503  static const Register ArgumentRegister();
504};
505
506class CreateIterResultObjectDescriptor final : public CallInterfaceDescriptor {
507 public:
508  DEFINE_PARAMETERS(kValue, kDone)
509  DECLARE_DEFAULT_DESCRIPTOR(CreateIterResultObjectDescriptor,
510                             CallInterfaceDescriptor, kParameterCount)
511};
512
513class HasPropertyDescriptor final : public CallInterfaceDescriptor {
514 public:
515  DEFINE_PARAMETERS(kKey, kObject)
516  DECLARE_DEFAULT_DESCRIPTOR(HasPropertyDescriptor, CallInterfaceDescriptor,
517                             kParameterCount)
518};
519
520class ForInFilterDescriptor final : public CallInterfaceDescriptor {
521 public:
522  DEFINE_PARAMETERS(kKey, kObject)
523  DECLARE_DEFAULT_DESCRIPTOR(ForInFilterDescriptor, CallInterfaceDescriptor,
524                             kParameterCount)
525};
526
527class ForInNextDescriptor final : public CallInterfaceDescriptor {
528 public:
529  DEFINE_PARAMETERS(kObject, kCacheArray, kCacheType, kIndex)
530  DECLARE_DEFAULT_DESCRIPTOR(ForInNextDescriptor, CallInterfaceDescriptor,
531                             kParameterCount)
532};
533
534class ForInPrepareDescriptor final : public CallInterfaceDescriptor {
535 public:
536  DEFINE_PARAMETERS(kObject)
537  DECLARE_DEFAULT_DESCRIPTOR(ForInPrepareDescriptor, CallInterfaceDescriptor,
538                             kParameterCount)
539};
540
541class GetPropertyDescriptor final : public CallInterfaceDescriptor {
542 public:
543  DEFINE_PARAMETERS(kObject, kKey)
544  DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor,
545                             kParameterCount)
546};
547
548class TypeofDescriptor : public CallInterfaceDescriptor {
549 public:
550  DEFINE_PARAMETERS(kObject)
551  DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
552};
553
554
555class FastCloneRegExpDescriptor : public CallInterfaceDescriptor {
556 public:
557  DEFINE_PARAMETERS(kClosure, kLiteralIndex, kPattern, kFlags)
558  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneRegExpDescriptor,
559                                               CallInterfaceDescriptor)
560};
561
562
563class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
564 public:
565  DEFINE_PARAMETERS(kClosure, kLiteralIndex, kConstantElements)
566  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneShallowArrayDescriptor,
567                                               CallInterfaceDescriptor)
568};
569
570
571class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
572 public:
573  DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
574};
575
576
577class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
578 public:
579  DEFINE_PARAMETERS(kVector, kSlot)
580  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateAllocationSiteDescriptor,
581                                               CallInterfaceDescriptor)
582};
583
584
585class CreateWeakCellDescriptor : public CallInterfaceDescriptor {
586 public:
587  DEFINE_PARAMETERS(kVector, kSlot, kValue)
588  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateWeakCellDescriptor,
589                                               CallInterfaceDescriptor)
590};
591
592
593class CallTrampolineDescriptor : public CallInterfaceDescriptor {
594 public:
595  DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
596  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallTrampolineDescriptor,
597                                               CallInterfaceDescriptor)
598};
599
600class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
601 public:
602  DEFINE_PARAMETERS(kTarget, kStartIndex)
603  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallForwardVarargsDescriptor,
604                                               CallInterfaceDescriptor)
605};
606
607class ConstructStubDescriptor : public CallInterfaceDescriptor {
608 public:
609  DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount,
610                    kAllocationSite)
611  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructStubDescriptor,
612                                               CallInterfaceDescriptor)
613};
614
615
616class ConstructTrampolineDescriptor : public CallInterfaceDescriptor {
617 public:
618  DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount)
619  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructTrampolineDescriptor,
620                                               CallInterfaceDescriptor)
621};
622
623
624class CallFunctionDescriptor : public CallInterfaceDescriptor {
625 public:
626  DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
627};
628
629class CallICDescriptor : public CallInterfaceDescriptor {
630 public:
631  DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kSlot, kVector)
632  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallICDescriptor,
633                                               CallInterfaceDescriptor)
634};
635
636class CallICTrampolineDescriptor : public CallInterfaceDescriptor {
637 public:
638  DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kSlot)
639  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallICTrampolineDescriptor,
640                                               CallInterfaceDescriptor)
641};
642
643class CallConstructDescriptor : public CallInterfaceDescriptor {
644 public:
645  DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
646};
647
648class RegExpExecDescriptor : public CallInterfaceDescriptor {
649 public:
650  DEFINE_PARAMETERS(kRegExpObject, kString, kPreviousIndex, kLastMatchInfo)
651  DECLARE_DESCRIPTOR_WITH_STACK_ARGS(RegExpExecDescriptor,
652                                     CallInterfaceDescriptor)
653};
654
655class RegExpReplaceDescriptor : public CallInterfaceDescriptor {
656 public:
657  DEFINE_PARAMETERS(kReceiver, kString, kReplaceValue)
658  DECLARE_DEFAULT_DESCRIPTOR(RegExpReplaceDescriptor, CallInterfaceDescriptor,
659                             kParameterCount)
660};
661
662class RegExpSplitDescriptor : public CallInterfaceDescriptor {
663 public:
664  DEFINE_PARAMETERS(kReceiver, kString, kLimit)
665  DECLARE_DEFAULT_DESCRIPTOR(RegExpSplitDescriptor, CallInterfaceDescriptor,
666                             kParameterCount)
667};
668
669class CopyFastSmiOrObjectElementsDescriptor : public CallInterfaceDescriptor {
670 public:
671  DEFINE_PARAMETERS(kObject)
672  DECLARE_DEFAULT_DESCRIPTOR(CopyFastSmiOrObjectElementsDescriptor,
673                             CallInterfaceDescriptor, kParameterCount)
674};
675
676class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
677 public:
678  DEFINE_PARAMETERS(kObject, kMap)
679  DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
680};
681
682
683class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
684 public:
685  DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
686};
687
688class BuiltinDescriptor : public CallInterfaceDescriptor {
689 public:
690  // TODO(ishell): Where is kFunction??
691  DEFINE_PARAMETERS(kNewTarget, kArgumentsCount)
692  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(BuiltinDescriptor,
693                                               CallInterfaceDescriptor)
694  static const Register ArgumentsCountRegister();
695  static const Register NewTargetRegister();
696  static const Register TargetRegister();
697};
698
699class ForEachDescriptor : public BuiltinDescriptor {
700 public:
701  DEFINE_BUILTIN_PARAMETERS(kCallback, kThisArg)
702  DECLARE_BUILTIN_DESCRIPTOR(ForEachDescriptor)
703};
704
705class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
706 public:
707  DEFINE_PARAMETERS(kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite)
708  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArrayConstructorDescriptor,
709                                               CallInterfaceDescriptor)
710};
711
712class ArrayNoArgumentConstructorDescriptor : public CallInterfaceDescriptor {
713 public:
714  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
715                    kFunctionParameter)
716  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
717      ArrayNoArgumentConstructorDescriptor, CallInterfaceDescriptor)
718};
719
720class ArraySingleArgumentConstructorDescriptor
721    : public CallInterfaceDescriptor {
722 public:
723  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
724                    kFunctionParameter, kArraySizeSmiParameter)
725  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
726      ArraySingleArgumentConstructorDescriptor, CallInterfaceDescriptor)
727};
728
729class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
730 public:
731  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
732  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
733      ArrayNArgumentsConstructorDescriptor, CallInterfaceDescriptor)
734};
735
736
737class CompareDescriptor : public CallInterfaceDescriptor {
738 public:
739  DEFINE_PARAMETERS(kLeft, kRight)
740  DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
741};
742
743
744class BinaryOpDescriptor : public CallInterfaceDescriptor {
745 public:
746  DEFINE_PARAMETERS(kLeft, kRight)
747  DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
748};
749
750
751class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
752 public:
753  DEFINE_PARAMETERS(kAllocationSite, kLeft, kRight)
754  DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
755                     CallInterfaceDescriptor)
756};
757
758class BinaryOpWithVectorDescriptor : public CallInterfaceDescriptor {
759 public:
760  DEFINE_PARAMETERS(kLeft, kRight, kSlot, kVector)
761  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(BinaryOpWithVectorDescriptor,
762                                               CallInterfaceDescriptor)
763};
764
765class CountOpDescriptor final : public CallInterfaceDescriptor {
766 public:
767  DECLARE_DESCRIPTOR(CountOpDescriptor, CallInterfaceDescriptor)
768};
769
770class StringAddDescriptor : public CallInterfaceDescriptor {
771 public:
772  DEFINE_PARAMETERS(kLeft, kRight)
773  DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
774};
775
776class StringCharAtDescriptor final : public CallInterfaceDescriptor {
777 public:
778  DEFINE_PARAMETERS(kReceiver, kPosition)
779  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StringCharAtDescriptor,
780                                               CallInterfaceDescriptor)
781};
782
783class StringCharCodeAtDescriptor final : public CallInterfaceDescriptor {
784 public:
785  DEFINE_PARAMETERS(kReceiver, kPosition)
786  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StringCharCodeAtDescriptor,
787                                               CallInterfaceDescriptor)
788};
789
790class StringCompareDescriptor : public CallInterfaceDescriptor {
791 public:
792  DEFINE_PARAMETERS(kLeft, kRight)
793  DECLARE_DESCRIPTOR(StringCompareDescriptor, CallInterfaceDescriptor)
794
795  static const Register LeftRegister();
796  static const Register RightRegister();
797};
798
799class SubStringDescriptor : public CallInterfaceDescriptor {
800 public:
801  DEFINE_PARAMETERS(kString, kFrom, kTo)
802  DECLARE_DESCRIPTOR_WITH_STACK_ARGS(SubStringDescriptor,
803                                     CallInterfaceDescriptor)
804};
805
806class StringIndexOfDescriptor final : public CallInterfaceDescriptor {
807 public:
808  DEFINE_PARAMETERS(kReceiver, kSearchString, kPosition)
809  DECLARE_DEFAULT_DESCRIPTOR(StringIndexOfDescriptor, CallInterfaceDescriptor,
810                             kParameterCount)
811};
812
813// TODO(ishell): not used, remove.
814class KeyedDescriptor : public CallInterfaceDescriptor {
815 public:
816  DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
817};
818
819// TODO(ishell): not used, remove
820class NamedDescriptor : public CallInterfaceDescriptor {
821 public:
822  DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
823};
824
825// TODO(ishell): not used, remove.
826class CallHandlerDescriptor : public CallInterfaceDescriptor {
827 public:
828  DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
829};
830
831
832class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
833 public:
834  DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount,
835                    kExpectedArgumentsCount)
836  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArgumentAdaptorDescriptor,
837                                               CallInterfaceDescriptor)
838};
839
840class ApiCallbackDescriptor : public CallInterfaceDescriptor {
841 public:
842  DEFINE_PARAMETERS(kFunction, kCallData, kHolder, kApiFunctionAddress)
843  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiCallbackDescriptor,
844                                               CallInterfaceDescriptor)
845};
846
847class ApiGetterDescriptor : public CallInterfaceDescriptor {
848 public:
849  DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
850  DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
851
852  static const Register ReceiverRegister();
853  static const Register HolderRegister();
854  static const Register CallbackRegister();
855};
856
857class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
858 public:
859  DEFINE_PARAMETERS(kExponent)
860  DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
861
862  static const Register exponent();
863};
864
865class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
866 public:
867  DEFINE_PARAMETERS(kExponent)
868  DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
869
870  static const Register exponent();
871};
872
873class VarArgFunctionDescriptor : public CallInterfaceDescriptor {
874 public:
875  DEFINE_PARAMETERS(kActualArgumentsCount)
876  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(VarArgFunctionDescriptor,
877                                               CallInterfaceDescriptor)
878};
879
880// TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
881class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
882 public:
883  DEFINE_PARAMETERS(kObject, kKey)
884  DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
885
886  static const Register ObjectRegister();
887  static const Register KeyRegister();
888};
889
890class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
891 public:
892  DEFINE_PARAMETERS(kFormalParameterCount)
893  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(NewArgumentsElementsDescriptor,
894                                               CallInterfaceDescriptor)
895};
896
897class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
898    : public CallInterfaceDescriptor {
899 public:
900  DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
901                    kDispatchTable)
902  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor,
903                                               CallInterfaceDescriptor)
904};
905
906class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
907 public:
908  DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
909  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
910      InterpreterPushArgsAndCallDescriptor, CallInterfaceDescriptor)
911};
912
913
914class InterpreterPushArgsAndConstructDescriptor
915    : public CallInterfaceDescriptor {
916 public:
917  DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor,
918                    kFeedbackElement, kFirstArgument)
919  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
920      InterpreterPushArgsAndConstructDescriptor, CallInterfaceDescriptor)
921};
922
923class InterpreterPushArgsAndConstructArrayDescriptor
924    : public CallInterfaceDescriptor {
925 public:
926  DEFINE_PARAMETERS(kNumberOfArguments, kFunction, kFeedbackElement,
927                    kFirstArgument)
928  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
929      InterpreterPushArgsAndConstructArrayDescriptor, CallInterfaceDescriptor)
930};
931
932class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
933 public:
934  DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunctionEntry)
935  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterCEntryDescriptor,
936                                               CallInterfaceDescriptor)
937};
938
939class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
940 public:
941  DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
942};
943
944class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
945  DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FrameDropperTrampolineDescriptor,
946                                               CallInterfaceDescriptor)
947};
948
949class PromiseHandleRejectDescriptor final : public CallInterfaceDescriptor {
950 public:
951  DEFINE_PARAMETERS(kPromise, kOnReject, kException)
952  DECLARE_DEFAULT_DESCRIPTOR(PromiseHandleRejectDescriptor,
953                             CallInterfaceDescriptor, kParameterCount)
954};
955
956class WasmRuntimeCallDescriptor final : public CallInterfaceDescriptor {
957 public:
958  DECLARE_DEFAULT_DESCRIPTOR(WasmRuntimeCallDescriptor, CallInterfaceDescriptor,
959                             0)
960};
961
962#undef DECLARE_DESCRIPTOR_WITH_BASE
963#undef DECLARE_DESCRIPTOR
964#undef DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE
965#undef DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG
966#undef DEFINE_PARAMETERS
967
968// We define the association between CallDescriptors::Key and the specialized
969// descriptor here to reduce boilerplate and mistakes.
970#define DEF_KEY(name) \
971  CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
972INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
973#undef DEF_KEY
974}  // namespace internal
975}  // namespace v8
976
977
978#if V8_TARGET_ARCH_ARM64
979#include "src/arm64/interface-descriptors-arm64.h"
980#elif V8_TARGET_ARCH_ARM
981#include "src/arm/interface-descriptors-arm.h"
982#endif
983
984#endif  // V8_CALL_INTERFACE_DESCRIPTOR_H_
985