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