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