1 // Copyright 2013 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_COMPILER_JS_OPERATOR_H_
6 #define V8_COMPILER_JS_OPERATOR_H_
7
8 #include "src/base/compiler-specific.h"
9 #include "src/codegen/tnode.h"
10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/feedback-source.h"
12 #include "src/compiler/globals.h"
13 #include "src/compiler/node-properties.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/opcodes.h"
16 #include "src/handles/maybe-handles.h"
17 #include "src/objects/type-hints.h"
18 #include "src/runtime/runtime.h"
19
20 namespace v8 {
21 namespace internal {
22
23 class AllocationSite;
24 class ObjectBoilerplateDescription;
25 class ArrayBoilerplateDescription;
26 class FeedbackCell;
27 class SharedFunctionInfo;
28
29 namespace wasm {
30 class ValueType;
31 }
32
33 namespace compiler {
34
35 // Forward declarations.
36 class JSGraph;
37 class Operator;
38 struct JSOperatorGlobalCache;
39
40 // Macro lists.
41 #define JS_UNOP_WITH_FEEDBACK(V) \
42 JS_BITWISE_UNOP_LIST(V) \
43 JS_ARITH_UNOP_LIST(V)
44
45 #define JS_BINOP_WITH_FEEDBACK(V) \
46 JS_ARITH_BINOP_LIST(V) \
47 JS_BITWISE_BINOP_LIST(V) \
48 JS_COMPARE_BINOP_LIST(V) \
49 V(JSInstanceOf, InstanceOf)
50
51 // Predicates.
52 class JSOperator final : public AllStatic {
53 public:
IsUnaryWithFeedback(Operator::Opcode opcode)54 static constexpr bool IsUnaryWithFeedback(Operator::Opcode opcode) {
55 #define CASE(Name, ...) \
56 case IrOpcode::k##Name: \
57 return true;
58 switch (opcode) {
59 JS_UNOP_WITH_FEEDBACK(CASE);
60 default:
61 return false;
62 }
63 #undef CASE
64 return false;
65 }
66
IsBinaryWithFeedback(Operator::Opcode opcode)67 static constexpr bool IsBinaryWithFeedback(Operator::Opcode opcode) {
68 #define CASE(Name, ...) \
69 case IrOpcode::k##Name: \
70 return true;
71 switch (opcode) {
72 JS_BINOP_WITH_FEEDBACK(CASE);
73 default:
74 return false;
75 }
76 #undef CASE
77 return false;
78 }
79 };
80
81 // Defines the frequency a given Call/Construct site was executed. For some
82 // call sites the frequency is not known.
83 class CallFrequency final {
84 public:
CallFrequency()85 CallFrequency() : value_(std::numeric_limits<float>::quiet_NaN()) {}
CallFrequency(float value)86 explicit CallFrequency(float value) : value_(value) {
87 DCHECK(!std::isnan(value));
88 }
89
IsKnown()90 bool IsKnown() const { return !IsUnknown(); }
IsUnknown()91 bool IsUnknown() const { return std::isnan(value_); }
value()92 float value() const {
93 DCHECK(IsKnown());
94 return value_;
95 }
96
97 bool operator==(CallFrequency const& that) const {
98 return bit_cast<uint32_t>(this->value_) == bit_cast<uint32_t>(that.value_);
99 }
100 bool operator!=(CallFrequency const& that) const { return !(*this == that); }
101
hash_value(CallFrequency const & f)102 friend size_t hash_value(CallFrequency const& f) {
103 return bit_cast<uint32_t>(f.value_);
104 }
105
106 static constexpr float kNoFeedbackCallFrequency = -1;
107
108 private:
109 float value_;
110 };
111
112 std::ostream& operator<<(std::ostream&, CallFrequency const&);
113
114 // Defines the flags for a JavaScript call forwarding parameters. This
115 // is used as parameter by JSConstructForwardVarargs operators.
116 class ConstructForwardVarargsParameters final {
117 public:
ConstructForwardVarargsParameters(size_t arity,uint32_t start_index)118 ConstructForwardVarargsParameters(size_t arity, uint32_t start_index)
119 : bit_field_(ArityField::encode(arity) |
120 StartIndexField::encode(start_index)) {}
121
arity()122 size_t arity() const { return ArityField::decode(bit_field_); }
start_index()123 uint32_t start_index() const { return StartIndexField::decode(bit_field_); }
124
125 bool operator==(ConstructForwardVarargsParameters const& that) const {
126 return this->bit_field_ == that.bit_field_;
127 }
128 bool operator!=(ConstructForwardVarargsParameters const& that) const {
129 return !(*this == that);
130 }
131
132 private:
hash_value(ConstructForwardVarargsParameters const & p)133 friend size_t hash_value(ConstructForwardVarargsParameters const& p) {
134 return p.bit_field_;
135 }
136
137 using ArityField = base::BitField<size_t, 0, 16>;
138 using StartIndexField = base::BitField<uint32_t, 16, 16>;
139
140 uint32_t const bit_field_;
141 };
142
143 std::ostream& operator<<(std::ostream&,
144 ConstructForwardVarargsParameters const&);
145
146 ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf(
147 Operator const*) V8_WARN_UNUSED_RESULT;
148
149 // Defines the arity (parameters plus the target and new target) and the
150 // feedback for a JavaScript constructor call. This is used as a parameter by
151 // JSConstruct, JSConstructWithArrayLike, and JSConstructWithSpread operators.
152 class ConstructParameters final {
153 public:
154 // A separate declaration to get around circular declaration dependencies.
155 // Checked to equal JSConstructNode::kExtraInputCount below.
156 static constexpr int kExtraConstructInputCount = 3;
157
ConstructParameters(uint32_t arity,CallFrequency const & frequency,FeedbackSource const & feedback)158 ConstructParameters(uint32_t arity, CallFrequency const& frequency,
159 FeedbackSource const& feedback)
160 : arity_(arity), frequency_(frequency), feedback_(feedback) {
161 DCHECK_GE(arity, kExtraConstructInputCount);
162 DCHECK(is_int32(arity));
163 }
164
165 // TODO(jgruber): Consider removing `arity()` and just storing the arity
166 // without extra args in ConstructParameters. Every spot that creates
167 // ConstructParameters artifically adds the extra args. Every spot that uses
168 // ConstructParameters artificially subtracts the extra args.
169 // We keep them for now for consistency with other spots
170 // that expect `arity()` to include extra args.
arity()171 uint32_t arity() const { return arity_; }
arity_without_implicit_args()172 int arity_without_implicit_args() const {
173 return static_cast<int>(arity_ - kExtraConstructInputCount);
174 }
175
frequency()176 CallFrequency const& frequency() const { return frequency_; }
feedback()177 FeedbackSource const& feedback() const { return feedback_; }
178
179 private:
180 uint32_t const arity_;
181 CallFrequency const frequency_;
182 FeedbackSource const feedback_;
183 };
184
185 bool operator==(ConstructParameters const&, ConstructParameters const&);
186 bool operator!=(ConstructParameters const&, ConstructParameters const&);
187
188 size_t hash_value(ConstructParameters const&);
189
190 std::ostream& operator<<(std::ostream&, ConstructParameters const&);
191
192 ConstructParameters const& ConstructParametersOf(Operator const*);
193
194 // Defines the flags for a JavaScript call forwarding parameters. This
195 // is used as parameter by JSCallForwardVarargs operators.
196 class CallForwardVarargsParameters final {
197 public:
CallForwardVarargsParameters(size_t arity,uint32_t start_index)198 CallForwardVarargsParameters(size_t arity, uint32_t start_index)
199 : bit_field_(ArityField::encode(arity) |
200 StartIndexField::encode(start_index)) {}
201
arity()202 size_t arity() const { return ArityField::decode(bit_field_); }
start_index()203 uint32_t start_index() const { return StartIndexField::decode(bit_field_); }
204
205 bool operator==(CallForwardVarargsParameters const& that) const {
206 return this->bit_field_ == that.bit_field_;
207 }
208 bool operator!=(CallForwardVarargsParameters const& that) const {
209 return !(*this == that);
210 }
211
212 private:
hash_value(CallForwardVarargsParameters const & p)213 friend size_t hash_value(CallForwardVarargsParameters const& p) {
214 return p.bit_field_;
215 }
216
217 using ArityField = base::BitField<size_t, 0, 15>;
218 using StartIndexField = base::BitField<uint32_t, 15, 15>;
219
220 uint32_t const bit_field_;
221 };
222
223 std::ostream& operator<<(std::ostream&, CallForwardVarargsParameters const&);
224
225 CallForwardVarargsParameters const& CallForwardVarargsParametersOf(
226 Operator const*) V8_WARN_UNUSED_RESULT;
227
228 // Defines the arity (parameters plus the target and receiver) and the call
229 // flags for a JavaScript function call. This is used as a parameter by JSCall,
230 // JSCallWithArrayLike and JSCallWithSpread operators.
231 class CallParameters final {
232 public:
233 // A separate declaration to get around circular declaration dependencies.
234 // Checked to equal JSCallNode::kExtraInputCount below.
235 static constexpr int kExtraCallInputCount = 3;
236
CallParameters(size_t arity,CallFrequency const & frequency,FeedbackSource const & feedback,ConvertReceiverMode convert_mode,SpeculationMode speculation_mode,CallFeedbackRelation feedback_relation)237 CallParameters(size_t arity, CallFrequency const& frequency,
238 FeedbackSource const& feedback,
239 ConvertReceiverMode convert_mode,
240 SpeculationMode speculation_mode,
241 CallFeedbackRelation feedback_relation)
242 : bit_field_(ArityField::encode(arity) |
243 CallFeedbackRelationField::encode(feedback_relation) |
244 SpeculationModeField::encode(speculation_mode) |
245 ConvertReceiverModeField::encode(convert_mode)),
246 frequency_(frequency),
247 feedback_(feedback) {
248 // CallFeedbackRelation is ignored if the feedback slot is invalid.
249 DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
250 feedback.IsValid());
251 DCHECK_IMPLIES(!feedback.IsValid(),
252 feedback_relation == CallFeedbackRelation::kUnrelated);
253 DCHECK_GE(arity, kExtraCallInputCount);
254 DCHECK(is_int32(arity));
255 }
256
257 // TODO(jgruber): Consider removing `arity()` and just storing the arity
258 // without extra args in CallParameters.
arity()259 size_t arity() const { return ArityField::decode(bit_field_); }
arity_without_implicit_args()260 int arity_without_implicit_args() const {
261 return static_cast<int>(arity() - kExtraCallInputCount);
262 }
263
frequency()264 CallFrequency const& frequency() const { return frequency_; }
convert_mode()265 ConvertReceiverMode convert_mode() const {
266 return ConvertReceiverModeField::decode(bit_field_);
267 }
feedback()268 FeedbackSource const& feedback() const { return feedback_; }
269
speculation_mode()270 SpeculationMode speculation_mode() const {
271 return SpeculationModeField::decode(bit_field_);
272 }
273
feedback_relation()274 CallFeedbackRelation feedback_relation() const {
275 return CallFeedbackRelationField::decode(bit_field_);
276 }
277
278 bool operator==(CallParameters const& that) const {
279 return this->bit_field_ == that.bit_field_ &&
280 this->frequency_ == that.frequency_ &&
281 this->feedback_ == that.feedback_;
282 }
283 bool operator!=(CallParameters const& that) const { return !(*this == that); }
284
285 private:
hash_value(CallParameters const & p)286 friend size_t hash_value(CallParameters const& p) {
287 FeedbackSource::Hash feedback_hash;
288 return base::hash_combine(p.bit_field_, p.frequency_,
289 feedback_hash(p.feedback_));
290 }
291
292 using ArityField = base::BitField<size_t, 0, 27>;
293 using CallFeedbackRelationField = base::BitField<CallFeedbackRelation, 27, 2>;
294 using SpeculationModeField = base::BitField<SpeculationMode, 29, 1>;
295 using ConvertReceiverModeField = base::BitField<ConvertReceiverMode, 30, 2>;
296
297 uint32_t const bit_field_;
298 CallFrequency const frequency_;
299 FeedbackSource const feedback_;
300 };
301
302 size_t hash_value(CallParameters const&);
303
304 std::ostream& operator<<(std::ostream&, CallParameters const&);
305
306 const CallParameters& CallParametersOf(const Operator* op);
307
308
309 // Defines the arity and the ID for a runtime function call. This is used as a
310 // parameter by JSCallRuntime operators.
311 class V8_EXPORT_PRIVATE CallRuntimeParameters final {
312 public:
CallRuntimeParameters(Runtime::FunctionId id,size_t arity)313 CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
314 : id_(id), arity_(arity) {}
315
id()316 Runtime::FunctionId id() const { return id_; }
arity()317 size_t arity() const { return arity_; }
318
319 private:
320 const Runtime::FunctionId id_;
321 const size_t arity_;
322 };
323
324 bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
325 bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
326
327 size_t hash_value(CallRuntimeParameters const&);
328
329 std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
330
331 V8_EXPORT_PRIVATE const CallRuntimeParameters& CallRuntimeParametersOf(
332 const Operator* op);
333
334 // Defines the location of a context slot relative to a specific scope. This is
335 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
336 // accessing a context-allocated variable without keeping track of the scope.
337 class ContextAccess final {
338 public:
339 ContextAccess(size_t depth, size_t index, bool immutable);
340
depth()341 size_t depth() const { return depth_; }
index()342 size_t index() const { return index_; }
immutable()343 bool immutable() const { return immutable_; }
344
345 private:
346 // For space reasons, we keep this tightly packed, otherwise we could just use
347 // a simple int/int/bool POD.
348 const bool immutable_;
349 const uint16_t depth_;
350 const uint32_t index_;
351 };
352
353 bool operator==(ContextAccess const&, ContextAccess const&);
354 bool operator!=(ContextAccess const&, ContextAccess const&);
355
356 size_t hash_value(ContextAccess const&);
357
358 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ContextAccess const&);
359
360 V8_EXPORT_PRIVATE ContextAccess const& ContextAccessOf(Operator const*);
361
362 // Defines the slot count and ScopeType for a new function or eval context. This
363 // is used as a parameter by the JSCreateFunctionContext operator.
364 class CreateFunctionContextParameters final {
365 public:
CreateFunctionContextParameters(const ScopeInfoRef & scope_info,int slot_count,ScopeType scope_type)366 CreateFunctionContextParameters(const ScopeInfoRef& scope_info,
367 int slot_count, ScopeType scope_type)
368 : scope_info_(scope_info),
369 slot_count_(slot_count),
370 scope_type_(scope_type) {}
371
scope_info(JSHeapBroker * broker)372 ScopeInfoRef scope_info(JSHeapBroker* broker) const {
373 return scope_info_.AsRef(broker);
374 }
slot_count()375 int slot_count() const { return slot_count_; }
scope_type()376 ScopeType scope_type() const { return scope_type_; }
377
378 private:
379 const ScopeInfoTinyRef scope_info_;
380 int const slot_count_;
381 ScopeType const scope_type_;
382
383 friend bool operator==(CreateFunctionContextParameters const& lhs,
384 CreateFunctionContextParameters const& rhs);
385 friend bool operator!=(CreateFunctionContextParameters const& lhs,
386 CreateFunctionContextParameters const& rhs);
387
388 friend size_t hash_value(CreateFunctionContextParameters const& parameters);
389
390 friend std::ostream& operator<<(
391 std::ostream& os, CreateFunctionContextParameters const& parameters);
392 };
393
394 CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
395 Operator const*);
396
397 // Defines parameters for JSDefineNamedOwnProperty operator.
398 class DefineNamedOwnPropertyParameters final {
399 public:
DefineNamedOwnPropertyParameters(const NameRef & name,FeedbackSource const & feedback)400 DefineNamedOwnPropertyParameters(const NameRef& name,
401 FeedbackSource const& feedback)
402 : name_(name), feedback_(feedback) {}
403
name(JSHeapBroker * broker)404 NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
feedback()405 FeedbackSource const& feedback() const { return feedback_; }
406
407 private:
408 const NameTinyRef name_;
409 FeedbackSource const feedback_;
410
411 friend bool operator==(DefineNamedOwnPropertyParameters const&,
412 DefineNamedOwnPropertyParameters const&);
413 friend bool operator!=(DefineNamedOwnPropertyParameters const&,
414 DefineNamedOwnPropertyParameters const&);
415 friend size_t hash_value(DefineNamedOwnPropertyParameters const&);
416 friend std::ostream& operator<<(std::ostream&,
417 DefineNamedOwnPropertyParameters const&);
418 };
419
420 const DefineNamedOwnPropertyParameters& DefineNamedOwnPropertyParametersOf(
421 const Operator* op);
422
423 // Defines the feedback, i.e., vector and index, for storing a data property in
424 // an object literal. This is used as a parameter by JSCreateEmptyLiteralArray
425 // and JSDefineKeyedOwnPropertyInLiteral operators.
426 class FeedbackParameter final {
427 public:
FeedbackParameter(FeedbackSource const & feedback)428 explicit FeedbackParameter(FeedbackSource const& feedback)
429 : feedback_(feedback) {}
430
feedback()431 FeedbackSource const& feedback() const { return feedback_; }
432
433 private:
434 FeedbackSource const feedback_;
435 };
436
437 bool operator==(FeedbackParameter const&, FeedbackParameter const&);
438 bool operator!=(FeedbackParameter const&, FeedbackParameter const&);
439
440 size_t hash_value(FeedbackParameter const&);
441
442 std::ostream& operator<<(std::ostream&, FeedbackParameter const&);
443
444 const FeedbackParameter& FeedbackParameterOf(const Operator* op);
445
446 // Defines the property of an object for a named access. This is
447 // used as a parameter by the JSLoadNamed and JSSetNamedProperty operators.
448 class NamedAccess final {
449 public:
NamedAccess(LanguageMode language_mode,const NameRef & name,FeedbackSource const & feedback)450 NamedAccess(LanguageMode language_mode, const NameRef& name,
451 FeedbackSource const& feedback)
452 : name_(name), feedback_(feedback), language_mode_(language_mode) {}
453
name(JSHeapBroker * broker)454 NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
language_mode()455 LanguageMode language_mode() const { return language_mode_; }
feedback()456 FeedbackSource const& feedback() const { return feedback_; }
457
458 private:
459 const NameTinyRef name_;
460 FeedbackSource const feedback_;
461 LanguageMode const language_mode_;
462
463 friend bool operator==(NamedAccess const&, NamedAccess const&);
464 friend bool operator!=(NamedAccess const&, NamedAccess const&);
465
466 friend size_t hash_value(NamedAccess const&);
467
468 friend std::ostream& operator<<(std::ostream&, NamedAccess const&);
469 };
470
471 const NamedAccess& NamedAccessOf(const Operator* op);
472
473
474 // Defines the property being loaded from an object by a named load. This is
475 // used as a parameter by JSLoadGlobal operator.
476 class LoadGlobalParameters final {
477 public:
LoadGlobalParameters(const NameRef & name,const FeedbackSource & feedback,TypeofMode typeof_mode)478 LoadGlobalParameters(const NameRef& name, const FeedbackSource& feedback,
479 TypeofMode typeof_mode)
480 : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
481
name(JSHeapBroker * broker)482 NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
typeof_mode()483 TypeofMode typeof_mode() const { return typeof_mode_; }
484
feedback()485 const FeedbackSource& feedback() const { return feedback_; }
486
487 private:
488 const NameTinyRef name_;
489 const FeedbackSource feedback_;
490 const TypeofMode typeof_mode_;
491
492 friend bool operator==(LoadGlobalParameters const&,
493 LoadGlobalParameters const&);
494 friend bool operator!=(LoadGlobalParameters const&,
495 LoadGlobalParameters const&);
496
497 friend size_t hash_value(LoadGlobalParameters const&);
498
499 friend std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&);
500 };
501
502 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op);
503
504
505 // Defines the property being stored to an object by a named store. This is
506 // used as a parameter by JSStoreGlobal operator.
507 class StoreGlobalParameters final {
508 public:
StoreGlobalParameters(LanguageMode language_mode,const FeedbackSource & feedback,const NameRef & name)509 StoreGlobalParameters(LanguageMode language_mode,
510 const FeedbackSource& feedback, const NameRef& name)
511 : language_mode_(language_mode), name_(name), feedback_(feedback) {}
512
language_mode()513 LanguageMode language_mode() const { return language_mode_; }
feedback()514 FeedbackSource const& feedback() const { return feedback_; }
name(JSHeapBroker * broker)515 NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
516
517 private:
518 LanguageMode const language_mode_;
519 const NameTinyRef name_;
520 FeedbackSource const feedback_;
521
522 friend bool operator==(StoreGlobalParameters const&,
523 StoreGlobalParameters const&);
524 friend bool operator!=(StoreGlobalParameters const&,
525 StoreGlobalParameters const&);
526
527 friend size_t hash_value(StoreGlobalParameters const&);
528
529 friend std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&);
530 };
531
532 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op);
533
534 // Defines the property of an object for a keyed access. This is used
535 // as a parameter by the JSLoadProperty and JSSetKeyedProperty
536 // operators.
537 class PropertyAccess final {
538 public:
PropertyAccess(LanguageMode language_mode,FeedbackSource const & feedback)539 PropertyAccess(LanguageMode language_mode, FeedbackSource const& feedback)
540 : feedback_(feedback), language_mode_(language_mode) {}
541
language_mode()542 LanguageMode language_mode() const { return language_mode_; }
feedback()543 FeedbackSource const& feedback() const { return feedback_; }
544
545 private:
546 FeedbackSource const feedback_;
547 LanguageMode const language_mode_;
548 };
549
550 bool operator==(PropertyAccess const&, PropertyAccess const&);
551 bool operator!=(PropertyAccess const&, PropertyAccess const&);
552
553 size_t hash_value(PropertyAccess const&);
554
555 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
556 PropertyAccess const&);
557
558 PropertyAccess const& PropertyAccessOf(const Operator* op);
559
560
561 // CreateArgumentsType is used as parameter to JSCreateArguments nodes.
562 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op);
563
564
565 // Defines shared information for the array that should be created. This is
566 // used as parameter by JSCreateArray operators.
567 class CreateArrayParameters final {
568 public:
CreateArrayParameters(size_t arity,base::Optional<AllocationSiteRef> site)569 CreateArrayParameters(size_t arity, base::Optional<AllocationSiteRef> site)
570 : arity_(arity), site_(site) {}
571
arity()572 size_t arity() const { return arity_; }
site(JSHeapBroker * broker)573 base::Optional<AllocationSiteRef> site(JSHeapBroker* broker) const {
574 return AllocationSiteTinyRef::AsOptionalRef(broker, site_);
575 }
576
577 private:
578 size_t const arity_;
579 base::Optional<AllocationSiteTinyRef> const site_;
580
581 friend bool operator==(CreateArrayParameters const&,
582 CreateArrayParameters const&);
583 friend bool operator!=(CreateArrayParameters const&,
584 CreateArrayParameters const&);
585 friend size_t hash_value(CreateArrayParameters const&);
586 friend std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
587 };
588
589 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
590
591 // Defines shared information for the array iterator that should be created.
592 // This is used as parameter by JSCreateArrayIterator operators.
593 class CreateArrayIteratorParameters final {
594 public:
CreateArrayIteratorParameters(IterationKind kind)595 explicit CreateArrayIteratorParameters(IterationKind kind) : kind_(kind) {}
596
kind()597 IterationKind kind() const { return kind_; }
598
599 private:
600 IterationKind const kind_;
601 };
602
603 bool operator==(CreateArrayIteratorParameters const&,
604 CreateArrayIteratorParameters const&);
605 bool operator!=(CreateArrayIteratorParameters const&,
606 CreateArrayIteratorParameters const&);
607
608 size_t hash_value(CreateArrayIteratorParameters const&);
609
610 std::ostream& operator<<(std::ostream&, CreateArrayIteratorParameters const&);
611
612 const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf(
613 const Operator* op);
614
615 // Defines shared information for the array iterator that should be created.
616 // This is used as parameter by JSCreateCollectionIterator operators.
617 class CreateCollectionIteratorParameters final {
618 public:
CreateCollectionIteratorParameters(CollectionKind collection_kind,IterationKind iteration_kind)619 explicit CreateCollectionIteratorParameters(CollectionKind collection_kind,
620 IterationKind iteration_kind)
621 : collection_kind_(collection_kind), iteration_kind_(iteration_kind) {
622 CHECK(!(collection_kind == CollectionKind::kSet &&
623 iteration_kind == IterationKind::kKeys));
624 }
625
collection_kind()626 CollectionKind collection_kind() const { return collection_kind_; }
iteration_kind()627 IterationKind iteration_kind() const { return iteration_kind_; }
628
629 private:
630 CollectionKind const collection_kind_;
631 IterationKind const iteration_kind_;
632 };
633
634 bool operator==(CreateCollectionIteratorParameters const&,
635 CreateCollectionIteratorParameters const&);
636 bool operator!=(CreateCollectionIteratorParameters const&,
637 CreateCollectionIteratorParameters const&);
638
639 size_t hash_value(CreateCollectionIteratorParameters const&);
640
641 std::ostream& operator<<(std::ostream&,
642 CreateCollectionIteratorParameters const&);
643
644 const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf(
645 const Operator* op);
646
647 // Defines shared information for the bound function that should be created.
648 // This is used as parameter by JSCreateBoundFunction operators.
649 class CreateBoundFunctionParameters final {
650 public:
CreateBoundFunctionParameters(size_t arity,const MapRef & map)651 CreateBoundFunctionParameters(size_t arity, const MapRef& map)
652 : arity_(arity), map_(map) {}
653
arity()654 size_t arity() const { return arity_; }
map(JSHeapBroker * broker)655 MapRef map(JSHeapBroker* broker) const { return map_.AsRef(broker); }
656
657 private:
658 size_t const arity_;
659 const MapTinyRef map_;
660
661 friend bool operator==(CreateBoundFunctionParameters const&,
662 CreateBoundFunctionParameters const&);
663 friend bool operator!=(CreateBoundFunctionParameters const&,
664 CreateBoundFunctionParameters const&);
665
666 friend size_t hash_value(CreateBoundFunctionParameters const&);
667
668 friend std::ostream& operator<<(std::ostream&,
669 CreateBoundFunctionParameters const&);
670 };
671
672 const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
673 const Operator* op);
674
675 // Defines shared information for the closure that should be created. This is
676 // used as a parameter by JSCreateClosure operators.
677 class CreateClosureParameters final {
678 public:
CreateClosureParameters(const SharedFunctionInfoRef & shared_info,const CodeTRef & code,AllocationType allocation)679 CreateClosureParameters(const SharedFunctionInfoRef& shared_info,
680 const CodeTRef& code, AllocationType allocation)
681 : shared_info_(shared_info), code_(code), allocation_(allocation) {}
682
shared_info(JSHeapBroker * broker)683 SharedFunctionInfoRef shared_info(JSHeapBroker* broker) const {
684 return shared_info_.AsRef(broker);
685 }
code(JSHeapBroker * broker)686 CodeTRef code(JSHeapBroker* broker) const { return code_.AsRef(broker); }
allocation()687 AllocationType allocation() const { return allocation_; }
688
689 private:
690 const SharedFunctionInfoTinyRef shared_info_;
691 const CodeTTinyRef code_;
692 AllocationType const allocation_;
693
694 friend bool operator==(CreateClosureParameters const&,
695 CreateClosureParameters const&);
696 friend bool operator!=(CreateClosureParameters const&,
697 CreateClosureParameters const&);
698
699 friend size_t hash_value(CreateClosureParameters const&);
700
701 friend std::ostream& operator<<(std::ostream&,
702 CreateClosureParameters const&);
703 };
704
705 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
706
707 class GetTemplateObjectParameters final {
708 public:
GetTemplateObjectParameters(const TemplateObjectDescriptionRef & description,const SharedFunctionInfoRef & shared,FeedbackSource const & feedback)709 GetTemplateObjectParameters(const TemplateObjectDescriptionRef& description,
710 const SharedFunctionInfoRef& shared,
711 FeedbackSource const& feedback)
712 : description_(description), shared_(shared), feedback_(feedback) {}
713
description(JSHeapBroker * broker)714 TemplateObjectDescriptionRef description(JSHeapBroker* broker) const {
715 return description_.AsRef(broker);
716 }
shared(JSHeapBroker * broker)717 SharedFunctionInfoRef shared(JSHeapBroker* broker) const {
718 return shared_.AsRef(broker);
719 }
feedback()720 FeedbackSource const& feedback() const { return feedback_; }
721
722 private:
723 const TemplateObjectDescriptionTinyRef description_;
724 const SharedFunctionInfoTinyRef shared_;
725 FeedbackSource const feedback_;
726
727 friend bool operator==(GetTemplateObjectParameters const&,
728 GetTemplateObjectParameters const&);
729 friend bool operator!=(GetTemplateObjectParameters const&,
730 GetTemplateObjectParameters const&);
731
732 friend size_t hash_value(GetTemplateObjectParameters const&);
733
734 friend std::ostream& operator<<(std::ostream&,
735 GetTemplateObjectParameters const&);
736 };
737
738 const GetTemplateObjectParameters& GetTemplateObjectParametersOf(
739 const Operator* op);
740
741 // Defines shared information for the literal that should be created. This is
742 // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
743 // JSCreateLiteralRegExp operators.
744 class CreateLiteralParameters final {
745 public:
CreateLiteralParameters(const HeapObjectRef & constant,FeedbackSource const & feedback,int length,int flags)746 CreateLiteralParameters(const HeapObjectRef& constant,
747 FeedbackSource const& feedback, int length, int flags)
748 : constant_(constant),
749 feedback_(feedback),
750 length_(length),
751 flags_(flags) {}
752
constant(JSHeapBroker * broker)753 HeapObjectRef constant(JSHeapBroker* broker) const {
754 return constant_.AsRef(broker);
755 }
feedback()756 FeedbackSource const& feedback() const { return feedback_; }
length()757 int length() const { return length_; }
flags()758 int flags() const { return flags_; }
759
760 private:
761 const HeapObjectTinyRef constant_;
762 FeedbackSource const feedback_;
763 int const length_;
764 int const flags_;
765
766 friend bool operator==(CreateLiteralParameters const&,
767 CreateLiteralParameters const&);
768 friend bool operator!=(CreateLiteralParameters const&,
769 CreateLiteralParameters const&);
770
771 friend size_t hash_value(CreateLiteralParameters const&);
772
773 friend std::ostream& operator<<(std::ostream&,
774 CreateLiteralParameters const&);
775 };
776
777 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
778
779 class CloneObjectParameters final {
780 public:
CloneObjectParameters(FeedbackSource const & feedback,int flags)781 CloneObjectParameters(FeedbackSource const& feedback, int flags)
782 : feedback_(feedback), flags_(flags) {}
783
feedback()784 FeedbackSource const& feedback() const { return feedback_; }
flags()785 int flags() const { return flags_; }
786
787 private:
788 FeedbackSource const feedback_;
789 int const flags_;
790 };
791
792 bool operator==(CloneObjectParameters const&, CloneObjectParameters const&);
793 bool operator!=(CloneObjectParameters const&, CloneObjectParameters const&);
794
795 size_t hash_value(CloneObjectParameters const&);
796
797 std::ostream& operator<<(std::ostream&, CloneObjectParameters const&);
798
799 const CloneObjectParameters& CloneObjectParametersOf(const Operator* op);
800
801 // Defines the shared information for the iterator symbol thats loaded and
802 // called. This is used as a parameter by JSGetIterator operator.
803 class GetIteratorParameters final {
804 public:
GetIteratorParameters(const FeedbackSource & load_feedback,const FeedbackSource & call_feedback)805 GetIteratorParameters(const FeedbackSource& load_feedback,
806 const FeedbackSource& call_feedback)
807 : load_feedback_(load_feedback), call_feedback_(call_feedback) {}
808
loadFeedback()809 FeedbackSource const& loadFeedback() const { return load_feedback_; }
callFeedback()810 FeedbackSource const& callFeedback() const { return call_feedback_; }
811
812 private:
813 FeedbackSource const load_feedback_;
814 FeedbackSource const call_feedback_;
815 };
816
817 bool operator==(GetIteratorParameters const&, GetIteratorParameters const&);
818 bool operator!=(GetIteratorParameters const&, GetIteratorParameters const&);
819
820 size_t hash_value(GetIteratorParameters const&);
821
822 std::ostream& operator<<(std::ostream&, GetIteratorParameters const&);
823
824 const GetIteratorParameters& GetIteratorParametersOf(const Operator* op);
825
826 enum class ForInMode : uint8_t {
827 kUseEnumCacheKeysAndIndices,
828 kUseEnumCacheKeys,
829 kGeneric
830 };
831 size_t hash_value(ForInMode const&);
832 std::ostream& operator<<(std::ostream&, ForInMode const&);
833
834 class ForInParameters final {
835 public:
ForInParameters(const FeedbackSource & feedback,ForInMode mode)836 ForInParameters(const FeedbackSource& feedback, ForInMode mode)
837 : feedback_(feedback), mode_(mode) {}
838
feedback()839 const FeedbackSource& feedback() const { return feedback_; }
mode()840 ForInMode mode() const { return mode_; }
841
842 private:
843 const FeedbackSource feedback_;
844 const ForInMode mode_;
845 };
846
847 bool operator==(ForInParameters const&, ForInParameters const&);
848 bool operator!=(ForInParameters const&, ForInParameters const&);
849 size_t hash_value(ForInParameters const&);
850 std::ostream& operator<<(std::ostream&, ForInParameters const&);
851 const ForInParameters& ForInParametersOf(const Operator* op);
852
853 #if V8_ENABLE_WEBASSEMBLY
854 class JSWasmCallParameters {
855 public:
JSWasmCallParameters(const wasm::WasmModule * module,const wasm::FunctionSig * signature,FeedbackSource const & feedback)856 explicit JSWasmCallParameters(const wasm::WasmModule* module,
857 const wasm::FunctionSig* signature,
858 FeedbackSource const& feedback)
859 : module_(module), signature_(signature), feedback_(feedback) {
860 DCHECK_NOT_NULL(module);
861 DCHECK_NOT_NULL(signature);
862 }
863
module()864 const wasm::WasmModule* module() const { return module_; }
signature()865 const wasm::FunctionSig* signature() const { return signature_; }
feedback()866 FeedbackSource const& feedback() const { return feedback_; }
867 int input_count() const;
868 int arity_without_implicit_args() const;
869
870 private:
871 const wasm::WasmModule* const module_;
872 const wasm::FunctionSig* const signature_;
873 const FeedbackSource feedback_;
874 };
875
876 JSWasmCallParameters const& JSWasmCallParametersOf(const Operator* op)
877 V8_WARN_UNUSED_RESULT;
878 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
879 JSWasmCallParameters const&);
880 size_t hash_value(JSWasmCallParameters const&);
881 bool operator==(JSWasmCallParameters const&, JSWasmCallParameters const&);
882 #endif // V8_ENABLE_WEBASSEMBLY
883
884 int RegisterCountOf(Operator const* op) V8_WARN_UNUSED_RESULT;
885
886 int GeneratorStoreValueCountOf(const Operator* op) V8_WARN_UNUSED_RESULT;
887 int RestoreRegisterIndexOf(const Operator* op) V8_WARN_UNUSED_RESULT;
888
889 ScopeInfoRef ScopeInfoOf(JSHeapBroker* broker,
890 const Operator* op) V8_WARN_UNUSED_RESULT;
891
892 bool operator==(ScopeInfoTinyRef const&, ScopeInfoTinyRef const&);
893 bool operator!=(ScopeInfoTinyRef const&, ScopeInfoTinyRef const&);
894
895 size_t hash_value(ScopeInfoTinyRef const&);
896
897 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
898 ScopeInfoTinyRef const&);
899
900 // Interface for building JavaScript-level operators, e.g. directly from the
901 // AST. Most operators have no parameters, thus can be globally shared for all
902 // graphs.
903 class V8_EXPORT_PRIVATE JSOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)904 : public NON_EXPORTED_BASE(ZoneObject) {
905 public:
906 explicit JSOperatorBuilder(Zone* zone);
907 JSOperatorBuilder(const JSOperatorBuilder&) = delete;
908 JSOperatorBuilder& operator=(const JSOperatorBuilder&) = delete;
909
910 const Operator* Equal(FeedbackSource const& feedback);
911 const Operator* StrictEqual(FeedbackSource const& feedback);
912 const Operator* LessThan(FeedbackSource const& feedback);
913 const Operator* GreaterThan(FeedbackSource const& feedback);
914 const Operator* LessThanOrEqual(FeedbackSource const& feedback);
915 const Operator* GreaterThanOrEqual(FeedbackSource const& feedback);
916
917 const Operator* BitwiseOr(FeedbackSource const& feedback);
918 const Operator* BitwiseXor(FeedbackSource const& feedback);
919 const Operator* BitwiseAnd(FeedbackSource const& feedback);
920 const Operator* ShiftLeft(FeedbackSource const& feedback);
921 const Operator* ShiftRight(FeedbackSource const& feedback);
922 const Operator* ShiftRightLogical(FeedbackSource const& feedback);
923 const Operator* Add(FeedbackSource const& feedback);
924 const Operator* Subtract(FeedbackSource const& feedback);
925 const Operator* Multiply(FeedbackSource const& feedback);
926 const Operator* Divide(FeedbackSource const& feedback);
927 const Operator* Modulus(FeedbackSource const& feedback);
928 const Operator* Exponentiate(FeedbackSource const& feedback);
929
930 const Operator* BitwiseNot(FeedbackSource const& feedback);
931 const Operator* Decrement(FeedbackSource const& feedback);
932 const Operator* Increment(FeedbackSource const& feedback);
933 const Operator* Negate(FeedbackSource const& feedback);
934
935 const Operator* ToLength();
936 const Operator* ToName();
937 const Operator* ToNumber();
938 const Operator* ToNumberConvertBigInt();
939 const Operator* ToNumeric();
940 const Operator* ToObject();
941 const Operator* ToString();
942
943 const Operator* Create();
944 const Operator* CreateArguments(CreateArgumentsType type);
945 const Operator* CreateArray(size_t arity,
946 base::Optional<AllocationSiteRef> site);
947 const Operator* CreateArrayIterator(IterationKind);
948 const Operator* CreateAsyncFunctionObject(int register_count);
949 const Operator* CreateCollectionIterator(CollectionKind, IterationKind);
950 const Operator* CreateBoundFunction(size_t arity, const MapRef& map);
951 const Operator* CreateClosure(
952 const SharedFunctionInfoRef& shared_info, const CodeTRef& code,
953 AllocationType allocation = AllocationType::kYoung);
954 const Operator* CreateIterResultObject();
955 const Operator* CreateStringIterator();
956 const Operator* CreateKeyValueArray();
957 const Operator* CreateObject();
958 const Operator* CreatePromise();
959 const Operator* CreateTypedArray();
960 const Operator* CreateLiteralArray(
961 const ArrayBoilerplateDescriptionRef& constant,
962 FeedbackSource const& feedback, int literal_flags,
963 int number_of_elements);
964 const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback);
965 const Operator* CreateArrayFromIterable();
966 const Operator* CreateEmptyLiteralObject();
967 const Operator* CreateLiteralObject(
968 const ObjectBoilerplateDescriptionRef& constant,
969 FeedbackSource const& feedback, int literal_flags,
970 int number_of_properties);
971 const Operator* CloneObject(FeedbackSource const& feedback,
972 int literal_flags);
973 const Operator* CreateLiteralRegExp(const StringRef& constant_pattern,
974 FeedbackSource const& feedback,
975 int literal_flags);
976
977 const Operator* GetTemplateObject(
978 const TemplateObjectDescriptionRef& description,
979 const SharedFunctionInfoRef& shared, FeedbackSource const& feedback);
980
981 const Operator* CallForwardVarargs(size_t arity, uint32_t start_index);
982 const Operator* Call(
983 size_t arity, CallFrequency const& frequency = CallFrequency(),
984 FeedbackSource const& feedback = FeedbackSource(),
985 ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
986 SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
987 CallFeedbackRelation feedback_relation =
988 CallFeedbackRelation::kUnrelated);
989 const Operator* CallWithArrayLike(
990 CallFrequency const& frequency,
991 const FeedbackSource& feedback = FeedbackSource{},
992 SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
993 CallFeedbackRelation feedback_relation = CallFeedbackRelation::kTarget);
994 const Operator* CallWithSpread(
995 uint32_t arity, CallFrequency const& frequency = CallFrequency(),
996 FeedbackSource const& feedback = FeedbackSource(),
997 SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
998 CallFeedbackRelation feedback_relation = CallFeedbackRelation::kTarget);
999 const Operator* CallRuntime(Runtime::FunctionId id);
1000 const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
1001 const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
1002
1003 #if V8_ENABLE_WEBASSEMBLY
1004 const Operator* CallWasm(const wasm::WasmModule* wasm_module,
1005 const wasm::FunctionSig* wasm_signature,
1006 FeedbackSource const& feedback);
1007 #endif // V8_ENABLE_WEBASSEMBLY
1008
1009 const Operator* ConstructForwardVarargs(size_t arity, uint32_t start_index);
1010 const Operator* Construct(uint32_t arity,
1011 CallFrequency const& frequency = CallFrequency(),
1012 FeedbackSource const& feedback = FeedbackSource());
1013 const Operator* ConstructWithArrayLike(CallFrequency const& frequency,
1014 FeedbackSource const& feedback);
1015 const Operator* ConstructWithSpread(
1016 uint32_t arity, CallFrequency const& frequency = CallFrequency(),
1017 FeedbackSource const& feedback = FeedbackSource());
1018
1019 const Operator* LoadProperty(FeedbackSource const& feedback);
1020 const Operator* LoadNamed(const NameRef& name,
1021 FeedbackSource const& feedback);
1022 const Operator* LoadNamedFromSuper(const NameRef& name,
1023 FeedbackSource const& feedback);
1024
1025 const Operator* SetKeyedProperty(LanguageMode language_mode,
1026 FeedbackSource const& feedback);
1027 const Operator* DefineKeyedOwnProperty(LanguageMode language_mode,
1028 FeedbackSource const& feedback);
1029 const Operator* SetNamedProperty(LanguageMode language_mode,
1030 const NameRef& name,
1031 FeedbackSource const& feedback);
1032
1033 const Operator* DefineNamedOwnProperty(const NameRef& name,
1034 FeedbackSource const& feedback);
1035 const Operator* DefineKeyedOwnPropertyInLiteral(
1036 const FeedbackSource& feedback);
1037 const Operator* StoreInArrayLiteral(const FeedbackSource& feedback);
1038
1039 const Operator* DeleteProperty();
1040
1041 const Operator* HasProperty(FeedbackSource const& feedback);
1042
1043 const Operator* GetSuperConstructor();
1044
1045 const Operator* CreateGeneratorObject();
1046
1047 const Operator* LoadGlobal(const NameRef& name,
1048 const FeedbackSource& feedback,
1049 TypeofMode typeof_mode = TypeofMode::kNotInside);
1050 const Operator* StoreGlobal(LanguageMode language_mode, const NameRef& name,
1051 const FeedbackSource& feedback);
1052
1053 const Operator* HasContextExtension(size_t depth);
1054 const Operator* LoadContext(size_t depth, size_t index, bool immutable);
1055 const Operator* StoreContext(size_t depth, size_t index);
1056
1057 const Operator* LoadModule(int32_t cell_index);
1058 const Operator* StoreModule(int32_t cell_index);
1059
1060 const Operator* GetImportMeta();
1061
1062 const Operator* HasInPrototypeChain();
1063 const Operator* InstanceOf(const FeedbackSource& feedback);
1064 const Operator* OrdinaryHasInstance();
1065
1066 const Operator* AsyncFunctionEnter();
1067 const Operator* AsyncFunctionReject();
1068 const Operator* AsyncFunctionResolve();
1069
1070 const Operator* ForInEnumerate();
1071 const Operator* ForInNext(ForInMode mode, const FeedbackSource& feedback);
1072 const Operator* ForInPrepare(ForInMode mode, const FeedbackSource& feedback);
1073
1074 const Operator* LoadMessage();
1075 const Operator* StoreMessage();
1076
1077 // Used to implement Ignition's SuspendGenerator bytecode.
1078 const Operator* GeneratorStore(int value_count);
1079
1080 // Used to implement Ignition's SwitchOnGeneratorState bytecode.
1081 const Operator* GeneratorRestoreContinuation();
1082 const Operator* GeneratorRestoreContext();
1083
1084 // Used to implement Ignition's ResumeGenerator bytecode.
1085 const Operator* GeneratorRestoreRegister(int index);
1086 const Operator* GeneratorRestoreInputOrDebugPos();
1087
1088 const Operator* StackCheck(StackCheckKind kind);
1089 const Operator* Debugger();
1090
1091 const Operator* FulfillPromise();
1092 const Operator* PerformPromiseThen();
1093 const Operator* PromiseResolve();
1094 const Operator* RejectPromise();
1095 const Operator* ResolvePromise();
1096
1097 const Operator* CreateFunctionContext(const ScopeInfoRef& scope_info,
1098 int slot_count, ScopeType scope_type);
1099 const Operator* CreateCatchContext(const ScopeInfoRef& scope_info);
1100 const Operator* CreateWithContext(const ScopeInfoRef& scope_info);
1101 const Operator* CreateBlockContext(const ScopeInfoRef& scpope_info);
1102
1103 const Operator* ObjectIsArray();
1104 const Operator* ParseInt();
1105 const Operator* RegExpTest();
1106
1107 const Operator* GetIterator(FeedbackSource const& load_feedback,
1108 FeedbackSource const& call_feedback);
1109
1110 private:
1111 Zone* zone() const { return zone_; }
1112
1113 const JSOperatorGlobalCache& cache_;
1114 Zone* const zone_;
1115 };
1116
1117 // Node wrappers.
1118
1119 class JSNodeWrapperBase : public NodeWrapper {
1120 public:
JSNodeWrapperBase(Node * node)1121 explicit constexpr JSNodeWrapperBase(Node* node) : NodeWrapper(node) {}
1122
1123 // Valid iff this node has a context input.
context()1124 TNode<Object> context() const {
1125 // Could be a Context or NoContextConstant.
1126 return TNode<Object>::UncheckedCast(
1127 NodeProperties::GetContextInput(node()));
1128 }
1129
1130 // Valid iff this node has exactly one effect input.
effect()1131 Effect effect() const {
1132 DCHECK_EQ(node()->op()->EffectInputCount(), 1);
1133 return Effect{NodeProperties::GetEffectInput(node())};
1134 }
1135
1136 // Valid iff this node has exactly one control input.
control()1137 Control control() const {
1138 DCHECK_EQ(node()->op()->ControlInputCount(), 1);
1139 return Control{NodeProperties::GetControlInput(node())};
1140 }
1141
1142 // Valid iff this node has a frame state input.
frame_state()1143 FrameState frame_state() const {
1144 return FrameState{NodeProperties::GetFrameStateInput(node())};
1145 }
1146 };
1147
1148 #define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
1149 static constexpr int Name##Index() { return TheIndex; } \
1150 TNode<Type> name() const { \
1151 return TNode<Type>::UncheckedCast( \
1152 NodeProperties::GetValueInput(node(), TheIndex)); \
1153 }
1154
1155 class JSUnaryOpNode final : public JSNodeWrapperBase {
1156 public:
JSUnaryOpNode(Node * node)1157 explicit constexpr JSUnaryOpNode(Node* node) : JSNodeWrapperBase(node) {
1158 DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode()));
1159 }
1160
1161 #define INPUTS(V) \
1162 V(Value, value, 0, Object) \
1163 V(FeedbackVector, feedback_vector, 1, HeapObject)
1164 INPUTS(DEFINE_INPUT_ACCESSORS)
1165 #undef INPUTS
1166 };
1167
1168 #define V(JSName, ...) using JSName##Node = JSUnaryOpNode;
JS_UNOP_WITH_FEEDBACK(V)1169 JS_UNOP_WITH_FEEDBACK(V)
1170 #undef V
1171
1172 class JSBinaryOpNode final : public JSNodeWrapperBase {
1173 public:
1174 explicit constexpr JSBinaryOpNode(Node* node) : JSNodeWrapperBase(node) {
1175 DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode()));
1176 }
1177
1178 const FeedbackParameter& Parameters() const {
1179 return FeedbackParameterOf(node()->op());
1180 }
1181
1182 #define INPUTS(V) \
1183 V(Left, left, 0, Object) \
1184 V(Right, right, 1, Object) \
1185 V(FeedbackVector, feedback_vector, 2, HeapObject)
1186 INPUTS(DEFINE_INPUT_ACCESSORS)
1187 #undef INPUTS
1188 };
1189
1190 #define V(JSName, ...) using JSName##Node = JSBinaryOpNode;
JS_BINOP_WITH_FEEDBACK(V)1191 JS_BINOP_WITH_FEEDBACK(V)
1192 #undef V
1193
1194 class JSGetIteratorNode final : public JSNodeWrapperBase {
1195 public:
1196 explicit constexpr JSGetIteratorNode(Node* node) : JSNodeWrapperBase(node) {
1197 DCHECK_EQ(IrOpcode::kJSGetIterator, node->opcode());
1198 }
1199
1200 const GetIteratorParameters& Parameters() const {
1201 return GetIteratorParametersOf(node()->op());
1202 }
1203
1204 #define INPUTS(V) \
1205 V(Receiver, receiver, 0, Object) \
1206 V(FeedbackVector, feedback_vector, 1, HeapObject)
1207 INPUTS(DEFINE_INPUT_ACCESSORS)
1208 #undef INPUTS
1209 };
1210
1211 class JSCloneObjectNode final : public JSNodeWrapperBase {
1212 public:
JSCloneObjectNode(Node * node)1213 explicit constexpr JSCloneObjectNode(Node* node) : JSNodeWrapperBase(node) {
1214 DCHECK_EQ(IrOpcode::kJSCloneObject, node->opcode());
1215 }
1216
Parameters()1217 const CloneObjectParameters& Parameters() const {
1218 return CloneObjectParametersOf(node()->op());
1219 }
1220
1221 #define INPUTS(V) \
1222 V(Source, source, 0, Object) \
1223 V(FeedbackVector, feedback_vector, 1, HeapObject)
1224 INPUTS(DEFINE_INPUT_ACCESSORS)
1225 #undef INPUTS
1226 };
1227
1228 class JSGetTemplateObjectNode final : public JSNodeWrapperBase {
1229 public:
JSGetTemplateObjectNode(Node * node)1230 explicit constexpr JSGetTemplateObjectNode(Node* node)
1231 : JSNodeWrapperBase(node) {
1232 DCHECK_EQ(IrOpcode::kJSGetTemplateObject, node->opcode());
1233 }
1234
Parameters()1235 const GetTemplateObjectParameters& Parameters() const {
1236 return GetTemplateObjectParametersOf(node()->op());
1237 }
1238
1239 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1240 INPUTS(DEFINE_INPUT_ACCESSORS)
1241 #undef INPUTS
1242 };
1243
1244 class JSCreateLiteralOpNode final : public JSNodeWrapperBase {
1245 public:
JSCreateLiteralOpNode(Node * node)1246 explicit constexpr JSCreateLiteralOpNode(Node* node)
1247 : JSNodeWrapperBase(node) {
1248 DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
1249 node->opcode() == IrOpcode::kJSCreateLiteralObject ||
1250 node->opcode() == IrOpcode::kJSCreateLiteralRegExp);
1251 }
1252
Parameters()1253 const CreateLiteralParameters& Parameters() const {
1254 return CreateLiteralParametersOf(node()->op());
1255 }
1256
1257 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1258 INPUTS(DEFINE_INPUT_ACCESSORS)
1259 #undef INPUTS
1260 };
1261
1262 using JSCreateLiteralArrayNode = JSCreateLiteralOpNode;
1263 using JSCreateLiteralObjectNode = JSCreateLiteralOpNode;
1264 using JSCreateLiteralRegExpNode = JSCreateLiteralOpNode;
1265
1266 class JSHasPropertyNode final : public JSNodeWrapperBase {
1267 public:
JSHasPropertyNode(Node * node)1268 explicit constexpr JSHasPropertyNode(Node* node) : JSNodeWrapperBase(node) {
1269 DCHECK_EQ(IrOpcode::kJSHasProperty, node->opcode());
1270 }
1271
Parameters()1272 const PropertyAccess& Parameters() const {
1273 return PropertyAccessOf(node()->op());
1274 }
1275
1276 #define INPUTS(V) \
1277 V(Object, object, 0, Object) \
1278 V(Key, key, 1, Object) \
1279 V(FeedbackVector, feedback_vector, 2, HeapObject)
1280 INPUTS(DEFINE_INPUT_ACCESSORS)
1281 #undef INPUTS
1282 };
1283
1284 class JSLoadPropertyNode final : public JSNodeWrapperBase {
1285 public:
JSLoadPropertyNode(Node * node)1286 explicit constexpr JSLoadPropertyNode(Node* node) : JSNodeWrapperBase(node) {
1287 DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode());
1288 }
1289
Parameters()1290 const PropertyAccess& Parameters() const {
1291 return PropertyAccessOf(node()->op());
1292 }
1293
1294 #define INPUTS(V) \
1295 V(Object, object, 0, Object) \
1296 V(Key, key, 1, Object) \
1297 V(FeedbackVector, feedback_vector, 2, HeapObject)
1298 INPUTS(DEFINE_INPUT_ACCESSORS)
1299 #undef INPUTS
1300 };
1301
1302 class JSSetKeyedPropertyNode final : public JSNodeWrapperBase {
1303 public:
JSSetKeyedPropertyNode(Node * node)1304 explicit constexpr JSSetKeyedPropertyNode(Node* node)
1305 : JSNodeWrapperBase(node) {
1306 DCHECK_EQ(IrOpcode::kJSSetKeyedProperty, node->opcode());
1307 }
1308
Parameters()1309 const PropertyAccess& Parameters() const {
1310 return PropertyAccessOf(node()->op());
1311 }
1312
1313 #define INPUTS(V) \
1314 V(Object, object, 0, Object) \
1315 V(Key, key, 1, Object) \
1316 V(Value, value, 2, Object) \
1317 V(FeedbackVector, feedback_vector, 3, HeapObject)
1318 INPUTS(DEFINE_INPUT_ACCESSORS)
1319 #undef INPUTS
1320 };
1321
1322 class JSDefineKeyedOwnPropertyNode final : public JSNodeWrapperBase {
1323 public:
JSDefineKeyedOwnPropertyNode(Node * node)1324 explicit constexpr JSDefineKeyedOwnPropertyNode(Node* node)
1325 : JSNodeWrapperBase(node) {
1326 DCHECK_EQ(IrOpcode::kJSDefineKeyedOwnProperty, node->opcode());
1327 }
1328
Parameters()1329 const PropertyAccess& Parameters() const {
1330 return PropertyAccessOf(node()->op());
1331 }
1332
1333 #define INPUTS(V) \
1334 V(Object, object, 0, Object) \
1335 V(Key, key, 1, Object) \
1336 V(Value, value, 2, Object) \
1337 V(FeedbackVector, feedback_vector, 3, HeapObject)
1338 INPUTS(DEFINE_INPUT_ACCESSORS)
1339 #undef INPUTS
1340 };
1341
1342 namespace js_node_wrapper_utils {
1343 // Avoids template definitions in the .cc file.
1344 TNode<Oddball> UndefinedConstant(JSGraph* jsgraph);
1345 } // namespace js_node_wrapper_utils
1346
1347 class JSCallOrConstructNode : public JSNodeWrapperBase {
1348 public:
JSCallOrConstructNode(Node * node)1349 explicit constexpr JSCallOrConstructNode(Node* node)
1350 : JSNodeWrapperBase(node) {
1351 DCHECK(IsValidNode(node));
1352 }
1353
1354 #define INPUTS(V) \
1355 V(Target, target, 0, Object) \
1356 V(ReceiverOrNewTarget, receiver_or_new_target, 1, Object)
1357 INPUTS(DEFINE_INPUT_ACCESSORS)
1358 #undef INPUTS
1359
1360 // Besides actual arguments, JSCall nodes (and variants) also take the
1361 // following. Note that we rely on the fact that all variants (JSCall,
1362 // JSCallWithArrayLike, JSCallWithSpread, JSConstruct,
1363 // JSConstructWithArrayLike, JSConstructWithSpread, JSWasmCall) have the same
1364 // underlying node layout.
1365 static constexpr int kTargetInputCount = 1;
1366 static constexpr int kReceiverOrNewTargetInputCount = 1;
1367 static constexpr int kFeedbackVectorInputCount = 1;
1368 static constexpr int kExtraInputCount = kTargetInputCount +
1369 kReceiverOrNewTargetInputCount +
1370 kFeedbackVectorInputCount;
1371 STATIC_ASSERT(kExtraInputCount == CallParameters::kExtraCallInputCount);
1372 STATIC_ASSERT(kExtraInputCount ==
1373 ConstructParameters::kExtraConstructInputCount);
1374
1375 // Just for static asserts for spots that rely on node layout.
1376 static constexpr bool kFeedbackVectorIsLastInput = true;
1377
1378 // Some spots rely on the fact that call and construct variants have the same
1379 // layout.
1380 static constexpr bool kHaveIdenticalLayouts = true;
1381
1382 // This is the arity fed into Call/ConstructArguments.
ArityForArgc(int parameters)1383 static constexpr int ArityForArgc(int parameters) {
1384 return parameters + kExtraInputCount;
1385 }
1386
FirstArgumentIndex()1387 static constexpr int FirstArgumentIndex() {
1388 return ReceiverOrNewTargetIndex() + 1;
1389 }
ArgumentIndex(int i)1390 static constexpr int ArgumentIndex(int i) { return FirstArgumentIndex() + i; }
1391
Argument(int i)1392 TNode<Object> Argument(int i) const {
1393 DCHECK_LT(i, ArgumentCount());
1394 return TNode<Object>::UncheckedCast(
1395 NodeProperties::GetValueInput(node(), ArgumentIndex(i)));
1396 }
LastArgumentIndex()1397 int LastArgumentIndex() const {
1398 DCHECK_GT(ArgumentCount(), 0);
1399 return ArgumentIndex(ArgumentCount() - 1);
1400 }
LastArgument()1401 TNode<Object> LastArgument() const {
1402 DCHECK_GT(ArgumentCount(), 0);
1403 return Argument(ArgumentCount() - 1);
1404 }
ArgumentOr(int i,Node * default_value)1405 TNode<Object> ArgumentOr(int i, Node* default_value) const {
1406 return i < ArgumentCount() ? Argument(i)
1407 : TNode<Object>::UncheckedCast(default_value);
1408 }
ArgumentOrUndefined(int i,JSGraph * jsgraph)1409 TNode<Object> ArgumentOrUndefined(int i, JSGraph* jsgraph) const {
1410 return ArgumentOr(i, js_node_wrapper_utils::UndefinedConstant(jsgraph));
1411 }
1412 virtual int ArgumentCount() const = 0;
1413
FeedbackVectorIndexForArgc(int argc)1414 static constexpr int FeedbackVectorIndexForArgc(int argc) {
1415 STATIC_ASSERT(kFeedbackVectorIsLastInput);
1416 return ArgumentIndex(argc - 1) + 1;
1417 }
FeedbackVectorIndex()1418 int FeedbackVectorIndex() const {
1419 return FeedbackVectorIndexForArgc(ArgumentCount());
1420 }
feedback_vector()1421 TNode<HeapObject> feedback_vector() const {
1422 return TNode<HeapObject>::UncheckedCast(
1423 NodeProperties::GetValueInput(node(), FeedbackVectorIndex()));
1424 }
1425
1426 private:
IsValidNode(Node * node)1427 static constexpr bool IsValidNode(Node* node) {
1428 return node->opcode() == IrOpcode::kJSCall ||
1429 node->opcode() == IrOpcode::kJSCallWithArrayLike ||
1430 node->opcode() == IrOpcode::kJSCallWithSpread ||
1431 node->opcode() == IrOpcode::kJSConstruct ||
1432 node->opcode() == IrOpcode::kJSConstructWithArrayLike ||
1433 node->opcode() == IrOpcode::kJSConstructWithSpread
1434 #if V8_ENABLE_WEBASSEMBLY
1435 || node->opcode() == IrOpcode::kJSWasmCall
1436 #endif // V8_ENABLE_WEBASSEMBLY
1437 ; // NOLINT(whitespace/semicolon)
1438 }
1439 };
1440
1441 template <int kOpcode>
IsExpectedOpcode(int opcode)1442 bool IsExpectedOpcode(int opcode) {
1443 return opcode == kOpcode;
1444 }
1445
1446 template <int kOpcode1, int kOpcode2, int... kOpcodes>
IsExpectedOpcode(int opcode)1447 bool IsExpectedOpcode(int opcode) {
1448 return opcode == kOpcode1 || IsExpectedOpcode<kOpcode2, kOpcodes...>(opcode);
1449 }
1450
1451 template <int... kOpcodes>
1452 class JSCallNodeBase final : public JSCallOrConstructNode {
1453 public:
JSCallNodeBase(Node * node)1454 explicit constexpr JSCallNodeBase(Node* node) : JSCallOrConstructNode(node) {
1455 DCHECK(IsExpectedOpcode<kOpcodes...>(node->opcode()));
1456 }
1457
Parameters()1458 const CallParameters& Parameters() const {
1459 return CallParametersOf(node()->op());
1460 }
1461
1462 #define INPUTS(V) \
1463 V(Target, target, 0, Object) \
1464 V(Receiver, receiver, 1, Object)
1465 INPUTS(DEFINE_INPUT_ACCESSORS)
1466 #undef INPUTS
1467
1468 static constexpr int kReceiverInputCount = 1;
1469 STATIC_ASSERT(kReceiverInputCount ==
1470 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1471
ArgumentCount()1472 int ArgumentCount() const override {
1473 // Note: The count reported by this function depends only on the parameter,
1474 // thus adding/removing inputs will not affect it.
1475 return Parameters().arity_without_implicit_args();
1476 }
1477 };
1478
1479 using JSCallNode = JSCallNodeBase<IrOpcode::kJSCall>;
1480 using JSCallWithSpreadNode = JSCallNodeBase<IrOpcode::kJSCallWithSpread>;
1481 using JSCallWithArrayLikeNode = JSCallNodeBase<IrOpcode::kJSCallWithArrayLike>;
1482 using JSCallWithArrayLikeOrSpreadNode =
1483 JSCallNodeBase<IrOpcode::kJSCallWithArrayLike, IrOpcode::kJSCallWithSpread>;
1484
1485 #if V8_ENABLE_WEBASSEMBLY
1486 class JSWasmCallNode final : public JSCallOrConstructNode {
1487 public:
JSWasmCallNode(Node * node)1488 explicit constexpr JSWasmCallNode(Node* node) : JSCallOrConstructNode(node) {
1489 DCHECK_EQ(IrOpcode::kJSWasmCall, node->opcode());
1490 }
1491
Parameters()1492 const JSWasmCallParameters& Parameters() const {
1493 return OpParameter<JSWasmCallParameters>(node()->op());
1494 }
1495
1496 #define INPUTS(V) \
1497 V(Target, target, 0, Object) \
1498 V(Receiver, receiver, 1, Object)
1499 INPUTS(DEFINE_INPUT_ACCESSORS)
1500 #undef INPUTS
1501
1502 static constexpr int kReceiverInputCount = 1;
1503 STATIC_ASSERT(kReceiverInputCount ==
1504 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1505
ArgumentCount()1506 int ArgumentCount() const override {
1507 // Note: The count reported by this function depends only on the parameter
1508 // count, thus adding/removing inputs will not affect it.
1509 return Parameters().arity_without_implicit_args();
1510 }
1511
1512 static Type TypeForWasmReturnType(const wasm::ValueType& type);
1513 };
1514 #endif // V8_ENABLE_WEBASSEMBLY
1515
1516 template <int kOpcode>
1517 class JSConstructNodeBase final : public JSCallOrConstructNode {
1518 public:
JSConstructNodeBase(Node * node)1519 explicit constexpr JSConstructNodeBase(Node* node)
1520 : JSCallOrConstructNode(node) {
1521 DCHECK_EQ(kOpcode, node->opcode());
1522 }
1523
Parameters()1524 const ConstructParameters& Parameters() const {
1525 return ConstructParametersOf(node()->op());
1526 }
1527
1528 #define INPUTS(V) \
1529 V(Target, target, 0, Object) \
1530 V(NewTarget, new_target, 1, Object)
1531 INPUTS(DEFINE_INPUT_ACCESSORS)
1532 #undef INPUTS
1533
1534 static constexpr int kNewTargetInputCount = 1;
1535 STATIC_ASSERT(kNewTargetInputCount ==
1536 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1537
ArgumentCount()1538 int ArgumentCount() const {
1539 // Note: The count reported by this function depends only on the parameter,
1540 // thus adding/removing inputs will not affect it.
1541 return Parameters().arity_without_implicit_args();
1542 }
1543 };
1544
1545 using JSConstructNode = JSConstructNodeBase<IrOpcode::kJSConstruct>;
1546 using JSConstructWithSpreadNode =
1547 JSConstructNodeBase<IrOpcode::kJSConstructWithSpread>;
1548 using JSConstructWithArrayLikeNode =
1549 JSConstructNodeBase<IrOpcode::kJSConstructWithArrayLike>;
1550
1551 class JSLoadNamedNode final : public JSNodeWrapperBase {
1552 public:
JSLoadNamedNode(Node * node)1553 explicit constexpr JSLoadNamedNode(Node* node) : JSNodeWrapperBase(node) {
1554 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
1555 }
1556
Parameters()1557 const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1558
1559 #define INPUTS(V) \
1560 V(Object, object, 0, Object) \
1561 V(FeedbackVector, feedback_vector, 1, HeapObject)
1562 INPUTS(DEFINE_INPUT_ACCESSORS)
1563 #undef INPUTS
1564 };
1565
1566 class JSLoadNamedFromSuperNode final : public JSNodeWrapperBase {
1567 public:
JSLoadNamedFromSuperNode(Node * node)1568 explicit constexpr JSLoadNamedFromSuperNode(Node* node)
1569 : JSNodeWrapperBase(node) {
1570 DCHECK_EQ(IrOpcode::kJSLoadNamedFromSuper, node->opcode());
1571 }
1572
Parameters()1573 const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1574
1575 #define INPUTS(V) \
1576 V(Receiver, receiver, 0, Object) \
1577 V(HomeObject, home_object, 1, Object) \
1578 V(FeedbackVector, feedback_vector, 2, HeapObject)
1579 INPUTS(DEFINE_INPUT_ACCESSORS)
1580 #undef INPUTS
1581 };
1582
1583 class JSSetNamedPropertyNode final : public JSNodeWrapperBase {
1584 public:
JSSetNamedPropertyNode(Node * node)1585 explicit constexpr JSSetNamedPropertyNode(Node* node)
1586 : JSNodeWrapperBase(node) {
1587 DCHECK_EQ(IrOpcode::kJSSetNamedProperty, node->opcode());
1588 }
1589
Parameters()1590 const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1591
1592 #define INPUTS(V) \
1593 V(Object, object, 0, Object) \
1594 V(Value, value, 1, Object) \
1595 V(FeedbackVector, feedback_vector, 2, HeapObject)
1596 INPUTS(DEFINE_INPUT_ACCESSORS)
1597 #undef INPUTS
1598 };
1599
1600 class JSDefineNamedOwnPropertyNode final : public JSNodeWrapperBase {
1601 public:
JSDefineNamedOwnPropertyNode(Node * node)1602 explicit constexpr JSDefineNamedOwnPropertyNode(Node* node)
1603 : JSNodeWrapperBase(node) {
1604 DCHECK_EQ(IrOpcode::kJSDefineNamedOwnProperty, node->opcode());
1605 }
1606
Parameters()1607 const DefineNamedOwnPropertyParameters& Parameters() const {
1608 return DefineNamedOwnPropertyParametersOf(node()->op());
1609 }
1610
1611 #define INPUTS(V) \
1612 V(Object, object, 0, Object) \
1613 V(Value, value, 1, Object) \
1614 V(FeedbackVector, feedback_vector, 2, HeapObject)
1615 INPUTS(DEFINE_INPUT_ACCESSORS)
1616 #undef INPUTS
1617 };
1618
1619 class JSStoreGlobalNode final : public JSNodeWrapperBase {
1620 public:
JSStoreGlobalNode(Node * node)1621 explicit constexpr JSStoreGlobalNode(Node* node) : JSNodeWrapperBase(node) {
1622 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
1623 }
1624
Parameters()1625 const StoreGlobalParameters& Parameters() const {
1626 return StoreGlobalParametersOf(node()->op());
1627 }
1628
1629 #define INPUTS(V) \
1630 V(Value, value, 0, Object) \
1631 V(FeedbackVector, feedback_vector, 1, HeapObject)
1632 INPUTS(DEFINE_INPUT_ACCESSORS)
1633 #undef INPUTS
1634 };
1635
1636 class JSLoadGlobalNode final : public JSNodeWrapperBase {
1637 public:
JSLoadGlobalNode(Node * node)1638 explicit constexpr JSLoadGlobalNode(Node* node) : JSNodeWrapperBase(node) {
1639 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
1640 }
1641
Parameters()1642 const LoadGlobalParameters& Parameters() const {
1643 return LoadGlobalParametersOf(node()->op());
1644 }
1645
1646 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1647 INPUTS(DEFINE_INPUT_ACCESSORS)
1648 #undef INPUTS
1649 };
1650
1651 class JSCreateEmptyLiteralArrayNode final : public JSNodeWrapperBase {
1652 public:
JSCreateEmptyLiteralArrayNode(Node * node)1653 explicit constexpr JSCreateEmptyLiteralArrayNode(Node* node)
1654 : JSNodeWrapperBase(node) {
1655 DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
1656 }
1657
Parameters()1658 const FeedbackParameter& Parameters() const {
1659 return FeedbackParameterOf(node()->op());
1660 }
1661
1662 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1663 INPUTS(DEFINE_INPUT_ACCESSORS)
1664 #undef INPUTS
1665 };
1666
1667 class JSDefineKeyedOwnPropertyInLiteralNode final : public JSNodeWrapperBase {
1668 public:
JSDefineKeyedOwnPropertyInLiteralNode(Node * node)1669 explicit constexpr JSDefineKeyedOwnPropertyInLiteralNode(Node* node)
1670 : JSNodeWrapperBase(node) {
1671 DCHECK_EQ(IrOpcode::kJSDefineKeyedOwnPropertyInLiteral, node->opcode());
1672 }
1673
Parameters()1674 const FeedbackParameter& Parameters() const {
1675 return FeedbackParameterOf(node()->op());
1676 }
1677
1678 #define INPUTS(V) \
1679 V(Object, object, 0, Object) \
1680 V(Name, name, 1, Object) \
1681 V(Value, value, 2, Object) \
1682 V(Flags, flags, 3, Object) \
1683 V(FeedbackVector, feedback_vector, 4, HeapObject)
1684 INPUTS(DEFINE_INPUT_ACCESSORS)
1685 #undef INPUTS
1686 };
1687
1688 class JSStoreInArrayLiteralNode final : public JSNodeWrapperBase {
1689 public:
JSStoreInArrayLiteralNode(Node * node)1690 explicit constexpr JSStoreInArrayLiteralNode(Node* node)
1691 : JSNodeWrapperBase(node) {
1692 DCHECK_EQ(IrOpcode::kJSStoreInArrayLiteral, node->opcode());
1693 }
1694
Parameters()1695 const FeedbackParameter& Parameters() const {
1696 return FeedbackParameterOf(node()->op());
1697 }
1698
1699 #define INPUTS(V) \
1700 V(Array, array, 0, Object) \
1701 V(Index, index, 1, Object) \
1702 V(Value, value, 2, Object) \
1703 V(FeedbackVector, feedback_vector, 3, HeapObject)
1704 INPUTS(DEFINE_INPUT_ACCESSORS)
1705 #undef INPUTS
1706 };
1707
1708 class JSCreateClosureNode final : public JSNodeWrapperBase {
1709 public:
JSCreateClosureNode(Node * node)1710 explicit constexpr JSCreateClosureNode(Node* node) : JSNodeWrapperBase(node) {
1711 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
1712 }
1713
Parameters()1714 const CreateClosureParameters& Parameters() const {
1715 return CreateClosureParametersOf(node()->op());
1716 }
1717
1718 #define INPUTS(V) V(FeedbackCell, feedback_cell, 0, FeedbackCell)
1719 INPUTS(DEFINE_INPUT_ACCESSORS)
1720 #undef INPUTS
1721
1722 FeedbackCellRef GetFeedbackCellRefChecked(JSHeapBroker* broker) const;
1723 };
1724
1725 class JSForInPrepareNode final : public JSNodeWrapperBase {
1726 public:
JSForInPrepareNode(Node * node)1727 explicit constexpr JSForInPrepareNode(Node* node) : JSNodeWrapperBase(node) {
1728 DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode());
1729 }
1730
Parameters()1731 const ForInParameters& Parameters() const {
1732 return ForInParametersOf(node()->op());
1733 }
1734
1735 #define INPUTS(V) \
1736 V(Enumerator, enumerator, 0, Object) \
1737 V(FeedbackVector, feedback_vector, 1, HeapObject)
1738 INPUTS(DEFINE_INPUT_ACCESSORS)
1739 #undef INPUTS
1740 };
1741
1742 class JSForInNextNode final : public JSNodeWrapperBase {
1743 public:
JSForInNextNode(Node * node)1744 explicit constexpr JSForInNextNode(Node* node) : JSNodeWrapperBase(node) {
1745 DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
1746 }
1747
Parameters()1748 const ForInParameters& Parameters() const {
1749 return ForInParametersOf(node()->op());
1750 }
1751
1752 #define INPUTS(V) \
1753 V(Receiver, receiver, 0, Object) \
1754 V(CacheArray, cache_array, 1, Object) \
1755 V(CacheType, cache_type, 2, Object) \
1756 V(Index, index, 3, Smi) \
1757 V(FeedbackVector, feedback_vector, 4, HeapObject)
1758 INPUTS(DEFINE_INPUT_ACCESSORS)
1759 #undef INPUTS
1760 };
1761
1762 #undef DEFINE_INPUT_ACCESSORS
1763
1764 } // namespace compiler
1765 } // namespace internal
1766 } // namespace v8
1767
1768 #endif // V8_COMPILER_JS_OPERATOR_H_
1769