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#include "src/compiler/js-operator.h"
6
7#include <limits>
8
9#include "src/base/lazy-instance.h"
10#include "src/compiler/opcodes.h"
11#include "src/compiler/operator.h"
12#include "src/handles-inl.h"
13#include "src/type-feedback-vector.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
19VectorSlotPair::VectorSlotPair() {}
20
21
22int VectorSlotPair::index() const {
23  return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
24}
25
26
27bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
28  return lhs.slot() == rhs.slot() &&
29         lhs.vector().location() == rhs.vector().location();
30}
31
32
33bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
34  return !(lhs == rhs);
35}
36
37
38size_t hash_value(VectorSlotPair const& p) {
39  return base::hash_combine(p.slot(), p.vector().location());
40}
41
42
43ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
44  DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode());
45  return OpParameter<ConvertReceiverMode>(op);
46}
47
48
49ToBooleanHints ToBooleanHintsOf(Operator const* op) {
50  DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode());
51  return OpParameter<ToBooleanHints>(op);
52}
53
54
55bool operator==(CallConstructParameters const& lhs,
56                CallConstructParameters const& rhs) {
57  return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() &&
58         lhs.feedback() == rhs.feedback();
59}
60
61
62bool operator!=(CallConstructParameters const& lhs,
63                CallConstructParameters const& rhs) {
64  return !(lhs == rhs);
65}
66
67
68size_t hash_value(CallConstructParameters const& p) {
69  return base::hash_combine(p.arity(), p.frequency(), p.feedback());
70}
71
72
73std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) {
74  return os << p.arity() << ", " << p.frequency();
75}
76
77
78CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
79  DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode());
80  return OpParameter<CallConstructParameters>(op);
81}
82
83
84std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
85  os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode() << ", "
86     << p.tail_call_mode();
87  return os;
88}
89
90
91const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
92  DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
93  return OpParameter<CallFunctionParameters>(op);
94}
95
96
97bool operator==(CallRuntimeParameters const& lhs,
98                CallRuntimeParameters const& rhs) {
99  return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
100}
101
102
103bool operator!=(CallRuntimeParameters const& lhs,
104                CallRuntimeParameters const& rhs) {
105  return !(lhs == rhs);
106}
107
108
109size_t hash_value(CallRuntimeParameters const& p) {
110  return base::hash_combine(p.id(), p.arity());
111}
112
113
114std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
115  return os << p.id() << ", " << p.arity();
116}
117
118
119const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
120  DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
121  return OpParameter<CallRuntimeParameters>(op);
122}
123
124
125ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
126    : immutable_(immutable),
127      depth_(static_cast<uint16_t>(depth)),
128      index_(static_cast<uint32_t>(index)) {
129  DCHECK(depth <= std::numeric_limits<uint16_t>::max());
130  DCHECK(index <= std::numeric_limits<uint32_t>::max());
131}
132
133
134bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
135  return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
136         lhs.immutable() == rhs.immutable();
137}
138
139
140bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
141  return !(lhs == rhs);
142}
143
144
145size_t hash_value(ContextAccess const& access) {
146  return base::hash_combine(access.depth(), access.index(), access.immutable());
147}
148
149
150std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
151  return os << access.depth() << ", " << access.index() << ", "
152            << access.immutable();
153}
154
155
156ContextAccess const& ContextAccessOf(Operator const* op) {
157  DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
158         op->opcode() == IrOpcode::kJSStoreContext);
159  return OpParameter<ContextAccess>(op);
160}
161
162CreateCatchContextParameters::CreateCatchContextParameters(
163    Handle<String> catch_name, Handle<ScopeInfo> scope_info)
164    : catch_name_(catch_name), scope_info_(scope_info) {}
165
166bool operator==(CreateCatchContextParameters const& lhs,
167                CreateCatchContextParameters const& rhs) {
168  return lhs.catch_name().location() == rhs.catch_name().location() &&
169         lhs.scope_info().location() == rhs.scope_info().location();
170}
171
172bool operator!=(CreateCatchContextParameters const& lhs,
173                CreateCatchContextParameters const& rhs) {
174  return !(lhs == rhs);
175}
176
177size_t hash_value(CreateCatchContextParameters const& parameters) {
178  return base::hash_combine(parameters.catch_name().location(),
179                            parameters.scope_info().location());
180}
181
182std::ostream& operator<<(std::ostream& os,
183                         CreateCatchContextParameters const& parameters) {
184  return os << Brief(*parameters.catch_name()) << ", "
185            << Brief(*parameters.scope_info());
186}
187
188CreateCatchContextParameters const& CreateCatchContextParametersOf(
189    Operator const* op) {
190  DCHECK_EQ(IrOpcode::kJSCreateCatchContext, op->opcode());
191  return OpParameter<CreateCatchContextParameters>(op);
192}
193
194bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
195  return lhs.name().location() == rhs.name().location() &&
196         lhs.language_mode() == rhs.language_mode() &&
197         lhs.feedback() == rhs.feedback();
198}
199
200
201bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
202  return !(lhs == rhs);
203}
204
205
206size_t hash_value(NamedAccess const& p) {
207  return base::hash_combine(p.name().location(), p.language_mode(),
208                            p.feedback());
209}
210
211
212std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
213  return os << Brief(*p.name()) << ", " << p.language_mode();
214}
215
216
217NamedAccess const& NamedAccessOf(const Operator* op) {
218  DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
219         op->opcode() == IrOpcode::kJSStoreNamed);
220  return OpParameter<NamedAccess>(op);
221}
222
223
224std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
225  return os << p.language_mode();
226}
227
228
229bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
230  return lhs.language_mode() == rhs.language_mode() &&
231         lhs.feedback() == rhs.feedback();
232}
233
234
235bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
236  return !(lhs == rhs);
237}
238
239
240PropertyAccess const& PropertyAccessOf(const Operator* op) {
241  DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
242         op->opcode() == IrOpcode::kJSStoreProperty);
243  return OpParameter<PropertyAccess>(op);
244}
245
246
247size_t hash_value(PropertyAccess const& p) {
248  return base::hash_combine(p.language_mode(), p.feedback());
249}
250
251
252bool operator==(LoadGlobalParameters const& lhs,
253                LoadGlobalParameters const& rhs) {
254  return lhs.name().location() == rhs.name().location() &&
255         lhs.feedback() == rhs.feedback() &&
256         lhs.typeof_mode() == rhs.typeof_mode();
257}
258
259
260bool operator!=(LoadGlobalParameters const& lhs,
261                LoadGlobalParameters const& rhs) {
262  return !(lhs == rhs);
263}
264
265
266size_t hash_value(LoadGlobalParameters const& p) {
267  return base::hash_combine(p.name().location(), p.typeof_mode());
268}
269
270
271std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
272  return os << Brief(*p.name()) << ", " << p.typeof_mode();
273}
274
275
276const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
277  DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
278  return OpParameter<LoadGlobalParameters>(op);
279}
280
281
282bool operator==(StoreGlobalParameters const& lhs,
283                StoreGlobalParameters const& rhs) {
284  return lhs.language_mode() == rhs.language_mode() &&
285         lhs.name().location() == rhs.name().location() &&
286         lhs.feedback() == rhs.feedback();
287}
288
289
290bool operator!=(StoreGlobalParameters const& lhs,
291                StoreGlobalParameters const& rhs) {
292  return !(lhs == rhs);
293}
294
295
296size_t hash_value(StoreGlobalParameters const& p) {
297  return base::hash_combine(p.language_mode(), p.name().location(),
298                            p.feedback());
299}
300
301
302std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
303  return os << p.language_mode() << ", " << Brief(*p.name());
304}
305
306
307const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
308  DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
309  return OpParameter<StoreGlobalParameters>(op);
310}
311
312
313CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) {
314  DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
315  return OpParameter<CreateArgumentsType>(op);
316}
317
318
319bool operator==(CreateArrayParameters const& lhs,
320                CreateArrayParameters const& rhs) {
321  return lhs.arity() == rhs.arity() &&
322         lhs.site().location() == rhs.site().location();
323}
324
325
326bool operator!=(CreateArrayParameters const& lhs,
327                CreateArrayParameters const& rhs) {
328  return !(lhs == rhs);
329}
330
331
332size_t hash_value(CreateArrayParameters const& p) {
333  return base::hash_combine(p.arity(), p.site().location());
334}
335
336
337std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
338  os << p.arity();
339  if (!p.site().is_null()) os << ", " << Brief(*p.site());
340  return os;
341}
342
343
344const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
345  DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
346  return OpParameter<CreateArrayParameters>(op);
347}
348
349
350bool operator==(CreateClosureParameters const& lhs,
351                CreateClosureParameters const& rhs) {
352  return lhs.pretenure() == rhs.pretenure() &&
353         lhs.shared_info().location() == rhs.shared_info().location();
354}
355
356
357bool operator!=(CreateClosureParameters const& lhs,
358                CreateClosureParameters const& rhs) {
359  return !(lhs == rhs);
360}
361
362
363size_t hash_value(CreateClosureParameters const& p) {
364  return base::hash_combine(p.pretenure(), p.shared_info().location());
365}
366
367
368std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
369  return os << p.pretenure() << ", " << Brief(*p.shared_info());
370}
371
372
373const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
374  DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
375  return OpParameter<CreateClosureParameters>(op);
376}
377
378
379bool operator==(CreateLiteralParameters const& lhs,
380                CreateLiteralParameters const& rhs) {
381  return lhs.constant().location() == rhs.constant().location() &&
382         lhs.length() == rhs.length() && lhs.flags() == rhs.flags() &&
383         lhs.index() == rhs.index();
384}
385
386
387bool operator!=(CreateLiteralParameters const& lhs,
388                CreateLiteralParameters const& rhs) {
389  return !(lhs == rhs);
390}
391
392
393size_t hash_value(CreateLiteralParameters const& p) {
394  return base::hash_combine(p.constant().location(), p.length(), p.flags(),
395                            p.index());
396}
397
398
399std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
400  return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags()
401            << ", " << p.index();
402}
403
404
405const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
406  DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
407         op->opcode() == IrOpcode::kJSCreateLiteralObject ||
408         op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
409  return OpParameter<CreateLiteralParameters>(op);
410}
411
412BinaryOperationHint BinaryOperationHintOf(const Operator* op) {
413  DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
414         op->opcode() == IrOpcode::kJSBitwiseXor ||
415         op->opcode() == IrOpcode::kJSBitwiseAnd ||
416         op->opcode() == IrOpcode::kJSShiftLeft ||
417         op->opcode() == IrOpcode::kJSShiftRight ||
418         op->opcode() == IrOpcode::kJSShiftRightLogical ||
419         op->opcode() == IrOpcode::kJSAdd ||
420         op->opcode() == IrOpcode::kJSSubtract ||
421         op->opcode() == IrOpcode::kJSMultiply ||
422         op->opcode() == IrOpcode::kJSDivide ||
423         op->opcode() == IrOpcode::kJSModulus);
424  return OpParameter<BinaryOperationHint>(op);
425}
426
427CompareOperationHint CompareOperationHintOf(const Operator* op) {
428  DCHECK(op->opcode() == IrOpcode::kJSEqual ||
429         op->opcode() == IrOpcode::kJSNotEqual ||
430         op->opcode() == IrOpcode::kJSStrictEqual ||
431         op->opcode() == IrOpcode::kJSStrictNotEqual ||
432         op->opcode() == IrOpcode::kJSLessThan ||
433         op->opcode() == IrOpcode::kJSGreaterThan ||
434         op->opcode() == IrOpcode::kJSLessThanOrEqual ||
435         op->opcode() == IrOpcode::kJSGreaterThanOrEqual);
436  return OpParameter<CompareOperationHint>(op);
437}
438
439#define CACHED_OP_LIST(V)                                   \
440  V(ToInteger, Operator::kNoProperties, 1, 1)               \
441  V(ToLength, Operator::kNoProperties, 1, 1)                \
442  V(ToName, Operator::kNoProperties, 1, 1)                  \
443  V(ToNumber, Operator::kNoProperties, 1, 1)                \
444  V(ToObject, Operator::kFoldable, 1, 1)                    \
445  V(ToString, Operator::kNoProperties, 1, 1)                \
446  V(Create, Operator::kEliminatable, 2, 1)                  \
447  V(CreateIterResultObject, Operator::kEliminatable, 2, 1)  \
448  V(CreateKeyValueArray, Operator::kEliminatable, 2, 1)     \
449  V(HasProperty, Operator::kNoProperties, 2, 1)             \
450  V(TypeOf, Operator::kPure, 1, 1)                          \
451  V(InstanceOf, Operator::kNoProperties, 2, 1)              \
452  V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1)     \
453  V(ForInNext, Operator::kNoProperties, 4, 1)               \
454  V(ForInPrepare, Operator::kNoProperties, 1, 3)            \
455  V(LoadMessage, Operator::kNoThrow, 0, 1)                  \
456  V(StoreMessage, Operator::kNoThrow, 1, 0)                 \
457  V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
458  V(StackCheck, Operator::kNoWrite, 0, 0)
459
460#define BINARY_OP_LIST(V) \
461  V(BitwiseOr)            \
462  V(BitwiseXor)           \
463  V(BitwiseAnd)           \
464  V(ShiftLeft)            \
465  V(ShiftRight)           \
466  V(ShiftRightLogical)    \
467  V(Add)                  \
468  V(Subtract)             \
469  V(Multiply)             \
470  V(Divide)               \
471  V(Modulus)
472
473#define COMPARE_OP_LIST(V)                    \
474  V(Equal, Operator::kNoProperties)           \
475  V(NotEqual, Operator::kNoProperties)        \
476  V(StrictEqual, Operator::kPure)             \
477  V(StrictNotEqual, Operator::kPure)          \
478  V(LessThan, Operator::kNoProperties)        \
479  V(GreaterThan, Operator::kNoProperties)     \
480  V(LessThanOrEqual, Operator::kNoProperties) \
481  V(GreaterThanOrEqual, Operator::kNoProperties)
482
483struct JSOperatorGlobalCache final {
484#define CACHED_OP(Name, properties, value_input_count, value_output_count) \
485  struct Name##Operator final : public Operator {                          \
486    Name##Operator()                                                       \
487        : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,            \
488                   value_input_count, Operator::ZeroIfPure(properties),    \
489                   Operator::ZeroIfEliminatable(properties),               \
490                   value_output_count, Operator::ZeroIfPure(properties),   \
491                   Operator::ZeroIfNoThrow(properties)) {}                 \
492  };                                                                       \
493  Name##Operator k##Name##Operator;
494  CACHED_OP_LIST(CACHED_OP)
495#undef CACHED_OP
496
497#define BINARY_OP(Name)                                                       \
498  template <BinaryOperationHint kHint>                                        \
499  struct Name##Operator final : public Operator1<BinaryOperationHint> {       \
500    Name##Operator()                                                          \
501        : Operator1<BinaryOperationHint>(IrOpcode::kJS##Name,                 \
502                                         Operator::kNoProperties, "JS" #Name, \
503                                         2, 1, 1, 1, 1, 2, kHint) {}          \
504  };                                                                          \
505  Name##Operator<BinaryOperationHint::kNone> k##Name##NoneOperator;           \
506  Name##Operator<BinaryOperationHint::kSignedSmall>                           \
507      k##Name##SignedSmallOperator;                                           \
508  Name##Operator<BinaryOperationHint::kSigned32> k##Name##Signed32Operator;   \
509  Name##Operator<BinaryOperationHint::kNumberOrOddball>                       \
510      k##Name##NumberOrOddballOperator;                                       \
511  Name##Operator<BinaryOperationHint::kString> k##Name##StringOperator;       \
512  Name##Operator<BinaryOperationHint::kAny> k##Name##AnyOperator;
513  BINARY_OP_LIST(BINARY_OP)
514#undef BINARY_OP
515
516#define COMPARE_OP(Name, properties)                                      \
517  template <CompareOperationHint kHint>                                   \
518  struct Name##Operator final : public Operator1<CompareOperationHint> {  \
519    Name##Operator()                                                      \
520        : Operator1<CompareOperationHint>(                                \
521              IrOpcode::kJS##Name, properties, "JS" #Name, 2, 1, 1, 1, 1, \
522              Operator::ZeroIfNoThrow(properties), kHint) {}              \
523  };                                                                      \
524  Name##Operator<CompareOperationHint::kNone> k##Name##NoneOperator;      \
525  Name##Operator<CompareOperationHint::kSignedSmall>                      \
526      k##Name##SignedSmallOperator;                                       \
527  Name##Operator<CompareOperationHint::kNumber> k##Name##NumberOperator;  \
528  Name##Operator<CompareOperationHint::kNumberOrOddball>                  \
529      k##Name##NumberOrOddballOperator;                                   \
530  Name##Operator<CompareOperationHint::kAny> k##Name##AnyOperator;
531  COMPARE_OP_LIST(COMPARE_OP)
532#undef COMPARE_OP
533};
534
535static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
536    LAZY_INSTANCE_INITIALIZER;
537
538JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
539    : cache_(kCache.Get()), zone_(zone) {}
540
541#define CACHED_OP(Name, properties, value_input_count, value_output_count) \
542  const Operator* JSOperatorBuilder::Name() {                              \
543    return &cache_.k##Name##Operator;                                      \
544  }
545CACHED_OP_LIST(CACHED_OP)
546#undef CACHED_OP
547
548#define BINARY_OP(Name)                                               \
549  const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \
550    switch (hint) {                                                   \
551      case BinaryOperationHint::kNone:                                \
552        return &cache_.k##Name##NoneOperator;                         \
553      case BinaryOperationHint::kSignedSmall:                         \
554        return &cache_.k##Name##SignedSmallOperator;                  \
555      case BinaryOperationHint::kSigned32:                            \
556        return &cache_.k##Name##Signed32Operator;                     \
557      case BinaryOperationHint::kNumberOrOddball:                     \
558        return &cache_.k##Name##NumberOrOddballOperator;              \
559      case BinaryOperationHint::kString:                              \
560        return &cache_.k##Name##StringOperator;                       \
561      case BinaryOperationHint::kAny:                                 \
562        return &cache_.k##Name##AnyOperator;                          \
563    }                                                                 \
564    UNREACHABLE();                                                    \
565    return nullptr;                                                   \
566  }
567BINARY_OP_LIST(BINARY_OP)
568#undef BINARY_OP
569
570#define COMPARE_OP(Name, ...)                                          \
571  const Operator* JSOperatorBuilder::Name(CompareOperationHint hint) { \
572    switch (hint) {                                                    \
573      case CompareOperationHint::kNone:                                \
574        return &cache_.k##Name##NoneOperator;                          \
575      case CompareOperationHint::kSignedSmall:                         \
576        return &cache_.k##Name##SignedSmallOperator;                   \
577      case CompareOperationHint::kNumber:                              \
578        return &cache_.k##Name##NumberOperator;                        \
579      case CompareOperationHint::kNumberOrOddball:                     \
580        return &cache_.k##Name##NumberOrOddballOperator;               \
581      case CompareOperationHint::kAny:                                 \
582        return &cache_.k##Name##AnyOperator;                           \
583    }                                                                  \
584    UNREACHABLE();                                                     \
585    return nullptr;                                                    \
586  }
587COMPARE_OP_LIST(COMPARE_OP)
588#undef COMPARE_OP
589
590const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
591  // TODO(turbofan): Cache most important versions of this operator.
592  return new (zone()) Operator1<ToBooleanHints>(  //--
593      IrOpcode::kJSToBoolean, Operator::kPure,    // opcode
594      "JSToBoolean",                              // name
595      1, 0, 0, 1, 0, 0,                           // inputs/outputs
596      hints);                                     // parameter
597}
598
599const Operator* JSOperatorBuilder::CallFunction(
600    size_t arity, float frequency, VectorSlotPair const& feedback,
601    ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
602  CallFunctionParameters parameters(arity, frequency, feedback, tail_call_mode,
603                                    convert_mode);
604  return new (zone()) Operator1<CallFunctionParameters>(   // --
605      IrOpcode::kJSCallFunction, Operator::kNoProperties,  // opcode
606      "JSCallFunction",                                    // name
607      parameters.arity(), 1, 1, 1, 1, 2,                   // inputs/outputs
608      parameters);                                         // parameter
609}
610
611
612const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) {
613  const Runtime::Function* f = Runtime::FunctionForId(id);
614  return CallRuntime(f, f->nargs);
615}
616
617
618const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
619                                               size_t arity) {
620  const Runtime::Function* f = Runtime::FunctionForId(id);
621  return CallRuntime(f, arity);
622}
623
624
625const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f,
626                                               size_t arity) {
627  CallRuntimeParameters parameters(f->function_id, arity);
628  DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
629  return new (zone()) Operator1<CallRuntimeParameters>(   // --
630      IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
631      "JSCallRuntime",                                    // name
632      parameters.arity(), 1, 1, f->result_size, 1, 2,     // inputs/outputs
633      parameters);                                        // parameter
634}
635
636const Operator* JSOperatorBuilder::CallConstruct(
637    uint32_t arity, float frequency, VectorSlotPair const& feedback) {
638  CallConstructParameters parameters(arity, frequency, feedback);
639  return new (zone()) Operator1<CallConstructParameters>(   // --
640      IrOpcode::kJSCallConstruct, Operator::kNoProperties,  // opcode
641      "JSCallConstruct",                                    // name
642      parameters.arity(), 1, 1, 1, 1, 2,                    // counts
643      parameters);                                          // parameter
644}
645
646
647const Operator* JSOperatorBuilder::ConvertReceiver(
648    ConvertReceiverMode convert_mode) {
649  return new (zone()) Operator1<ConvertReceiverMode>(         // --
650      IrOpcode::kJSConvertReceiver, Operator::kEliminatable,  // opcode
651      "JSConvertReceiver",                                    // name
652      1, 1, 1, 1, 1, 0,                                       // counts
653      convert_mode);                                          // parameter
654}
655
656const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name,
657                                             const VectorSlotPair& feedback) {
658  NamedAccess access(SLOPPY, name, feedback);
659  return new (zone()) Operator1<NamedAccess>(           // --
660      IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
661      "JSLoadNamed",                                    // name
662      2, 1, 1, 1, 1, 2,                                 // counts
663      access);                                          // parameter
664}
665
666const Operator* JSOperatorBuilder::LoadProperty(
667    VectorSlotPair const& feedback) {
668  PropertyAccess access(SLOPPY, feedback);
669  return new (zone()) Operator1<PropertyAccess>(           // --
670      IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
671      "JSLoadProperty",                                    // name
672      3, 1, 1, 1, 1, 2,                                    // counts
673      access);                                             // parameter
674}
675
676const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
677  return new (zone()) Operator1<int>(                   // --
678      IrOpcode::kJSGeneratorStore, Operator::kNoThrow,  // opcode
679      "JSGeneratorStore",                               // name
680      3 + register_count, 1, 1, 0, 1, 0,                // counts
681      register_count);                                  // parameter
682}
683
684const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) {
685  return new (zone()) Operator1<int>(                             // --
686      IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow,  // opcode
687      "JSGeneratorRestoreRegister",                               // name
688      1, 1, 1, 1, 1, 0,                                           // counts
689      index);                                                     // parameter
690}
691
692const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
693                                              Handle<Name> name,
694                                              VectorSlotPair const& feedback) {
695  NamedAccess access(language_mode, name, feedback);
696  return new (zone()) Operator1<NamedAccess>(            // --
697      IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
698      "JSStoreNamed",                                    // name
699      3, 1, 1, 0, 1, 2,                                  // counts
700      access);                                           // parameter
701}
702
703
704const Operator* JSOperatorBuilder::StoreProperty(
705    LanguageMode language_mode, VectorSlotPair const& feedback) {
706  PropertyAccess access(language_mode, feedback);
707  return new (zone()) Operator1<PropertyAccess>(            // --
708      IrOpcode::kJSStoreProperty, Operator::kNoProperties,  // opcode
709      "JSStoreProperty",                                    // name
710      4, 1, 1, 0, 1, 2,                                     // counts
711      access);                                              // parameter
712}
713
714
715const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
716  return new (zone()) Operator1<LanguageMode>(               // --
717      IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
718      "JSDeleteProperty",                                    // name
719      2, 1, 1, 1, 1, 2,                                      // counts
720      language_mode);                                        // parameter
721}
722
723
724const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
725                                              const VectorSlotPair& feedback,
726                                              TypeofMode typeof_mode) {
727  LoadGlobalParameters parameters(name, feedback, typeof_mode);
728  return new (zone()) Operator1<LoadGlobalParameters>(   // --
729      IrOpcode::kJSLoadGlobal, Operator::kNoProperties,  // opcode
730      "JSLoadGlobal",                                    // name
731      1, 1, 1, 1, 1, 2,                                  // counts
732      parameters);                                       // parameter
733}
734
735
736const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
737                                               const Handle<Name>& name,
738                                               const VectorSlotPair& feedback) {
739  StoreGlobalParameters parameters(language_mode, feedback, name);
740  return new (zone()) Operator1<StoreGlobalParameters>(   // --
741      IrOpcode::kJSStoreGlobal, Operator::kNoProperties,  // opcode
742      "JSStoreGlobal",                                    // name
743      2, 1, 1, 0, 1, 2,                                   // counts
744      parameters);                                        // parameter
745}
746
747
748const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
749                                               bool immutable) {
750  ContextAccess access(depth, index, immutable);
751  return new (zone()) Operator1<ContextAccess>(  // --
752      IrOpcode::kJSLoadContext,                  // opcode
753      Operator::kNoWrite | Operator::kNoThrow,   // flags
754      "JSLoadContext",                           // name
755      1, 1, 0, 1, 1, 0,                          // counts
756      access);                                   // parameter
757}
758
759
760const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
761  ContextAccess access(depth, index, false);
762  return new (zone()) Operator1<ContextAccess>(  // --
763      IrOpcode::kJSStoreContext,                 // opcode
764      Operator::kNoRead | Operator::kNoThrow,    // flags
765      "JSStoreContext",                          // name
766      2, 1, 1, 0, 1, 0,                          // counts
767      access);                                   // parameter
768}
769
770const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) {
771  return new (zone()) Operator1<int32_t>(       // --
772      IrOpcode::kJSLoadModule,                  // opcode
773      Operator::kNoWrite | Operator::kNoThrow,  // flags
774      "JSLoadModule",                           // name
775      1, 1, 1, 1, 1, 0,                         // counts
776      cell_index);                              // parameter
777}
778
779const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) {
780  return new (zone()) Operator1<int32_t>(      // --
781      IrOpcode::kJSStoreModule,                // opcode
782      Operator::kNoRead | Operator::kNoThrow,  // flags
783      "JSStoreModule",                         // name
784      2, 1, 1, 0, 1, 0,                        // counts
785      cell_index);                             // parameter
786}
787
788const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
789  return new (zone()) Operator1<CreateArgumentsType>(         // --
790      IrOpcode::kJSCreateArguments, Operator::kEliminatable,  // opcode
791      "JSCreateArguments",                                    // name
792      1, 1, 0, 1, 1, 0,                                       // counts
793      type);                                                  // parameter
794}
795
796
797const Operator* JSOperatorBuilder::CreateArray(size_t arity,
798                                               Handle<AllocationSite> site) {
799  // constructor, new_target, arg1, ..., argN
800  int const value_input_count = static_cast<int>(arity) + 2;
801  CreateArrayParameters parameters(arity, site);
802  return new (zone()) Operator1<CreateArrayParameters>(   // --
803      IrOpcode::kJSCreateArray, Operator::kNoProperties,  // opcode
804      "JSCreateArray",                                    // name
805      value_input_count, 1, 1, 1, 1, 2,                   // counts
806      parameters);                                        // parameter
807}
808
809
810const Operator* JSOperatorBuilder::CreateClosure(
811    Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) {
812  CreateClosureParameters parameters(shared_info, pretenure);
813  return new (zone()) Operator1<CreateClosureParameters>(  // --
814      IrOpcode::kJSCreateClosure, Operator::kNoThrow,      // opcode
815      "JSCreateClosure",                                   // name
816      0, 1, 1, 1, 1, 0,                                    // counts
817      parameters);                                         // parameter
818}
819
820const Operator* JSOperatorBuilder::CreateLiteralArray(
821    Handle<FixedArray> constant_elements, int literal_flags, int literal_index,
822    int number_of_elements) {
823  CreateLiteralParameters parameters(constant_elements, number_of_elements,
824                                     literal_flags, literal_index);
825  return new (zone()) Operator1<CreateLiteralParameters>(        // --
826      IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties,  // opcode
827      "JSCreateLiteralArray",                                    // name
828      1, 1, 1, 1, 1, 2,                                          // counts
829      parameters);                                               // parameter
830}
831
832const Operator* JSOperatorBuilder::CreateLiteralObject(
833    Handle<FixedArray> constant_properties, int literal_flags,
834    int literal_index, int number_of_properties) {
835  CreateLiteralParameters parameters(constant_properties, number_of_properties,
836                                     literal_flags, literal_index);
837  return new (zone()) Operator1<CreateLiteralParameters>(         // --
838      IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties,  // opcode
839      "JSCreateLiteralObject",                                    // name
840      1, 1, 1, 1, 1, 2,                                           // counts
841      parameters);                                                // parameter
842}
843
844
845const Operator* JSOperatorBuilder::CreateLiteralRegExp(
846    Handle<String> constant_pattern, int literal_flags, int literal_index) {
847  CreateLiteralParameters parameters(constant_pattern, -1, literal_flags,
848                                     literal_index);
849  return new (zone()) Operator1<CreateLiteralParameters>(         // --
850      IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties,  // opcode
851      "JSCreateLiteralRegExp",                                    // name
852      1, 1, 1, 1, 1, 2,                                           // counts
853      parameters);                                                // parameter
854}
855
856
857const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) {
858  return new (zone()) Operator1<int>(                               // --
859      IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties,  // opcode
860      "JSCreateFunctionContext",                                    // name
861      1, 1, 1, 1, 1, 2,                                             // counts
862      slot_count);                                                  // parameter
863}
864
865const Operator* JSOperatorBuilder::CreateCatchContext(
866    const Handle<String>& name, const Handle<ScopeInfo>& scope_info) {
867  CreateCatchContextParameters parameters(name, scope_info);
868  return new (zone()) Operator1<CreateCatchContextParameters>(
869      IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
870      "JSCreateCatchContext",                                    // name
871      2, 1, 1, 1, 1, 2,                                          // counts
872      parameters);                                               // parameter
873}
874
875const Operator* JSOperatorBuilder::CreateWithContext(
876    const Handle<ScopeInfo>& scope_info) {
877  return new (zone()) Operator1<Handle<ScopeInfo>>(
878      IrOpcode::kJSCreateWithContext, Operator::kNoProperties,  // opcode
879      "JSCreateWithContext",                                    // name
880      2, 1, 1, 1, 1, 2,                                         // counts
881      scope_info);                                              // parameter
882}
883
884const Operator* JSOperatorBuilder::CreateBlockContext(
885    const Handle<ScopeInfo>& scpope_info) {
886  return new (zone()) Operator1<Handle<ScopeInfo>>(              // --
887      IrOpcode::kJSCreateBlockContext, Operator::kNoProperties,  // opcode
888      "JSCreateBlockContext",                                    // name
889      1, 1, 1, 1, 1, 2,                                          // counts
890      scpope_info);                                              // parameter
891}
892
893
894const Operator* JSOperatorBuilder::CreateScriptContext(
895    const Handle<ScopeInfo>& scpope_info) {
896  return new (zone()) Operator1<Handle<ScopeInfo>>(               // --
897      IrOpcode::kJSCreateScriptContext, Operator::kNoProperties,  // opcode
898      "JSCreateScriptContext",                                    // name
899      1, 1, 1, 1, 1, 2,                                           // counts
900      scpope_info);                                               // parameter
901}
902
903}  // namespace compiler
904}  // namespace internal
905}  // namespace v8
906