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