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/typer.h"
6
7 #include <iomanip>
8
9 #include "src/base/flags.h"
10 #include "src/bootstrapper.h"
11 #include "src/compiler/common-operator.h"
12 #include "src/compiler/graph-reducer.h"
13 #include "src/compiler/js-operator.h"
14 #include "src/compiler/linkage.h"
15 #include "src/compiler/loop-variable-optimizer.h"
16 #include "src/compiler/node-properties.h"
17 #include "src/compiler/node.h"
18 #include "src/compiler/operation-typer.h"
19 #include "src/compiler/simplified-operator.h"
20 #include "src/compiler/type-cache.h"
21 #include "src/objects-inl.h"
22
23 namespace v8 {
24 namespace internal {
25 namespace compiler {
26
27 class Typer::Decorator final : public GraphDecorator {
28 public:
Decorator(Typer * typer)29 explicit Decorator(Typer* typer) : typer_(typer) {}
30 void Decorate(Node* node) final;
31
32 private:
33 Typer* const typer_;
34 };
35
Typer(Isolate * isolate,JSHeapBroker * js_heap_broker,Flags flags,Graph * graph)36 Typer::Typer(Isolate* isolate, JSHeapBroker* js_heap_broker, Flags flags,
37 Graph* graph)
38 : flags_(flags),
39 graph_(graph),
40 decorator_(nullptr),
41 cache_(TypeCache::Get()),
42 js_heap_broker_(js_heap_broker),
43 operation_typer_(isolate, js_heap_broker, zone()) {
44 singleton_false_ = operation_typer_.singleton_false();
45 singleton_true_ = operation_typer_.singleton_true();
46
47 decorator_ = new (zone()) Decorator(this);
48 graph_->AddDecorator(decorator_);
49 }
50
51
~Typer()52 Typer::~Typer() {
53 graph_->RemoveDecorator(decorator_);
54 }
55
56
57 class Typer::Visitor : public Reducer {
58 public:
Visitor(Typer * typer,LoopVariableOptimizer * induction_vars)59 explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
60 : typer_(typer),
61 induction_vars_(induction_vars),
62 weakened_nodes_(typer->zone()) {}
63
reducer_name() const64 const char* reducer_name() const override { return "Typer"; }
65
Reduce(Node * node)66 Reduction Reduce(Node* node) override {
67 if (node->op()->ValueOutputCount() == 0) return NoChange();
68 switch (node->opcode()) {
69 #define DECLARE_CASE(x) \
70 case IrOpcode::k##x: \
71 return UpdateType(node, TypeBinaryOp(node, x##Typer));
72 JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
73 #undef DECLARE_CASE
74
75 #define DECLARE_CASE(x) \
76 case IrOpcode::k##x: \
77 return UpdateType(node, Type##x(node));
78 DECLARE_CASE(Start)
79 DECLARE_CASE(IfException)
80 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
81 COMMON_OP_LIST(DECLARE_CASE)
82 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
83 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
84 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
85 JS_OBJECT_OP_LIST(DECLARE_CASE)
86 JS_CONTEXT_OP_LIST(DECLARE_CASE)
87 JS_OTHER_OP_LIST(DECLARE_CASE)
88 #undef DECLARE_CASE
89
90 #define DECLARE_CASE(x) \
91 case IrOpcode::k##x: \
92 return UpdateType(node, TypeBinaryOp(node, x));
93 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
94 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
95 #undef DECLARE_CASE
96
97 #define DECLARE_CASE(x) \
98 case IrOpcode::k##x: \
99 return UpdateType(node, TypeUnaryOp(node, x));
100 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
101 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
102 #undef DECLARE_CASE
103
104 #define DECLARE_CASE(x) case IrOpcode::k##x:
105 DECLARE_CASE(Loop)
106 DECLARE_CASE(Branch)
107 DECLARE_CASE(IfTrue)
108 DECLARE_CASE(IfFalse)
109 DECLARE_CASE(IfSuccess)
110 DECLARE_CASE(Switch)
111 DECLARE_CASE(IfValue)
112 DECLARE_CASE(IfDefault)
113 DECLARE_CASE(Merge)
114 DECLARE_CASE(Deoptimize)
115 DECLARE_CASE(DeoptimizeIf)
116 DECLARE_CASE(DeoptimizeUnless)
117 DECLARE_CASE(TrapIf)
118 DECLARE_CASE(TrapUnless)
119 DECLARE_CASE(Return)
120 DECLARE_CASE(TailCall)
121 DECLARE_CASE(Terminate)
122 DECLARE_CASE(OsrNormalEntry)
123 DECLARE_CASE(OsrLoopEntry)
124 DECLARE_CASE(Throw)
125 DECLARE_CASE(End)
126 SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
127 SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
128 MACHINE_SIMD_OP_LIST(DECLARE_CASE)
129 MACHINE_OP_LIST(DECLARE_CASE)
130 #undef DECLARE_CASE
131 break;
132 }
133 return NoChange();
134 }
135
TypeNode(Node * node)136 Type TypeNode(Node* node) {
137 switch (node->opcode()) {
138 #define DECLARE_CASE(x) \
139 case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
140 JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
141 #undef DECLARE_CASE
142
143 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
144 DECLARE_CASE(Start)
145 DECLARE_CASE(IfException)
146 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
147 COMMON_OP_LIST(DECLARE_CASE)
148 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
150 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
151 JS_OBJECT_OP_LIST(DECLARE_CASE)
152 JS_CONTEXT_OP_LIST(DECLARE_CASE)
153 JS_OTHER_OP_LIST(DECLARE_CASE)
154 #undef DECLARE_CASE
155
156 #define DECLARE_CASE(x) \
157 case IrOpcode::k##x: \
158 return TypeBinaryOp(node, x);
159 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
160 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
161 #undef DECLARE_CASE
162
163 #define DECLARE_CASE(x) \
164 case IrOpcode::k##x: \
165 return TypeUnaryOp(node, x);
166 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
167 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
168 #undef DECLARE_CASE
169
170 #define DECLARE_CASE(x) case IrOpcode::k##x:
171 DECLARE_CASE(Loop)
172 DECLARE_CASE(Branch)
173 DECLARE_CASE(IfTrue)
174 DECLARE_CASE(IfFalse)
175 DECLARE_CASE(IfSuccess)
176 DECLARE_CASE(Switch)
177 DECLARE_CASE(IfValue)
178 DECLARE_CASE(IfDefault)
179 DECLARE_CASE(Merge)
180 DECLARE_CASE(Deoptimize)
181 DECLARE_CASE(DeoptimizeIf)
182 DECLARE_CASE(DeoptimizeUnless)
183 DECLARE_CASE(TrapIf)
184 DECLARE_CASE(TrapUnless)
185 DECLARE_CASE(Return)
186 DECLARE_CASE(TailCall)
187 DECLARE_CASE(Terminate)
188 DECLARE_CASE(OsrNormalEntry)
189 DECLARE_CASE(OsrLoopEntry)
190 DECLARE_CASE(Throw)
191 DECLARE_CASE(End)
192 SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
193 SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
194 MACHINE_SIMD_OP_LIST(DECLARE_CASE)
195 MACHINE_OP_LIST(DECLARE_CASE)
196 #undef DECLARE_CASE
197 break;
198 }
199 UNREACHABLE();
200 }
201
202 Type TypeConstant(Handle<Object> value);
203
204 private:
205 Typer* typer_;
206 LoopVariableOptimizer* induction_vars_;
207 ZoneSet<NodeId> weakened_nodes_;
208
209 #define DECLARE_METHOD(x) inline Type Type##x(Node* node);
210 DECLARE_METHOD(Start)
DECLARE_METHOD(IfException)211 DECLARE_METHOD(IfException)
212 COMMON_OP_LIST(DECLARE_METHOD)
213 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
214 SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
215 JS_OP_LIST(DECLARE_METHOD)
216 #undef DECLARE_METHOD
217
218 Type TypeOrNone(Node* node) {
219 return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
220 : Type::None();
221 }
222
Operand(Node * node,int i)223 Type Operand(Node* node, int i) {
224 Node* operand_node = NodeProperties::GetValueInput(node, i);
225 return TypeOrNone(operand_node);
226 }
227
228 Type Weaken(Node* node, Type current_type, Type previous_type);
229
zone()230 Zone* zone() { return typer_->zone(); }
graph()231 Graph* graph() { return typer_->graph(); }
232
SetWeakened(NodeId node_id)233 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
IsWeakened(NodeId node_id)234 bool IsWeakened(NodeId node_id) {
235 return weakened_nodes_.find(node_id) != weakened_nodes_.end();
236 }
237
238 typedef Type (*UnaryTyperFun)(Type, Typer* t);
239 typedef Type (*BinaryTyperFun)(Type, Type, Typer* t);
240
241 Type TypeUnaryOp(Node* node, UnaryTyperFun);
242 Type TypeBinaryOp(Node* node, BinaryTyperFun);
243
244 static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
245 BinaryTyperFun f);
246
247 enum ComparisonOutcomeFlags {
248 kComparisonTrue = 1,
249 kComparisonFalse = 2,
250 kComparisonUndefined = 4
251 };
252 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
253
254 static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
255 static Type FalsifyUndefined(ComparisonOutcome, Typer*);
256
257 static Type BitwiseNot(Type, Typer*);
258 static Type Decrement(Type, Typer*);
259 static Type Increment(Type, Typer*);
260 static Type Negate(Type, Typer*);
261
262 static Type ToPrimitive(Type, Typer*);
263 static Type ToBoolean(Type, Typer*);
264 static Type ToInteger(Type, Typer*);
265 static Type ToLength(Type, Typer*);
266 static Type ToName(Type, Typer*);
267 static Type ToNumber(Type, Typer*);
268 static Type ToNumberConvertBigInt(Type, Typer*);
269 static Type ToNumeric(Type, Typer*);
270 static Type ToObject(Type, Typer*);
271 static Type ToString(Type, Typer*);
272 #define DECLARE_METHOD(Name) \
273 static Type Name(Type type, Typer* t) { \
274 return t->operation_typer_.Name(type); \
275 }
276 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
277 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
278 #undef DECLARE_METHOD
279 #define DECLARE_METHOD(Name) \
280 static Type Name(Type lhs, Type rhs, Typer* t) { \
281 return t->operation_typer_.Name(lhs, rhs); \
282 }
283 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
284 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
285 #undef DECLARE_METHOD
286
287 static Type ObjectIsArrayBufferView(Type, Typer*);
288 static Type ObjectIsBigInt(Type, Typer*);
289 static Type ObjectIsCallable(Type, Typer*);
290 static Type ObjectIsConstructor(Type, Typer*);
291 static Type ObjectIsDetectableCallable(Type, Typer*);
292 static Type ObjectIsMinusZero(Type, Typer*);
293 static Type ObjectIsNaN(Type, Typer*);
294 static Type NumberIsNaN(Type, Typer*);
295 static Type ObjectIsNonCallable(Type, Typer*);
296 static Type ObjectIsNumber(Type, Typer*);
297 static Type ObjectIsReceiver(Type, Typer*);
298 static Type ObjectIsSmi(Type, Typer*);
299 static Type ObjectIsString(Type, Typer*);
300 static Type ObjectIsSymbol(Type, Typer*);
301 static Type ObjectIsUndetectable(Type, Typer*);
302
303 static ComparisonOutcome JSCompareTyper(Type, Type, Typer*);
304 static ComparisonOutcome NumberCompareTyper(Type, Type, Typer*);
305
306 #define DECLARE_METHOD(x) static Type x##Typer(Type, Type, Typer*);
307 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
308 #undef DECLARE_METHOD
309
310 static Type JSCallTyper(Type, Typer*);
311
312 static Type NumberEqualTyper(Type, Type, Typer*);
313 static Type NumberLessThanTyper(Type, Type, Typer*);
314 static Type NumberLessThanOrEqualTyper(Type, Type, Typer*);
315 static Type ReferenceEqualTyper(Type, Type, Typer*);
316 static Type SameValueTyper(Type, Type, Typer*);
317 static Type StringFromSingleCharCodeTyper(Type, Typer*);
318 static Type StringFromSingleCodePointTyper(Type, Typer*);
319
UpdateType(Node * node,Type current)320 Reduction UpdateType(Node* node, Type current) {
321 if (NodeProperties::IsTyped(node)) {
322 // Widen the type of a previously typed node.
323 Type previous = NodeProperties::GetType(node);
324 if (node->opcode() == IrOpcode::kPhi ||
325 node->opcode() == IrOpcode::kInductionVariablePhi) {
326 // Speed up termination in the presence of range types:
327 current = Weaken(node, current, previous);
328 }
329
330 CHECK(previous.Is(current));
331
332 NodeProperties::SetType(node, current);
333 if (!current.Is(previous)) {
334 // If something changed, revisit all uses.
335 return Changed(node);
336 }
337 return NoChange();
338 } else {
339 // No previous type, simply update the type.
340 NodeProperties::SetType(node, current);
341 return Changed(node);
342 }
343 }
344 };
345
Run()346 void Typer::Run() { Run(NodeVector(zone()), nullptr); }
347
Run(const NodeVector & roots,LoopVariableOptimizer * induction_vars)348 void Typer::Run(const NodeVector& roots,
349 LoopVariableOptimizer* induction_vars) {
350 if (induction_vars != nullptr) {
351 induction_vars->ChangeToInductionVariablePhis();
352 }
353 Visitor visitor(this, induction_vars);
354 GraphReducer graph_reducer(zone(), graph());
355 graph_reducer.AddReducer(&visitor);
356 for (Node* const root : roots) graph_reducer.ReduceNode(root);
357 graph_reducer.ReduceGraph();
358
359 if (induction_vars != nullptr) {
360 induction_vars->ChangeToPhisAndInsertGuards();
361 }
362 }
363
Decorate(Node * node)364 void Typer::Decorator::Decorate(Node* node) {
365 if (node->op()->ValueOutputCount() > 0) {
366 // Only eagerly type-decorate nodes with known input types.
367 // Other cases will generally require a proper fixpoint iteration with Run.
368 bool is_typed = NodeProperties::IsTyped(node);
369 if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
370 Visitor typing(typer_, nullptr);
371 Type type = typing.TypeNode(node);
372 if (is_typed) {
373 type = Type::Intersect(type, NodeProperties::GetType(node),
374 typer_->zone());
375 }
376 NodeProperties::SetType(node, type);
377 }
378 }
379 }
380
381
382 // -----------------------------------------------------------------------------
383
384 // Helper functions that lift a function f on types to a function on bounds,
385 // and uses that to type the given node. Note that f is never called with None
386 // as an argument.
387
TypeUnaryOp(Node * node,UnaryTyperFun f)388 Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
389 Type input = Operand(node, 0);
390 return input.IsNone() ? Type::None() : f(input, typer_);
391 }
392
TypeBinaryOp(Node * node,BinaryTyperFun f)393 Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
394 Type left = Operand(node, 0);
395 Type right = Operand(node, 1);
396 return left.IsNone() || right.IsNone() ? Type::None()
397 : f(left, right, typer_);
398 }
399
BinaryNumberOpTyper(Type lhs,Type rhs,Typer * t,BinaryTyperFun f)400 Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
401 BinaryTyperFun f) {
402 lhs = ToNumeric(lhs, t);
403 rhs = ToNumeric(rhs, t);
404 bool lhs_is_number = lhs.Is(Type::Number());
405 bool rhs_is_number = rhs.Is(Type::Number());
406 if (lhs_is_number && rhs_is_number) {
407 return f(lhs, rhs, t);
408 }
409 if (lhs_is_number || rhs_is_number) {
410 return Type::Number();
411 }
412 if (lhs.Is(Type::BigInt()) || rhs.Is(Type::BigInt())) {
413 return Type::BigInt();
414 }
415 return Type::Numeric();
416 }
417
Invert(ComparisonOutcome outcome,Typer * t)418 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
419 ComparisonOutcome outcome, Typer* t) {
420 ComparisonOutcome result(0);
421 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
422 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
423 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
424 return result;
425 }
426
FalsifyUndefined(ComparisonOutcome outcome,Typer * t)427 Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
428 if ((outcome & kComparisonFalse) != 0 ||
429 (outcome & kComparisonUndefined) != 0) {
430 return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
431 : t->singleton_false_;
432 }
433 // Type should be non empty, so we know it should be true.
434 DCHECK_NE(0, outcome & kComparisonTrue);
435 return t->singleton_true_;
436 }
437
BitwiseNot(Type type,Typer * t)438 Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
439 type = ToNumeric(type, t);
440 if (type.Is(Type::Number())) {
441 return NumberBitwiseXor(type, t->cache_.kSingletonMinusOne, t);
442 }
443 return Type::Numeric();
444 }
445
Decrement(Type type,Typer * t)446 Type Typer::Visitor::Decrement(Type type, Typer* t) {
447 type = ToNumeric(type, t);
448 if (type.Is(Type::Number())) {
449 return NumberSubtract(type, t->cache_.kSingletonOne, t);
450 }
451 return Type::Numeric();
452 }
453
Increment(Type type,Typer * t)454 Type Typer::Visitor::Increment(Type type, Typer* t) {
455 type = ToNumeric(type, t);
456 if (type.Is(Type::Number())) {
457 return NumberAdd(type, t->cache_.kSingletonOne, t);
458 }
459 return Type::Numeric();
460 }
461
Negate(Type type,Typer * t)462 Type Typer::Visitor::Negate(Type type, Typer* t) {
463 type = ToNumeric(type, t);
464 if (type.Is(Type::Number())) {
465 return NumberMultiply(type, t->cache_.kSingletonMinusOne, t);
466 }
467 return Type::Numeric();
468 }
469
470 // Type conversion.
471
ToPrimitive(Type type,Typer * t)472 Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
473 if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
474 return type;
475 }
476 return Type::Primitive();
477 }
478
ToBoolean(Type type,Typer * t)479 Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
480 return t->operation_typer()->ToBoolean(type);
481 }
482
483
484 // static
ToInteger(Type type,Typer * t)485 Type Typer::Visitor::ToInteger(Type type, Typer* t) {
486 // ES6 section 7.1.4 ToInteger ( argument )
487 type = ToNumber(type, t);
488 if (type.Is(t->cache_.kIntegerOrMinusZero)) return type;
489 if (type.Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
490 return Type::Union(
491 Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()),
492 t->cache_.kSingletonZero, t->zone());
493 }
494 return t->cache_.kIntegerOrMinusZero;
495 }
496
497
498 // static
ToLength(Type type,Typer * t)499 Type Typer::Visitor::ToLength(Type type, Typer* t) {
500 // ES6 section 7.1.15 ToLength ( argument )
501 type = ToInteger(type, t);
502 if (type.IsNone()) return type;
503 double min = type.Min();
504 double max = type.Max();
505 if (max <= 0.0) {
506 return Type::NewConstant(0, t->zone());
507 }
508 if (min >= kMaxSafeInteger) {
509 return Type::NewConstant(kMaxSafeInteger, t->zone());
510 }
511 if (min <= 0.0) min = 0.0;
512 if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
513 return Type::Range(min, max, t->zone());
514 }
515
516
517 // static
ToName(Type type,Typer * t)518 Type Typer::Visitor::ToName(Type type, Typer* t) {
519 // ES6 section 7.1.14 ToPropertyKey ( argument )
520 type = ToPrimitive(type, t);
521 if (type.Is(Type::Name())) return type;
522 if (type.Maybe(Type::Symbol())) return Type::Name();
523 return ToString(type, t);
524 }
525
526
527 // static
ToNumber(Type type,Typer * t)528 Type Typer::Visitor::ToNumber(Type type, Typer* t) {
529 return t->operation_typer_.ToNumber(type);
530 }
531
532 // static
ToNumberConvertBigInt(Type type,Typer * t)533 Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
534 return t->operation_typer_.ToNumberConvertBigInt(type);
535 }
536
537 // static
ToNumeric(Type type,Typer * t)538 Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
539 return t->operation_typer_.ToNumeric(type);
540 }
541
542 // static
ToObject(Type type,Typer * t)543 Type Typer::Visitor::ToObject(Type type, Typer* t) {
544 // ES6 section 7.1.13 ToObject ( argument )
545 if (type.Is(Type::Receiver())) return type;
546 if (type.Is(Type::Primitive())) return Type::OtherObject();
547 if (!type.Maybe(Type::OtherUndetectable())) {
548 return Type::DetectableReceiver();
549 }
550 return Type::Receiver();
551 }
552
553
554 // static
ToString(Type type,Typer * t)555 Type Typer::Visitor::ToString(Type type, Typer* t) {
556 // ES6 section 7.1.12 ToString ( argument )
557 type = ToPrimitive(type, t);
558 if (type.Is(Type::String())) return type;
559 return Type::String();
560 }
561
562 // Type checks.
563
ObjectIsArrayBufferView(Type type,Typer * t)564 Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
565 // TODO(turbofan): Introduce a Type::ArrayBufferView?
566 if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
567 return Type::Boolean();
568 }
569
ObjectIsBigInt(Type type,Typer * t)570 Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
571 if (type.Is(Type::BigInt())) return t->singleton_true_;
572 if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
573 return Type::Boolean();
574 }
575
ObjectIsCallable(Type type,Typer * t)576 Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
577 if (type.Is(Type::Callable())) return t->singleton_true_;
578 if (!type.Maybe(Type::Callable())) return t->singleton_false_;
579 return Type::Boolean();
580 }
581
ObjectIsConstructor(Type type,Typer * t)582 Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
583 // TODO(turbofan): Introduce a Type::Constructor?
584 if (!type.Maybe(Type::Callable())) return t->singleton_false_;
585 return Type::Boolean();
586 }
587
ObjectIsDetectableCallable(Type type,Typer * t)588 Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
589 if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
590 if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_;
591 return Type::Boolean();
592 }
593
ObjectIsMinusZero(Type type,Typer * t)594 Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
595 if (type.Is(Type::MinusZero())) return t->singleton_true_;
596 if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
597 return Type::Boolean();
598 }
599
ObjectIsNaN(Type type,Typer * t)600 Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
601 if (type.Is(Type::NaN())) return t->singleton_true_;
602 if (!type.Maybe(Type::NaN())) return t->singleton_false_;
603 return Type::Boolean();
604 }
605
NumberIsNaN(Type type,Typer * t)606 Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
607 if (type.Is(Type::NaN())) return t->singleton_true_;
608 if (!type.Maybe(Type::NaN())) return t->singleton_false_;
609 return Type::Boolean();
610 }
611
ObjectIsNonCallable(Type type,Typer * t)612 Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
613 if (type.Is(Type::NonCallable())) return t->singleton_true_;
614 if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
615 return Type::Boolean();
616 }
617
ObjectIsNumber(Type type,Typer * t)618 Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
619 if (type.Is(Type::Number())) return t->singleton_true_;
620 if (!type.Maybe(Type::Number())) return t->singleton_false_;
621 return Type::Boolean();
622 }
623
ObjectIsReceiver(Type type,Typer * t)624 Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
625 if (type.Is(Type::Receiver())) return t->singleton_true_;
626 if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
627 return Type::Boolean();
628 }
629
ObjectIsSmi(Type type,Typer * t)630 Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
631 if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
632 return Type::Boolean();
633 }
634
ObjectIsString(Type type,Typer * t)635 Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
636 if (type.Is(Type::String())) return t->singleton_true_;
637 if (!type.Maybe(Type::String())) return t->singleton_false_;
638 return Type::Boolean();
639 }
640
ObjectIsSymbol(Type type,Typer * t)641 Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
642 if (type.Is(Type::Symbol())) return t->singleton_true_;
643 if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
644 return Type::Boolean();
645 }
646
ObjectIsUndetectable(Type type,Typer * t)647 Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
648 if (type.Is(Type::Undetectable())) return t->singleton_true_;
649 if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
650 return Type::Boolean();
651 }
652
653
654 // -----------------------------------------------------------------------------
655
656
657 // Control operators.
658
TypeStart(Node * node)659 Type Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
660
TypeIfException(Node * node)661 Type Typer::Visitor::TypeIfException(Node* node) { return Type::NonInternal(); }
662
663 // Common operators.
664
TypeParameter(Node * node)665 Type Typer::Visitor::TypeParameter(Node* node) {
666 Node* const start = node->InputAt(0);
667 DCHECK_EQ(IrOpcode::kStart, start->opcode());
668 int const parameter_count = start->op()->ValueOutputCount() - 4;
669 DCHECK_LE(1, parameter_count);
670 int const index = ParameterIndexOf(node->op());
671 if (index == Linkage::kJSCallClosureParamIndex) {
672 return Type::Function();
673 } else if (index == 0) {
674 if (typer_->flags() & Typer::kThisIsReceiver) {
675 return Type::Receiver();
676 } else {
677 // Parameter[this] can be the_hole for derived class constructors.
678 return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
679 }
680 } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
681 if (typer_->flags() & Typer::kNewTargetIsReceiver) {
682 return Type::Receiver();
683 } else {
684 return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
685 }
686 } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
687 return Type::Range(0.0, Code::kMaxArguments, typer_->zone());
688 } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
689 return Type::OtherInternal();
690 }
691 return Type::NonInternal();
692 }
693
TypeOsrValue(Node * node)694 Type Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
695
TypeRetain(Node * node)696 Type Typer::Visitor::TypeRetain(Node* node) { UNREACHABLE(); }
697
TypeInt32Constant(Node * node)698 Type Typer::Visitor::TypeInt32Constant(Node* node) { UNREACHABLE(); }
699
TypeInt64Constant(Node * node)700 Type Typer::Visitor::TypeInt64Constant(Node* node) { UNREACHABLE(); }
701
TypeRelocatableInt32Constant(Node * node)702 Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { UNREACHABLE(); }
703
TypeRelocatableInt64Constant(Node * node)704 Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { UNREACHABLE(); }
705
TypeFloat32Constant(Node * node)706 Type Typer::Visitor::TypeFloat32Constant(Node* node) { UNREACHABLE(); }
707
TypeFloat64Constant(Node * node)708 Type Typer::Visitor::TypeFloat64Constant(Node* node) { UNREACHABLE(); }
709
TypeNumberConstant(Node * node)710 Type Typer::Visitor::TypeNumberConstant(Node* node) {
711 double number = OpParameter<double>(node->op());
712 return Type::NewConstant(number, zone());
713 }
714
TypeHeapConstant(Node * node)715 Type Typer::Visitor::TypeHeapConstant(Node* node) {
716 return TypeConstant(HeapConstantOf(node->op()));
717 }
718
TypeExternalConstant(Node * node)719 Type Typer::Visitor::TypeExternalConstant(Node* node) {
720 return Type::ExternalPointer();
721 }
722
TypePointerConstant(Node * node)723 Type Typer::Visitor::TypePointerConstant(Node* node) {
724 return Type::ExternalPointer();
725 }
726
TypeSelect(Node * node)727 Type Typer::Visitor::TypeSelect(Node* node) {
728 return Type::Union(Operand(node, 1), Operand(node, 2), zone());
729 }
730
TypePhi(Node * node)731 Type Typer::Visitor::TypePhi(Node* node) {
732 int arity = node->op()->ValueInputCount();
733 Type type = Operand(node, 0);
734 for (int i = 1; i < arity; ++i) {
735 type = Type::Union(type, Operand(node, i), zone());
736 }
737 return type;
738 }
739
TypeInductionVariablePhi(Node * node)740 Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
741 int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
742 DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
743 DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());
744
745 Type initial_type = Operand(node, 0);
746 Type increment_type = Operand(node, 2);
747
748 // We only handle integer induction variables (otherwise ranges
749 // do not apply and we cannot do anything).
750 if (!initial_type.Is(typer_->cache_.kInteger) ||
751 !increment_type.Is(typer_->cache_.kInteger)) {
752 // Fallback to normal phi typing, but ensure monotonicity.
753 // (Unfortunately, without baking in the previous type, monotonicity might
754 // be violated because we might not yet have retyped the incrementing
755 // operation even though the increment's type might been already reflected
756 // in the induction variable phi.)
757 Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
758 : Type::None();
759 for (int i = 0; i < arity; ++i) {
760 type = Type::Union(type, Operand(node, i), zone());
761 }
762 return type;
763 }
764 // If we do not have enough type information for the initial value or
765 // the increment, just return the initial value's type.
766 if (initial_type.IsNone() ||
767 increment_type.Is(typer_->cache_.kSingletonZero)) {
768 return initial_type;
769 }
770
771 // Now process the bounds.
772 auto res = induction_vars_->induction_variables().find(node->id());
773 DCHECK(res != induction_vars_->induction_variables().end());
774 InductionVariable* induction_var = res->second;
775
776 InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
777
778 double min = -V8_INFINITY;
779 double max = V8_INFINITY;
780
781 double increment_min;
782 double increment_max;
783 if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
784 increment_min = increment_type.Min();
785 increment_max = increment_type.Max();
786 } else {
787 DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
788 increment_min = -increment_type.Max();
789 increment_max = -increment_type.Min();
790 }
791
792 if (increment_min >= 0) {
793 // increasing sequence
794 min = initial_type.Min();
795 for (auto bound : induction_var->upper_bounds()) {
796 Type bound_type = TypeOrNone(bound.bound);
797 // If the type is not an integer, just skip the bound.
798 if (!bound_type.Is(typer_->cache_.kInteger)) continue;
799 // If the type is not inhabited, then we can take the initial value.
800 if (bound_type.IsNone()) {
801 max = initial_type.Max();
802 break;
803 }
804 double bound_max = bound_type.Max();
805 if (bound.kind == InductionVariable::kStrict) {
806 bound_max -= 1;
807 }
808 max = std::min(max, bound_max + increment_max);
809 }
810 // The upper bound must be at least the initial value's upper bound.
811 max = std::max(max, initial_type.Max());
812 } else if (increment_max <= 0) {
813 // decreasing sequence
814 max = initial_type.Max();
815 for (auto bound : induction_var->lower_bounds()) {
816 Type bound_type = TypeOrNone(bound.bound);
817 // If the type is not an integer, just skip the bound.
818 if (!bound_type.Is(typer_->cache_.kInteger)) continue;
819 // If the type is not inhabited, then we can take the initial value.
820 if (bound_type.IsNone()) {
821 min = initial_type.Min();
822 break;
823 }
824 double bound_min = bound_type.Min();
825 if (bound.kind == InductionVariable::kStrict) {
826 bound_min += 1;
827 }
828 min = std::max(min, bound_min + increment_min);
829 }
830 // The lower bound must be at most the initial value's lower bound.
831 min = std::min(min, initial_type.Min());
832 } else {
833 // Shortcut: If the increment can be both positive and negative,
834 // the variable can go arbitrarily far, so just return integer.
835 return typer_->cache_.kInteger;
836 }
837 if (FLAG_trace_turbo_loop) {
838 StdoutStream{} << std::setprecision(10) << "Loop ("
839 << NodeProperties::GetControlInput(node)->id()
840 << ") variable bounds in "
841 << (arithmetic_type ==
842 InductionVariable::ArithmeticType::kAddition
843 ? "addition"
844 : "subtraction")
845 << " for phi " << node->id() << ": (" << min << ", " << max
846 << ")\n";
847 }
848 return Type::Range(min, max, typer_->zone());
849 }
850
TypeEffectPhi(Node * node)851 Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); }
852
TypeLoopExit(Node * node)853 Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }
854
TypeLoopExitValue(Node * node)855 Type Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
856
TypeLoopExitEffect(Node * node)857 Type Typer::Visitor::TypeLoopExitEffect(Node* node) { UNREACHABLE(); }
858
TypeEnsureWritableFastElements(Node * node)859 Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
860 return Operand(node, 1);
861 }
862
TypeMaybeGrowFastElements(Node * node)863 Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
864 return Operand(node, 1);
865 }
866
TypeTransitionElementsKind(Node * node)867 Type Typer::Visitor::TypeTransitionElementsKind(Node* node) { UNREACHABLE(); }
868
TypeCheckpoint(Node * node)869 Type Typer::Visitor::TypeCheckpoint(Node* node) { UNREACHABLE(); }
870
TypeBeginRegion(Node * node)871 Type Typer::Visitor::TypeBeginRegion(Node* node) { UNREACHABLE(); }
872
TypeFinishRegion(Node * node)873 Type Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
874
TypeFrameState(Node * node)875 Type Typer::Visitor::TypeFrameState(Node* node) {
876 // TODO(rossberg): Ideally FrameState wouldn't have a value output.
877 return Type::Internal();
878 }
879
TypeStateValues(Node * node)880 Type Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
881
TypeTypedStateValues(Node * node)882 Type Typer::Visitor::TypeTypedStateValues(Node* node) {
883 return Type::Internal();
884 }
885
TypeObjectId(Node * node)886 Type Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
887
TypeArgumentsElementsState(Node * node)888 Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
889 return Type::Internal();
890 }
891
TypeArgumentsLengthState(Node * node)892 Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
893 return Type::Internal();
894 }
895
TypeObjectState(Node * node)896 Type Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
897
TypeTypedObjectState(Node * node)898 Type Typer::Visitor::TypeTypedObjectState(Node* node) {
899 return Type::Internal();
900 }
901
TypeCall(Node * node)902 Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
903
TypeCallWithCallerSavedRegisters(Node * node)904 Type Typer::Visitor::TypeCallWithCallerSavedRegisters(Node* node) {
905 UNREACHABLE();
906 }
907
TypeProjection(Node * node)908 Type Typer::Visitor::TypeProjection(Node* node) {
909 Type const type = Operand(node, 0);
910 if (type.Is(Type::None())) return Type::None();
911 int const index = static_cast<int>(ProjectionIndexOf(node->op()));
912 if (type.IsTuple() && index < type.AsTuple()->Arity()) {
913 return type.AsTuple()->Element(index);
914 }
915 return Type::Any();
916 }
917
TypeMapGuard(Node * node)918 Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
919
TypeTypeGuard(Node * node)920 Type Typer::Visitor::TypeTypeGuard(Node* node) {
921 Type const type = Operand(node, 0);
922 return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
923 }
924
TypeDead(Node * node)925 Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
926
TypeDeadValue(Node * node)927 Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
928
TypeUnreachable(Node * node)929 Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
930
931 // JS comparison operators.
932
JSEqualTyper(Type lhs,Type rhs,Typer * t)933 Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
934 if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
935 if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
936 return t->singleton_true_;
937 }
938 if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
939 (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
940 return t->singleton_false_;
941 }
942 if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
943 // Types are equal and are inhabited only by a single semantic value,
944 // which is not nan due to the earlier check.
945 return t->singleton_true_;
946 }
947 return Type::Boolean();
948 }
949
JSStrictEqualTyper(Type lhs,Type rhs,Typer * t)950 Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
951 return t->operation_typer()->StrictEqual(lhs, rhs);
952 }
953
954 // The EcmaScript specification defines the four relational comparison operators
955 // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
956 // but returns undefined when the inputs cannot be compared.
957 // We implement the typing analogously.
JSCompareTyper(Type lhs,Type rhs,Typer * t)958 Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
959 Type rhs,
960 Typer* t) {
961 lhs = ToPrimitive(lhs, t);
962 rhs = ToPrimitive(rhs, t);
963 if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
964 return ComparisonOutcome(kComparisonTrue) |
965 ComparisonOutcome(kComparisonFalse);
966 }
967 lhs = ToNumeric(lhs, t);
968 rhs = ToNumeric(rhs, t);
969 if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
970 return NumberCompareTyper(lhs, rhs, t);
971 }
972 return ComparisonOutcome(kComparisonTrue) |
973 ComparisonOutcome(kComparisonFalse) |
974 ComparisonOutcome(kComparisonUndefined);
975 }
976
NumberCompareTyper(Type lhs,Type rhs,Typer * t)977 Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type lhs,
978 Type rhs,
979 Typer* t) {
980 DCHECK(lhs.Is(Type::Number()));
981 DCHECK(rhs.Is(Type::Number()));
982
983 // Shortcut for NaNs.
984 if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
985
986 ComparisonOutcome result;
987 if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
988 // Types are equal and are inhabited only by a single semantic value.
989 result = kComparisonFalse;
990 } else if (lhs.Min() >= rhs.Max()) {
991 result = kComparisonFalse;
992 } else if (lhs.Max() < rhs.Min()) {
993 result = kComparisonTrue;
994 } else {
995 // We cannot figure out the result, return both true and false. (We do not
996 // have to return undefined because that cannot affect the result of
997 // FalsifyUndefined.)
998 return ComparisonOutcome(kComparisonTrue) |
999 ComparisonOutcome(kComparisonFalse);
1000 }
1001 // Add the undefined if we could see NaN.
1002 if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1003 result |= kComparisonUndefined;
1004 }
1005 return result;
1006 }
1007
JSLessThanTyper(Type lhs,Type rhs,Typer * t)1008 Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1009 return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1010 }
1011
JSGreaterThanTyper(Type lhs,Type rhs,Typer * t)1012 Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1013 return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1014 }
1015
JSLessThanOrEqualTyper(Type lhs,Type rhs,Typer * t)1016 Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1017 return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1018 }
1019
JSGreaterThanOrEqualTyper(Type lhs,Type rhs,Typer * t)1020 Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1021 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1022 }
1023
1024 // JS bitwise operators.
1025
JSBitwiseOrTyper(Type lhs,Type rhs,Typer * t)1026 Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1027 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1028 }
1029
JSBitwiseAndTyper(Type lhs,Type rhs,Typer * t)1030 Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1031 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1032 }
1033
JSBitwiseXorTyper(Type lhs,Type rhs,Typer * t)1034 Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1035 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1036 }
1037
JSShiftLeftTyper(Type lhs,Type rhs,Typer * t)1038 Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1039 return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1040 }
1041
JSShiftRightTyper(Type lhs,Type rhs,Typer * t)1042 Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1043 return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1044 }
1045
JSShiftRightLogicalTyper(Type lhs,Type rhs,Typer * t)1046 Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1047 return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1048 }
1049
1050
1051 // JS arithmetic operators.
1052
JSAddTyper(Type lhs,Type rhs,Typer * t)1053 Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1054 lhs = ToPrimitive(lhs, t);
1055 rhs = ToPrimitive(rhs, t);
1056 if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1057 if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1058 return Type::String();
1059 } else {
1060 return Type::NumericOrString();
1061 }
1062 }
1063 // The addition must be numeric.
1064 return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1065 }
1066
JSSubtractTyper(Type lhs,Type rhs,Typer * t)1067 Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1068 return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1069 }
1070
JSMultiplyTyper(Type lhs,Type rhs,Typer * t)1071 Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1072 return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1073 }
1074
JSDivideTyper(Type lhs,Type rhs,Typer * t)1075 Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1076 return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1077 }
1078
JSModulusTyper(Type lhs,Type rhs,Typer * t)1079 Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1080 return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1081 }
1082
JSExponentiateTyper(Type lhs,Type rhs,Typer * t)1083 Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1084 // TODO(neis): Refine using BinaryNumberOpTyper?
1085 return Type::Numeric();
1086 }
1087
1088 // JS unary operators.
1089
TypeJSBitwiseNot(Node * node)1090 Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1091 return TypeUnaryOp(node, BitwiseNot);
1092 }
1093
TypeJSDecrement(Node * node)1094 Type Typer::Visitor::TypeJSDecrement(Node* node) {
1095 return TypeUnaryOp(node, Decrement);
1096 }
1097
TypeJSIncrement(Node * node)1098 Type Typer::Visitor::TypeJSIncrement(Node* node) {
1099 return TypeUnaryOp(node, Increment);
1100 }
1101
TypeJSNegate(Node * node)1102 Type Typer::Visitor::TypeJSNegate(Node* node) {
1103 return TypeUnaryOp(node, Negate);
1104 }
1105
TypeTypeOf(Node * node)1106 Type Typer::Visitor::TypeTypeOf(Node* node) {
1107 return Type::InternalizedString();
1108 }
1109
1110
1111 // JS conversion operators.
1112
TypeToBoolean(Node * node)1113 Type Typer::Visitor::TypeToBoolean(Node* node) {
1114 return TypeUnaryOp(node, ToBoolean);
1115 }
1116
TypeJSToInteger(Node * node)1117 Type Typer::Visitor::TypeJSToInteger(Node* node) {
1118 return TypeUnaryOp(node, ToInteger);
1119 }
1120
TypeJSToLength(Node * node)1121 Type Typer::Visitor::TypeJSToLength(Node* node) {
1122 return TypeUnaryOp(node, ToLength);
1123 }
1124
TypeJSToName(Node * node)1125 Type Typer::Visitor::TypeJSToName(Node* node) {
1126 return TypeUnaryOp(node, ToName);
1127 }
1128
TypeJSToNumber(Node * node)1129 Type Typer::Visitor::TypeJSToNumber(Node* node) {
1130 return TypeUnaryOp(node, ToNumber);
1131 }
1132
TypeJSToNumberConvertBigInt(Node * node)1133 Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
1134 return TypeUnaryOp(node, ToNumberConvertBigInt);
1135 }
1136
TypeJSToNumeric(Node * node)1137 Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1138 return TypeUnaryOp(node, ToNumeric);
1139 }
1140
TypeJSToObject(Node * node)1141 Type Typer::Visitor::TypeJSToObject(Node* node) {
1142 return TypeUnaryOp(node, ToObject);
1143 }
1144
TypeJSToString(Node * node)1145 Type Typer::Visitor::TypeJSToString(Node* node) {
1146 return TypeUnaryOp(node, ToString);
1147 }
1148
1149 // JS object operators.
1150
TypeJSCreate(Node * node)1151 Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1152
TypeJSCreateArguments(Node * node)1153 Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1154 switch (CreateArgumentsTypeOf(node->op())) {
1155 case CreateArgumentsType::kRestParameter:
1156 return Type::Array();
1157 case CreateArgumentsType::kMappedArguments:
1158 case CreateArgumentsType::kUnmappedArguments:
1159 return Type::OtherObject();
1160 }
1161 UNREACHABLE();
1162 }
1163
TypeJSCreateArray(Node * node)1164 Type Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1165
TypeJSCreateArrayIterator(Node * node)1166 Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1167 return Type::OtherObject();
1168 }
1169
TypeJSCreateCollectionIterator(Node * node)1170 Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1171 return Type::OtherObject();
1172 }
1173
TypeJSCreateBoundFunction(Node * node)1174 Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1175 return Type::BoundFunction();
1176 }
1177
TypeJSCreateGeneratorObject(Node * node)1178 Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1179 return Type::OtherObject();
1180 }
1181
TypeJSCreateClosure(Node * node)1182 Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1183 return Type::Function();
1184 }
1185
TypeJSCreateIterResultObject(Node * node)1186 Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1187 return Type::OtherObject();
1188 }
1189
TypeJSCreateStringIterator(Node * node)1190 Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1191 return Type::OtherObject();
1192 }
1193
TypeJSCreateKeyValueArray(Node * node)1194 Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1195 return Type::OtherObject();
1196 }
1197
TypeJSCreateObject(Node * node)1198 Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1199 return Type::OtherObject();
1200 }
1201
TypeJSCreatePromise(Node * node)1202 Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1203 return Type::OtherObject();
1204 }
1205
TypeJSCreateTypedArray(Node * node)1206 Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1207 return Type::OtherObject();
1208 }
1209
TypeJSCreateLiteralArray(Node * node)1210 Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1211 return Type::Array();
1212 }
1213
TypeJSCreateEmptyLiteralArray(Node * node)1214 Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1215 return Type::Array();
1216 }
1217
TypeJSCreateLiteralObject(Node * node)1218 Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1219 return Type::OtherObject();
1220 }
1221
TypeJSCreateEmptyLiteralObject(Node * node)1222 Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1223 return Type::OtherObject();
1224 }
1225
TypeJSCloneObject(Node * node)1226 Type Typer::Visitor::TypeJSCloneObject(Node* node) {
1227 return Type::OtherObject();
1228 }
1229
TypeJSCreateLiteralRegExp(Node * node)1230 Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1231 return Type::OtherObject();
1232 }
1233
TypeJSLoadProperty(Node * node)1234 Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
1235 return Type::NonInternal();
1236 }
1237
TypeJSLoadNamed(Node * node)1238 Type Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::NonInternal(); }
1239
TypeJSLoadGlobal(Node * node)1240 Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1241 return Type::NonInternal();
1242 }
1243
TypeJSParseInt(Node * node)1244 Type Typer::Visitor::TypeJSParseInt(Node* node) { return Type::Number(); }
1245
TypeJSRegExpTest(Node * node)1246 Type Typer::Visitor::TypeJSRegExpTest(Node* node) { return Type::Boolean(); }
1247
1248 // Returns a somewhat larger range if we previously assigned
1249 // a (smaller) range to this node. This is used to speed up
1250 // the fixpoint calculation in case there appears to be a loop
1251 // in the graph. In the current implementation, we are
1252 // increasing the limits to the closest power of two.
Weaken(Node * node,Type current_type,Type previous_type)1253 Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) {
1254 static const double kWeakenMinLimits[] = {
1255 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1256 -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1257 -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1258 -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1259 -70368744177664.0, -140737488355328.0, -281474976710656.0,
1260 -562949953421312.0};
1261 static const double kWeakenMaxLimits[] = {
1262 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1263 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1264 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1265 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1266 70368744177663.0, 140737488355327.0, 281474976710655.0,
1267 562949953421311.0};
1268 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1269
1270 // If the types have nothing to do with integers, return the types.
1271 Type const integer = typer_->cache_.kInteger;
1272 if (!previous_type.Maybe(integer)) {
1273 return current_type;
1274 }
1275 DCHECK(current_type.Maybe(integer));
1276
1277 Type current_integer = Type::Intersect(current_type, integer, zone());
1278 Type previous_integer = Type::Intersect(previous_type, integer, zone());
1279
1280 // Once we start weakening a node, we should always weaken.
1281 if (!IsWeakened(node->id())) {
1282 // Only weaken if there is range involved; we should converge quickly
1283 // for all other types (the exception is a union of many constants,
1284 // but we currently do not increase the number of constants in unions).
1285 Type previous = previous_integer.GetRange();
1286 Type current = current_integer.GetRange();
1287 if (current.IsInvalid() || previous.IsInvalid()) {
1288 return current_type;
1289 }
1290 // Range is involved => we are weakening.
1291 SetWeakened(node->id());
1292 }
1293
1294 double current_min = current_integer.Min();
1295 double new_min = current_min;
1296 // Find the closest lower entry in the list of allowed
1297 // minima (or negative infinity if there is no such entry).
1298 if (current_min != previous_integer.Min()) {
1299 new_min = -V8_INFINITY;
1300 for (double const min : kWeakenMinLimits) {
1301 if (min <= current_min) {
1302 new_min = min;
1303 break;
1304 }
1305 }
1306 }
1307
1308 double current_max = current_integer.Max();
1309 double new_max = current_max;
1310 // Find the closest greater entry in the list of allowed
1311 // maxima (or infinity if there is no such entry).
1312 if (current_max != previous_integer.Max()) {
1313 new_max = V8_INFINITY;
1314 for (double const max : kWeakenMaxLimits) {
1315 if (max >= current_max) {
1316 new_max = max;
1317 break;
1318 }
1319 }
1320 }
1321
1322 return Type::Union(current_type,
1323 Type::Range(new_min, new_max, typer_->zone()),
1324 typer_->zone());
1325 }
1326
TypeJSStoreProperty(Node * node)1327 Type Typer::Visitor::TypeJSStoreProperty(Node* node) { UNREACHABLE(); }
1328
TypeJSStoreNamed(Node * node)1329 Type Typer::Visitor::TypeJSStoreNamed(Node* node) { UNREACHABLE(); }
1330
TypeJSStoreGlobal(Node * node)1331 Type Typer::Visitor::TypeJSStoreGlobal(Node* node) { UNREACHABLE(); }
1332
TypeJSStoreNamedOwn(Node * node)1333 Type Typer::Visitor::TypeJSStoreNamedOwn(Node* node) { UNREACHABLE(); }
1334
TypeJSStoreDataPropertyInLiteral(Node * node)1335 Type Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1336 UNREACHABLE();
1337 }
1338
TypeJSStoreInArrayLiteral(Node * node)1339 Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
1340
TypeJSDeleteProperty(Node * node)1341 Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1342 return Type::Boolean();
1343 }
1344
TypeJSHasProperty(Node * node)1345 Type Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1346
1347 // JS instanceof operator.
1348
JSHasInPrototypeChainTyper(Type lhs,Type rhs,Typer * t)1349 Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1350 return Type::Boolean();
1351 }
1352
JSInstanceOfTyper(Type lhs,Type rhs,Typer * t)1353 Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1354 return Type::Boolean();
1355 }
1356
JSOrdinaryHasInstanceTyper(Type lhs,Type rhs,Typer * t)1357 Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1358 return Type::Boolean();
1359 }
1360
TypeJSGetSuperConstructor(Node * node)1361 Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1362 return Type::Callable();
1363 }
1364
1365 // JS context operators.
1366
TypeJSLoadContext(Node * node)1367 Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1368 ContextAccess const& access = ContextAccessOf(node->op());
1369 switch (access.index()) {
1370 case Context::PREVIOUS_INDEX:
1371 case Context::NATIVE_CONTEXT_INDEX:
1372 case Context::SCOPE_INFO_INDEX:
1373 return Type::OtherInternal();
1374 default:
1375 return Type::Any();
1376 }
1377 }
1378
TypeJSStoreContext(Node * node)1379 Type Typer::Visitor::TypeJSStoreContext(Node* node) { UNREACHABLE(); }
1380
TypeJSCreateFunctionContext(Node * node)1381 Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1382 return Type::OtherInternal();
1383 }
1384
TypeJSCreateCatchContext(Node * node)1385 Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1386 return Type::OtherInternal();
1387 }
1388
TypeJSCreateWithContext(Node * node)1389 Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1390 return Type::OtherInternal();
1391 }
1392
TypeJSCreateBlockContext(Node * node)1393 Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1394 return Type::OtherInternal();
1395 }
1396
1397 // JS other operators.
1398
TypeJSConstructForwardVarargs(Node * node)1399 Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1400 return Type::Receiver();
1401 }
1402
TypeJSConstruct(Node * node)1403 Type Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1404
TypeJSConstructWithArrayLike(Node * node)1405 Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1406 return Type::Receiver();
1407 }
1408
TypeJSConstructWithSpread(Node * node)1409 Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1410 return Type::Receiver();
1411 }
1412
TypeJSObjectIsArray(Node * node)1413 Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
1414
TypeDateNow(Node * node)1415 Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
1416
JSCallTyper(Type fun,Typer * t)1417 Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1418 if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1419 return Type::NonInternal();
1420 }
1421 JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1422 if (!function.shared().HasBuiltinFunctionId()) {
1423 return Type::NonInternal();
1424 }
1425 switch (function.shared().builtin_function_id()) {
1426 case BuiltinFunctionId::kMathRandom:
1427 return Type::PlainNumber();
1428 case BuiltinFunctionId::kMathFloor:
1429 case BuiltinFunctionId::kMathCeil:
1430 case BuiltinFunctionId::kMathRound:
1431 case BuiltinFunctionId::kMathTrunc:
1432 return t->cache_.kIntegerOrMinusZeroOrNaN;
1433 // Unary math functions.
1434 case BuiltinFunctionId::kMathAbs:
1435 case BuiltinFunctionId::kMathExp:
1436 case BuiltinFunctionId::kMathExpm1:
1437 return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1438 case BuiltinFunctionId::kMathAcos:
1439 case BuiltinFunctionId::kMathAcosh:
1440 case BuiltinFunctionId::kMathAsin:
1441 case BuiltinFunctionId::kMathAsinh:
1442 case BuiltinFunctionId::kMathAtan:
1443 case BuiltinFunctionId::kMathAtanh:
1444 case BuiltinFunctionId::kMathCbrt:
1445 case BuiltinFunctionId::kMathCos:
1446 case BuiltinFunctionId::kMathFround:
1447 case BuiltinFunctionId::kMathLog:
1448 case BuiltinFunctionId::kMathLog1p:
1449 case BuiltinFunctionId::kMathLog10:
1450 case BuiltinFunctionId::kMathLog2:
1451 case BuiltinFunctionId::kMathSin:
1452 case BuiltinFunctionId::kMathSqrt:
1453 case BuiltinFunctionId::kMathTan:
1454 return Type::Number();
1455 case BuiltinFunctionId::kMathSign:
1456 return t->cache_.kMinusOneToOneOrMinusZeroOrNaN;
1457 // Binary math functions.
1458 case BuiltinFunctionId::kMathAtan2:
1459 case BuiltinFunctionId::kMathPow:
1460 case BuiltinFunctionId::kMathMax:
1461 case BuiltinFunctionId::kMathMin:
1462 return Type::Number();
1463 case BuiltinFunctionId::kMathImul:
1464 return Type::Signed32();
1465 case BuiltinFunctionId::kMathClz32:
1466 return t->cache_.kZeroToThirtyTwo;
1467 // Date functions.
1468 case BuiltinFunctionId::kDateNow:
1469 return t->cache_.kTimeValueType;
1470 case BuiltinFunctionId::kDateGetDate:
1471 return t->cache_.kJSDateDayType;
1472 case BuiltinFunctionId::kDateGetDay:
1473 return t->cache_.kJSDateWeekdayType;
1474 case BuiltinFunctionId::kDateGetFullYear:
1475 return t->cache_.kJSDateYearType;
1476 case BuiltinFunctionId::kDateGetHours:
1477 return t->cache_.kJSDateHourType;
1478 case BuiltinFunctionId::kDateGetMilliseconds:
1479 return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1480 t->zone());
1481 case BuiltinFunctionId::kDateGetMinutes:
1482 return t->cache_.kJSDateMinuteType;
1483 case BuiltinFunctionId::kDateGetMonth:
1484 return t->cache_.kJSDateMonthType;
1485 case BuiltinFunctionId::kDateGetSeconds:
1486 return t->cache_.kJSDateSecondType;
1487 case BuiltinFunctionId::kDateGetTime:
1488 return t->cache_.kJSDateValueType;
1489
1490 // Symbol functions.
1491 case BuiltinFunctionId::kSymbolConstructor:
1492 return Type::Symbol();
1493
1494 // BigInt functions.
1495 case BuiltinFunctionId::kBigIntConstructor:
1496 return Type::BigInt();
1497
1498 // Number functions.
1499 case BuiltinFunctionId::kNumberConstructor:
1500 return Type::Number();
1501 case BuiltinFunctionId::kNumberIsFinite:
1502 case BuiltinFunctionId::kNumberIsInteger:
1503 case BuiltinFunctionId::kNumberIsNaN:
1504 case BuiltinFunctionId::kNumberIsSafeInteger:
1505 return Type::Boolean();
1506 case BuiltinFunctionId::kNumberParseFloat:
1507 return Type::Number();
1508 case BuiltinFunctionId::kNumberParseInt:
1509 return t->cache_.kIntegerOrMinusZeroOrNaN;
1510 case BuiltinFunctionId::kNumberToString:
1511 return Type::String();
1512
1513 // String functions.
1514 case BuiltinFunctionId::kStringConstructor:
1515 return Type::String();
1516 case BuiltinFunctionId::kStringCharCodeAt:
1517 return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1518 t->zone());
1519 case BuiltinFunctionId::kStringCharAt:
1520 return Type::String();
1521 case BuiltinFunctionId::kStringCodePointAt:
1522 return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1523 Type::Undefined(), t->zone());
1524 case BuiltinFunctionId::kStringConcat:
1525 case BuiltinFunctionId::kStringFromCharCode:
1526 case BuiltinFunctionId::kStringFromCodePoint:
1527 return Type::String();
1528 case BuiltinFunctionId::kStringIndexOf:
1529 case BuiltinFunctionId::kStringLastIndexOf:
1530 return Type::Range(-1.0, String::kMaxLength, t->zone());
1531 case BuiltinFunctionId::kStringEndsWith:
1532 case BuiltinFunctionId::kStringIncludes:
1533 return Type::Boolean();
1534 case BuiltinFunctionId::kStringRaw:
1535 case BuiltinFunctionId::kStringRepeat:
1536 case BuiltinFunctionId::kStringSlice:
1537 return Type::String();
1538 case BuiltinFunctionId::kStringStartsWith:
1539 return Type::Boolean();
1540 case BuiltinFunctionId::kStringSubstr:
1541 case BuiltinFunctionId::kStringSubstring:
1542 case BuiltinFunctionId::kStringToLowerCase:
1543 case BuiltinFunctionId::kStringToString:
1544 case BuiltinFunctionId::kStringToUpperCase:
1545 case BuiltinFunctionId::kStringTrim:
1546 case BuiltinFunctionId::kStringTrimEnd:
1547 case BuiltinFunctionId::kStringTrimStart:
1548 case BuiltinFunctionId::kStringValueOf:
1549 return Type::String();
1550
1551 case BuiltinFunctionId::kStringIterator:
1552 case BuiltinFunctionId::kStringIteratorNext:
1553 return Type::OtherObject();
1554
1555 case BuiltinFunctionId::kArrayEntries:
1556 case BuiltinFunctionId::kArrayKeys:
1557 case BuiltinFunctionId::kArrayValues:
1558 case BuiltinFunctionId::kTypedArrayEntries:
1559 case BuiltinFunctionId::kTypedArrayKeys:
1560 case BuiltinFunctionId::kTypedArrayValues:
1561 case BuiltinFunctionId::kArrayIteratorNext:
1562 case BuiltinFunctionId::kMapIteratorNext:
1563 case BuiltinFunctionId::kSetIteratorNext:
1564 return Type::OtherObject();
1565 case BuiltinFunctionId::kTypedArrayToStringTag:
1566 return Type::Union(Type::InternalizedString(), Type::Undefined(),
1567 t->zone());
1568
1569 // Array functions.
1570 case BuiltinFunctionId::kArrayIsArray:
1571 return Type::Boolean();
1572 case BuiltinFunctionId::kArrayConcat:
1573 return Type::Receiver();
1574 case BuiltinFunctionId::kArrayEvery:
1575 return Type::Boolean();
1576 case BuiltinFunctionId::kArrayFill:
1577 case BuiltinFunctionId::kArrayFilter:
1578 return Type::Receiver();
1579 case BuiltinFunctionId::kArrayFindIndex:
1580 return Type::Range(-1, kMaxSafeInteger, t->zone());
1581 case BuiltinFunctionId::kArrayForEach:
1582 return Type::Undefined();
1583 case BuiltinFunctionId::kArrayIncludes:
1584 return Type::Boolean();
1585 case BuiltinFunctionId::kArrayIndexOf:
1586 return Type::Range(-1, kMaxSafeInteger, t->zone());
1587 case BuiltinFunctionId::kArrayJoin:
1588 return Type::String();
1589 case BuiltinFunctionId::kArrayLastIndexOf:
1590 return Type::Range(-1, kMaxSafeInteger, t->zone());
1591 case BuiltinFunctionId::kArrayMap:
1592 return Type::Receiver();
1593 case BuiltinFunctionId::kArrayPush:
1594 return t->cache_.kPositiveSafeInteger;
1595 case BuiltinFunctionId::kArrayReverse:
1596 case BuiltinFunctionId::kArraySlice:
1597 return Type::Receiver();
1598 case BuiltinFunctionId::kArraySome:
1599 return Type::Boolean();
1600 case BuiltinFunctionId::kArraySplice:
1601 return Type::Receiver();
1602 case BuiltinFunctionId::kArrayUnshift:
1603 return t->cache_.kPositiveSafeInteger;
1604
1605 // ArrayBuffer functions.
1606 case BuiltinFunctionId::kArrayBufferIsView:
1607 return Type::Boolean();
1608
1609 // Object functions.
1610 case BuiltinFunctionId::kObjectAssign:
1611 return Type::Receiver();
1612 case BuiltinFunctionId::kObjectCreate:
1613 return Type::OtherObject();
1614 case BuiltinFunctionId::kObjectIs:
1615 case BuiltinFunctionId::kObjectHasOwnProperty:
1616 case BuiltinFunctionId::kObjectIsPrototypeOf:
1617 return Type::Boolean();
1618 case BuiltinFunctionId::kObjectToString:
1619 return Type::String();
1620
1621 // RegExp functions.
1622 case BuiltinFunctionId::kRegExpCompile:
1623 return Type::OtherObject();
1624 case BuiltinFunctionId::kRegExpExec:
1625 return Type::Union(Type::Array(), Type::Null(), t->zone());
1626 case BuiltinFunctionId::kRegExpTest:
1627 return Type::Boolean();
1628 case BuiltinFunctionId::kRegExpToString:
1629 return Type::String();
1630
1631 // Function functions.
1632 case BuiltinFunctionId::kFunctionBind:
1633 return Type::BoundFunction();
1634 case BuiltinFunctionId::kFunctionHasInstance:
1635 return Type::Boolean();
1636
1637 // Global functions.
1638 case BuiltinFunctionId::kGlobalDecodeURI:
1639 case BuiltinFunctionId::kGlobalDecodeURIComponent:
1640 case BuiltinFunctionId::kGlobalEncodeURI:
1641 case BuiltinFunctionId::kGlobalEncodeURIComponent:
1642 case BuiltinFunctionId::kGlobalEscape:
1643 case BuiltinFunctionId::kGlobalUnescape:
1644 return Type::String();
1645 case BuiltinFunctionId::kGlobalIsFinite:
1646 case BuiltinFunctionId::kGlobalIsNaN:
1647 return Type::Boolean();
1648
1649 // Map functions.
1650 case BuiltinFunctionId::kMapClear:
1651 case BuiltinFunctionId::kMapForEach:
1652 return Type::Undefined();
1653 case BuiltinFunctionId::kMapDelete:
1654 case BuiltinFunctionId::kMapHas:
1655 return Type::Boolean();
1656 case BuiltinFunctionId::kMapEntries:
1657 case BuiltinFunctionId::kMapKeys:
1658 case BuiltinFunctionId::kMapSet:
1659 case BuiltinFunctionId::kMapValues:
1660 return Type::OtherObject();
1661
1662 // Set functions.
1663 case BuiltinFunctionId::kSetAdd:
1664 case BuiltinFunctionId::kSetEntries:
1665 case BuiltinFunctionId::kSetValues:
1666 return Type::OtherObject();
1667 case BuiltinFunctionId::kSetClear:
1668 case BuiltinFunctionId::kSetForEach:
1669 return Type::Undefined();
1670 case BuiltinFunctionId::kSetDelete:
1671 case BuiltinFunctionId::kSetHas:
1672 return Type::Boolean();
1673
1674 // WeakMap functions.
1675 case BuiltinFunctionId::kWeakMapDelete:
1676 case BuiltinFunctionId::kWeakMapHas:
1677 return Type::Boolean();
1678 case BuiltinFunctionId::kWeakMapSet:
1679 return Type::OtherObject();
1680
1681 // WeakSet functions.
1682 case BuiltinFunctionId::kWeakSetAdd:
1683 return Type::OtherObject();
1684 case BuiltinFunctionId::kWeakSetDelete:
1685 case BuiltinFunctionId::kWeakSetHas:
1686 return Type::Boolean();
1687 default:
1688 return Type::NonInternal();
1689 }
1690 }
1691
TypeJSCallForwardVarargs(Node * node)1692 Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1693 return TypeUnaryOp(node, JSCallTyper);
1694 }
1695
TypeJSCall(Node * node)1696 Type Typer::Visitor::TypeJSCall(Node* node) {
1697 // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1698 // argument types for the JSCallTyper above.
1699 return TypeUnaryOp(node, JSCallTyper);
1700 }
1701
TypeJSCallWithArrayLike(Node * node)1702 Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1703 return TypeUnaryOp(node, JSCallTyper);
1704 }
1705
TypeJSCallWithSpread(Node * node)1706 Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1707 return TypeUnaryOp(node, JSCallTyper);
1708 }
1709
TypeJSCallRuntime(Node * node)1710 Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1711 switch (CallRuntimeParametersOf(node->op()).id()) {
1712 case Runtime::kInlineIsJSReceiver:
1713 return TypeUnaryOp(node, ObjectIsReceiver);
1714 case Runtime::kInlineIsSmi:
1715 return TypeUnaryOp(node, ObjectIsSmi);
1716 case Runtime::kInlineIsArray:
1717 case Runtime::kInlineIsDate:
1718 case Runtime::kInlineIsTypedArray:
1719 case Runtime::kInlineIsRegExp:
1720 return Type::Boolean();
1721 case Runtime::kInlineCreateIterResultObject:
1722 return Type::OtherObject();
1723 case Runtime::kInlineStringCharFromCode:
1724 return Type::String();
1725 case Runtime::kInlineToInteger:
1726 return TypeUnaryOp(node, ToInteger);
1727 case Runtime::kInlineToLength:
1728 return TypeUnaryOp(node, ToLength);
1729 case Runtime::kInlineToNumber:
1730 return TypeUnaryOp(node, ToNumber);
1731 case Runtime::kInlineToObject:
1732 return TypeUnaryOp(node, ToObject);
1733 case Runtime::kInlineToString:
1734 return TypeUnaryOp(node, ToString);
1735 case Runtime::kHasInPrototypeChain:
1736 return Type::Boolean();
1737 default:
1738 break;
1739 }
1740 // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1741 // have a few weird runtime calls that return the hole or even FixedArrays;
1742 // change this once those weird runtime calls have been removed.
1743 return Type::Any();
1744 }
1745
TypeJSForInEnumerate(Node * node)1746 Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1747 return Type::OtherInternal();
1748 }
1749
TypeJSForInNext(Node * node)1750 Type Typer::Visitor::TypeJSForInNext(Node* node) {
1751 return Type::Union(Type::String(), Type::Undefined(), zone());
1752 }
1753
TypeJSForInPrepare(Node * node)1754 Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1755 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1756 Type const cache_type =
1757 Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1758 Type const cache_array = Type::OtherInternal();
1759 Type const cache_length = typer_->cache_.kFixedArrayLengthType;
1760 return Type::Tuple(cache_type, cache_array, cache_length, zone());
1761 }
1762
TypeJSLoadMessage(Node * node)1763 Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1764
TypeJSStoreMessage(Node * node)1765 Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1766
TypeJSLoadModule(Node * node)1767 Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1768
TypeJSStoreModule(Node * node)1769 Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1770
TypeJSGeneratorStore(Node * node)1771 Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1772
TypeJSGeneratorRestoreContinuation(Node * node)1773 Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1774 return Type::SignedSmall();
1775 }
1776
TypeJSGeneratorRestoreContext(Node * node)1777 Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1778 return Type::Any();
1779 }
1780
TypeJSGeneratorRestoreRegister(Node * node)1781 Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1782 return Type::Any();
1783 }
1784
TypeJSGeneratorRestoreInputOrDebugPos(Node * node)1785 Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1786 return Type::Any();
1787 }
1788
TypeJSStackCheck(Node * node)1789 Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1790
TypeJSDebugger(Node * node)1791 Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1792
TypeJSFulfillPromise(Node * node)1793 Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1794 return Type::Undefined();
1795 }
1796
TypeJSPerformPromiseThen(Node * node)1797 Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1798 return Type::Receiver();
1799 }
1800
TypeJSPromiseResolve(Node * node)1801 Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1802 return Type::Receiver();
1803 }
1804
TypeJSRejectPromise(Node * node)1805 Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1806 return Type::Undefined();
1807 }
1808
TypeJSResolvePromise(Node * node)1809 Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1810 return Type::Undefined();
1811 }
1812
1813 // Simplified operators.
1814
TypeBooleanNot(Node * node)1815 Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1816
1817 // static
NumberEqualTyper(Type lhs,Type rhs,Typer * t)1818 Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1819 return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1820 }
1821
1822 // static
NumberLessThanTyper(Type lhs,Type rhs,Typer * t)1823 Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1824 return FalsifyUndefined(
1825 NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1826 }
1827
1828 // static
NumberLessThanOrEqualTyper(Type lhs,Type rhs,Typer * t)1829 Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1830 return FalsifyUndefined(
1831 Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1832 }
1833
TypeNumberEqual(Node * node)1834 Type Typer::Visitor::TypeNumberEqual(Node* node) {
1835 return TypeBinaryOp(node, NumberEqualTyper);
1836 }
1837
TypeNumberLessThan(Node * node)1838 Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1839 return TypeBinaryOp(node, NumberLessThanTyper);
1840 }
1841
TypeNumberLessThanOrEqual(Node * node)1842 Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1843 return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1844 }
1845
TypeSpeculativeNumberEqual(Node * node)1846 Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1847 return TypeBinaryOp(node, NumberEqualTyper);
1848 }
1849
TypeSpeculativeNumberLessThan(Node * node)1850 Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1851 return TypeBinaryOp(node, NumberLessThanTyper);
1852 }
1853
TypeSpeculativeNumberLessThanOrEqual(Node * node)1854 Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1855 return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1856 }
1857
TypeStringToNumber(Node * node)1858 Type Typer::Visitor::TypeStringToNumber(Node* node) {
1859 return TypeUnaryOp(node, ToNumber);
1860 }
1861
TypePlainPrimitiveToNumber(Node * node)1862 Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1863 return TypeUnaryOp(node, ToNumber);
1864 }
1865
TypePlainPrimitiveToWord32(Node * node)1866 Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1867 return Type::Integral32();
1868 }
1869
TypePlainPrimitiveToFloat64(Node * node)1870 Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1871 return Type::Number();
1872 }
1873
1874 // static
ReferenceEqualTyper(Type lhs,Type rhs,Typer * t)1875 Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1876 if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1877 return t->singleton_true_;
1878 }
1879 return Type::Boolean();
1880 }
1881
TypeReferenceEqual(Node * node)1882 Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1883 return TypeBinaryOp(node, ReferenceEqualTyper);
1884 }
1885
1886 // static
SameValueTyper(Type lhs,Type rhs,Typer * t)1887 Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1888 return t->operation_typer()->SameValue(lhs, rhs);
1889 }
1890
TypeSameValue(Node * node)1891 Type Typer::Visitor::TypeSameValue(Node* node) {
1892 return TypeBinaryOp(node, SameValueTyper);
1893 }
1894
TypeStringEqual(Node * node)1895 Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1896
TypeStringLessThan(Node * node)1897 Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1898
TypeStringLessThanOrEqual(Node * node)1899 Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1900 return Type::Boolean();
1901 }
1902
StringFromSingleCharCodeTyper(Type type,Typer * t)1903 Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
1904 return Type::String();
1905 }
1906
StringFromSingleCodePointTyper(Type type,Typer * t)1907 Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
1908 return Type::String();
1909 }
1910
TypeStringToLowerCaseIntl(Node * node)1911 Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
1912 return Type::String();
1913 }
1914
TypeStringToUpperCaseIntl(Node * node)1915 Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
1916 return Type::String();
1917 }
1918
TypeStringCharCodeAt(Node * node)1919 Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
1920 return typer_->cache_.kUint16;
1921 }
1922
TypeStringCodePointAt(Node * node)1923 Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
1924 return Type::Range(0.0, String::kMaxCodePoint, zone());
1925 }
1926
TypeStringFromSingleCharCode(Node * node)1927 Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
1928 return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
1929 }
1930
TypeStringFromSingleCodePoint(Node * node)1931 Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
1932 return TypeUnaryOp(node, StringFromSingleCodePointTyper);
1933 }
1934
TypeStringIndexOf(Node * node)1935 Type Typer::Visitor::TypeStringIndexOf(Node* node) {
1936 return Type::Range(-1.0, String::kMaxLength, zone());
1937 }
1938
TypeStringLength(Node * node)1939 Type Typer::Visitor::TypeStringLength(Node* node) {
1940 return typer_->cache_.kStringLengthType;
1941 }
1942
TypeStringSubstring(Node * node)1943 Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
1944
TypePoisonIndex(Node * node)1945 Type Typer::Visitor::TypePoisonIndex(Node* node) {
1946 return Type::Union(Operand(node, 0), typer_->cache_.kSingletonZero, zone());
1947 }
1948
TypeCheckBounds(Node * node)1949 Type Typer::Visitor::TypeCheckBounds(Node* node) {
1950 Type index = Operand(node, 0);
1951 Type length = Operand(node, 1);
1952 DCHECK(length.Is(Type::Unsigned31()));
1953 if (index.Maybe(Type::MinusZero())) {
1954 index = Type::Union(index, typer_->cache_.kSingletonZero, zone());
1955 }
1956 index = Type::Intersect(index, Type::Integral32(), zone());
1957 if (index.IsNone() || length.IsNone()) return Type::None();
1958 double min = std::max(index.Min(), 0.0);
1959 double max = std::min(index.Max(), length.Max() - 1);
1960 if (max < min) return Type::None();
1961 return Type::Range(min, max, zone());
1962 }
1963
TypeCheckHeapObject(Node * node)1964 Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
1965 Type type = Operand(node, 0);
1966 return type;
1967 }
1968
TypeCheckIf(Node * node)1969 Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
1970
TypeCheckInternalizedString(Node * node)1971 Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
1972 Type arg = Operand(node, 0);
1973 return Type::Intersect(arg, Type::InternalizedString(), zone());
1974 }
1975
TypeCheckMaps(Node * node)1976 Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
1977
TypeCompareMaps(Node * node)1978 Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
1979
TypeCheckNumber(Node * node)1980 Type Typer::Visitor::TypeCheckNumber(Node* node) {
1981 return typer_->operation_typer_.CheckNumber(Operand(node, 0));
1982 }
1983
TypeCheckReceiver(Node * node)1984 Type Typer::Visitor::TypeCheckReceiver(Node* node) {
1985 Type arg = Operand(node, 0);
1986 return Type::Intersect(arg, Type::Receiver(), zone());
1987 }
1988
TypeCheckSmi(Node * node)1989 Type Typer::Visitor::TypeCheckSmi(Node* node) {
1990 Type arg = Operand(node, 0);
1991 return Type::Intersect(arg, Type::SignedSmall(), zone());
1992 }
1993
TypeCheckString(Node * node)1994 Type Typer::Visitor::TypeCheckString(Node* node) {
1995 Type arg = Operand(node, 0);
1996 return Type::Intersect(arg, Type::String(), zone());
1997 }
1998
TypeCheckSymbol(Node * node)1999 Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2000 Type arg = Operand(node, 0);
2001 return Type::Intersect(arg, Type::Symbol(), zone());
2002 }
2003
TypeCheckFloat64Hole(Node * node)2004 Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2005 return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2006 }
2007
TypeCheckNotTaggedHole(Node * node)2008 Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2009 Type type = Operand(node, 0);
2010 type = Type::Intersect(type, Type::NonInternal(), zone());
2011 return type;
2012 }
2013
TypeConvertReceiver(Node * node)2014 Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2015 Type arg = Operand(node, 0);
2016 return typer_->operation_typer_.ConvertReceiver(arg);
2017 }
2018
TypeConvertTaggedHoleToUndefined(Node * node)2019 Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2020 Type type = Operand(node, 0);
2021 return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2022 }
2023
TypeCheckEqualsInternalizedString(Node * node)2024 Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2025 UNREACHABLE();
2026 }
2027
TypeCheckEqualsSymbol(Node * node)2028 Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2029
TypeAllocate(Node * node)2030 Type Typer::Visitor::TypeAllocate(Node* node) {
2031 return AllocateTypeOf(node->op());
2032 }
2033
TypeAllocateRaw(Node * node)2034 Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2035
TypeLoadFieldByIndex(Node * node)2036 Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2037 return Type::NonInternal();
2038 }
2039
TypeLoadField(Node * node)2040 Type Typer::Visitor::TypeLoadField(Node* node) {
2041 return FieldAccessOf(node->op()).type;
2042 }
2043
TypeLoadElement(Node * node)2044 Type Typer::Visitor::TypeLoadElement(Node* node) {
2045 return ElementAccessOf(node->op()).type;
2046 }
2047
TypeLoadTypedElement(Node * node)2048 Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2049 switch (ExternalArrayTypeOf(node->op())) {
2050 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2051 case kExternal##ElemType##Array: \
2052 return typer_->cache_.k##ElemType;
2053 TYPED_ARRAYS(TYPED_ARRAY_CASE)
2054 #undef TYPED_ARRAY_CASE
2055 }
2056 UNREACHABLE();
2057 }
2058
TypeLoadDataViewElement(Node * node)2059 Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2060 switch (ExternalArrayTypeOf(node->op())) {
2061 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2062 case kExternal##ElemType##Array: \
2063 return typer_->cache_.k##ElemType;
2064 TYPED_ARRAYS(TYPED_ARRAY_CASE)
2065 #undef TYPED_ARRAY_CASE
2066 }
2067 UNREACHABLE();
2068 }
2069
TypeStoreField(Node * node)2070 Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2071
TypeStoreElement(Node * node)2072 Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2073
TypeTransitionAndStoreElement(Node * node)2074 Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2075 UNREACHABLE();
2076 }
2077
TypeTransitionAndStoreNumberElement(Node * node)2078 Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2079 UNREACHABLE();
2080 }
2081
TypeTransitionAndStoreNonNumberElement(Node * node)2082 Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2083 UNREACHABLE();
2084 }
2085
TypeStoreSignedSmallElement(Node * node)2086 Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2087
TypeStoreTypedElement(Node * node)2088 Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2089
TypeStoreDataViewElement(Node * node)2090 Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2091
TypeObjectIsArrayBufferView(Node * node)2092 Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2093 return TypeUnaryOp(node, ObjectIsArrayBufferView);
2094 }
2095
TypeObjectIsBigInt(Node * node)2096 Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2097 return TypeUnaryOp(node, ObjectIsBigInt);
2098 }
2099
TypeObjectIsCallable(Node * node)2100 Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2101 return TypeUnaryOp(node, ObjectIsCallable);
2102 }
2103
TypeObjectIsConstructor(Node * node)2104 Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2105 return TypeUnaryOp(node, ObjectIsConstructor);
2106 }
2107
TypeObjectIsDetectableCallable(Node * node)2108 Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2109 return TypeUnaryOp(node, ObjectIsDetectableCallable);
2110 }
2111
TypeObjectIsMinusZero(Node * node)2112 Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2113 return TypeUnaryOp(node, ObjectIsMinusZero);
2114 }
2115
TypeNumberIsFloat64Hole(Node * node)2116 Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2117 return Type::Boolean();
2118 }
2119
TypeNumberIsFinite(Node * node)2120 Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2121
TypeObjectIsFiniteNumber(Node * node)2122 Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2123 return Type::Boolean();
2124 }
2125
TypeNumberIsInteger(Node * node)2126 Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2127
TypeObjectIsSafeInteger(Node * node)2128 Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2129 return Type::Boolean();
2130 }
2131
TypeNumberIsSafeInteger(Node * node)2132 Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2133
TypeObjectIsInteger(Node * node)2134 Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2135
TypeObjectIsNaN(Node * node)2136 Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2137 return TypeUnaryOp(node, ObjectIsNaN);
2138 }
2139
TypeNumberIsNaN(Node * node)2140 Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2141 return TypeUnaryOp(node, NumberIsNaN);
2142 }
2143
TypeObjectIsNonCallable(Node * node)2144 Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2145 return TypeUnaryOp(node, ObjectIsNonCallable);
2146 }
2147
TypeObjectIsNumber(Node * node)2148 Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2149 return TypeUnaryOp(node, ObjectIsNumber);
2150 }
2151
TypeObjectIsReceiver(Node * node)2152 Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2153 return TypeUnaryOp(node, ObjectIsReceiver);
2154 }
2155
TypeObjectIsSmi(Node * node)2156 Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2157 return TypeUnaryOp(node, ObjectIsSmi);
2158 }
2159
TypeObjectIsString(Node * node)2160 Type Typer::Visitor::TypeObjectIsString(Node* node) {
2161 return TypeUnaryOp(node, ObjectIsString);
2162 }
2163
TypeObjectIsSymbol(Node * node)2164 Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2165 return TypeUnaryOp(node, ObjectIsSymbol);
2166 }
2167
TypeObjectIsUndetectable(Node * node)2168 Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2169 return TypeUnaryOp(node, ObjectIsUndetectable);
2170 }
2171
TypeArgumentsLength(Node * node)2172 Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2173 return TypeCache::Get().kArgumentsLengthType;
2174 }
2175
TypeArgumentsFrame(Node * node)2176 Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2177 return Type::ExternalPointer();
2178 }
2179
TypeNewDoubleElements(Node * node)2180 Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2181 return Type::OtherInternal();
2182 }
2183
TypeNewSmiOrObjectElements(Node * node)2184 Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2185 return Type::OtherInternal();
2186 }
2187
TypeNewArgumentsElements(Node * node)2188 Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2189 return Type::OtherInternal();
2190 }
2191
TypeNewConsString(Node * node)2192 Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2193
TypeArrayBufferWasNeutered(Node * node)2194 Type Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) {
2195 return Type::Boolean();
2196 }
2197
TypeFindOrderedHashMapEntry(Node * node)2198 Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2199 return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2200 }
2201
TypeFindOrderedHashMapEntryForInt32Key(Node * node)2202 Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2203 return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2204 }
2205
TypeRuntimeAbort(Node * node)2206 Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2207
2208 // Heap constants.
2209
TypeConstant(Handle<Object> value)2210 Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2211 return Type::NewConstant(typer_->js_heap_broker(), value, zone());
2212 }
2213
2214 } // namespace compiler
2215 } // namespace internal
2216 } // namespace v8
2217