Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/compiler/typer.cc

Issue 648163002: Revert "Refine expression typing, esp. by propagating range information." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/typer.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/graph-inl.h" 5 #include "src/compiler/graph-inl.h"
6 #include "src/compiler/js-operator.h" 6 #include "src/compiler/js-operator.h"
7 #include "src/compiler/node.h" 7 #include "src/compiler/node.h"
8 #include "src/compiler/node-properties-inl.h" 8 #include "src/compiler/node-properties-inl.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 #include "src/compiler/simplified-operator.h" 10 #include "src/compiler/simplified-operator.h"
11 #include "src/compiler/typer.h" 11 #include "src/compiler/typer.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 namespace compiler { 15 namespace compiler {
16 16
17 Typer::Typer(Zone* zone) : zone_(zone) { 17 Typer::Typer(Zone* zone) : zone_(zone) {
18 Factory* f = zone->isolate()->factory(); 18 Factory* f = zone->isolate()->factory();
19 19
20 Handle<Object> zero = f->NewNumber(0);
21 Handle<Object> one = f->NewNumber(1);
22 Handle<Object> positive_infinity = f->NewNumber(+V8_INFINITY);
23 Handle<Object> negative_infinity = f->NewNumber(-V8_INFINITY);
24
25 negative_signed32 = Type::Union(
26 Type::SignedSmall(), Type::OtherSigned32(), zone);
27 non_negative_signed32 = Type::Union(
28 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone);
29 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
30 singleton_false = Type::Constant(f->false_value(), zone);
31 singleton_true = Type::Constant(f->true_value(), zone);
32 singleton_zero = Type::Range(zero, zero, zone);
33 singleton_one = Type::Range(one, one, zone);
34 zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
35 zeroish = Type::Union(
36 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
37 falsish = Type::Union(Type::Undetectable(),
38 Type::Union(zeroish, undefined_or_null, zone), zone);
39 integer = Type::Range(negative_infinity, positive_infinity, zone);
40
41 Type* number = Type::Number(); 20 Type* number = Type::Number();
42 Type* signed32 = Type::Signed32(); 21 Type* signed32 = Type::Signed32();
43 Type* unsigned32 = Type::Unsigned32(); 22 Type* unsigned32 = Type::Unsigned32();
44 Type* integral32 = Type::Integral32(); 23 Type* integral32 = Type::Integral32();
45 Type* object = Type::Object(); 24 Type* object = Type::Object();
46 Type* undefined = Type::Undefined(); 25 Type* undefined = Type::Undefined();
47 Type* weakint = Type::Union( 26 Type* weakint = Type::Union(
48 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); 27 Type::Range(f->NewNumber(-V8_INFINITY), f->NewNumber(+V8_INFINITY), zone),
28 Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
49 29
50 number_fun0_ = Type::Function(number, zone); 30 number_fun0_ = Type::Function(number, zone);
51 number_fun1_ = Type::Function(number, number, zone); 31 number_fun1_ = Type::Function(number, number, zone);
52 number_fun2_ = Type::Function(number, number, number, zone); 32 number_fun2_ = Type::Function(number, number, number, zone);
53 weakint_fun1_ = Type::Function(weakint, number, zone); 33 weakint_fun1_ = Type::Function(weakint, number, zone);
54 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); 34 imul_fun_ = Type::Function(signed32, integral32, integral32, zone);
55 random_fun_ = Type::Function(Type::Union( 35 random_fun_ = Type::Function(Type::Union(
56 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); 36 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone);
57 37
58 Type* int8 = Type::Intersect(
59 Type::Range(f->NewNumber(-0x7F), f->NewNumber(0x7F-1), zone),
60 Type::UntaggedInt8(), zone);
61 Type* int16 = Type::Intersect(
62 Type::Range(f->NewNumber(-0x7FFF), f->NewNumber(0x7FFF-1), zone),
63 Type::UntaggedInt16(), zone);
64 Type* uint8 = Type::Intersect(
65 Type::Range(zero, f->NewNumber(0xFF-1), zone),
66 Type::UntaggedInt8(), zone);
67 Type* uint16 = Type::Intersect(
68 Type::Range(zero, f->NewNumber(0xFFFF-1), zone),
69 Type::UntaggedInt16(), zone);
70 38
71 #define NATIVE_TYPE(sem, rep) \ 39 #define NATIVE_TYPE(sem, rep) \
72 Type::Intersect(Type::sem(), Type::rep(), zone) 40 Type::Intersect(Type::sem(zone), Type::rep(zone), zone)
41 // TODO(rossberg): Use range types for more precision, once we have them.
42 Type* int8 = NATIVE_TYPE(SignedSmall, UntaggedInt8);
43 Type* int16 = NATIVE_TYPE(SignedSmall, UntaggedInt16);
73 Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32); 44 Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32);
45 Type* uint8 = NATIVE_TYPE(UnsignedSmall, UntaggedInt8);
46 Type* uint16 = NATIVE_TYPE(UnsignedSmall, UntaggedInt16);
74 Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32); 47 Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32);
75 Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32); 48 Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32);
76 Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64); 49 Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64);
77 #undef NATIVE_TYPE 50 #undef NATIVE_TYPE
78
79 Type* buffer = Type::Buffer(zone); 51 Type* buffer = Type::Buffer(zone);
80 Type* int8_array = Type::Array(int8, zone); 52 Type* int8_array = Type::Array(int8, zone);
81 Type* int16_array = Type::Array(int16, zone); 53 Type* int16_array = Type::Array(int16, zone);
82 Type* int32_array = Type::Array(int32, zone); 54 Type* int32_array = Type::Array(int32, zone);
83 Type* uint8_array = Type::Array(uint8, zone); 55 Type* uint8_array = Type::Array(uint8, zone);
84 Type* uint16_array = Type::Array(uint16, zone); 56 Type* uint16_array = Type::Array(uint16, zone);
85 Type* uint32_array = Type::Array(uint32, zone); 57 Type* uint32_array = Type::Array(uint32, zone);
86 Type* float32_array = Type::Array(float32, zone); 58 Type* float32_array = Type::Array(float32, zone);
87 Type* float64_array = Type::Array(float64, zone); 59 Type* float64_array = Type::Array(float64, zone);
88 Type* arg1 = Type::Union(unsigned32, object, zone); 60 Type* arg1 = Type::Union(unsigned32, object, zone);
(...skipping 11 matching lines...) Expand all
100 } 72 }
101 73
102 74
103 class Typer::Visitor : public NullNodeVisitor { 75 class Typer::Visitor : public NullNodeVisitor {
104 public: 76 public:
105 Visitor(Typer* typer, MaybeHandle<Context> context) 77 Visitor(Typer* typer, MaybeHandle<Context> context)
106 : typer_(typer), context_(context) {} 78 : typer_(typer), context_(context) {}
107 79
108 Bounds TypeNode(Node* node) { 80 Bounds TypeNode(Node* node) {
109 switch (node->opcode()) { 81 switch (node->opcode()) {
110 #define DECLARE_CASE(x) \
111 case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
112 JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
113 #undef DECLARE_CASE
114
115 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); 82 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
116 DECLARE_CASE(Start) 83 DECLARE_CASE(Start)
117 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: 84 VALUE_OP_LIST(DECLARE_CASE)
118 COMMON_OP_LIST(DECLARE_CASE)
119 SIMPLIFIED_OP_LIST(DECLARE_CASE)
120 MACHINE_OP_LIST(DECLARE_CASE)
121 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
122 JS_OBJECT_OP_LIST(DECLARE_CASE)
123 JS_CONTEXT_OP_LIST(DECLARE_CASE)
124 JS_OTHER_OP_LIST(DECLARE_CASE)
125 #undef DECLARE_CASE 85 #undef DECLARE_CASE
126 86
127 #define DECLARE_CASE(x) case IrOpcode::k##x: 87 #define DECLARE_CASE(x) case IrOpcode::k##x:
128 DECLARE_CASE(End) 88 DECLARE_CASE(End)
129 INNER_CONTROL_OP_LIST(DECLARE_CASE) 89 INNER_CONTROL_OP_LIST(DECLARE_CASE)
130 #undef DECLARE_CASE 90 #undef DECLARE_CASE
131 break; 91 break;
132 } 92 }
133 UNREACHABLE(); 93 UNREACHABLE();
134 return Bounds(); 94 return Bounds();
135 } 95 }
136 96
137 Type* TypeConstant(Handle<Object> value); 97 Type* TypeConstant(Handle<Object> value);
138 98
139 protected: 99 protected:
140 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); 100 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
141 DECLARE_METHOD(Start) 101 DECLARE_METHOD(Start)
142 VALUE_OP_LIST(DECLARE_METHOD) 102 VALUE_OP_LIST(DECLARE_METHOD)
143 #undef DECLARE_METHOD 103 #undef DECLARE_METHOD
144 104
145 static Bounds OperandType(Node* node, int i) { 105 Bounds OperandType(Node* node, int i) {
146 return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i)); 106 return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i));
147 } 107 }
148 108
149 static Type* ContextType(Node* node) { 109 Type* ContextType(Node* node) {
150 Bounds result = 110 Bounds result =
151 NodeProperties::GetBounds(NodeProperties::GetContextInput(node)); 111 NodeProperties::GetBounds(NodeProperties::GetContextInput(node));
152 DCHECK(result.upper->Maybe(Type::Internal())); 112 DCHECK(result.upper->Maybe(Type::Internal()));
153 // TODO(rossberg): More precisely, instead of the above assertion, we should 113 // TODO(rossberg): More precisely, instead of the above assertion, we should
154 // back-propagate the constraint that it has to be a subtype of Internal. 114 // back-propagate the constraint that it has to be a subtype of Internal.
155 return result.upper; 115 return result.upper;
156 } 116 }
157 117
158 Zone* zone() { return typer_->zone(); } 118 Zone* zone() { return typer_->zone(); }
159 Isolate* isolate() { return typer_->isolate(); } 119 Isolate* isolate() { return typer_->isolate(); }
160 MaybeHandle<Context> context() { return context_; } 120 MaybeHandle<Context> context() { return context_; }
161 121
162 private: 122 private:
163 Typer* typer_; 123 Typer* typer_;
164 MaybeHandle<Context> context_; 124 MaybeHandle<Context> context_;
165
166 typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
167 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
168
169 Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
170 Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
171
172 static Type* Invert(Type*, Typer*);
173 static Type* FalsifyUndefined(Type*, Typer*);
174
175 static Type* ToPrimitive(Type*, Typer*);
176 static Type* ToBoolean(Type*, Typer*);
177 static Type* ToNumber(Type*, Typer*);
178 static Type* ToString(Type*, Typer*);
179 static Type* NumberToInt32(Type*, Typer*);
180 static Type* NumberToUint32(Type*, Typer*);
181
182 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*);
183 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*);
184 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
185 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
186
187 static Type* JSCompareTyper(Type*, Type*, Typer*);
188
189 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
190 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
191 #undef DECLARE_METHOD
192
193 static Type* JSUnaryNotTyper(Type*, Typer*);
194 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
195 static Type* JSCallFunctionTyper(Type*, Typer*);
196 }; 125 };
197 126
198 127
199 class Typer::RunVisitor : public Typer::Visitor { 128 class Typer::RunVisitor : public Typer::Visitor {
200 public: 129 public:
201 RunVisitor(Typer* typer, MaybeHandle<Context> context) 130 RunVisitor(Typer* typer, MaybeHandle<Context> context)
202 : Visitor(typer, context), 131 : Visitor(typer, context),
203 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} 132 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
204 133
205 GenericGraphVisit::Control Post(Node* node) { 134 GenericGraphVisit::Control Post(Node* node) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 Visitor typing(this, MaybeHandle<Context>()); 231 Visitor typing(this, MaybeHandle<Context>());
303 Bounds bounds = typing.TypeNode(node); 232 Bounds bounds = typing.TypeNode(node);
304 NodeProperties::SetBounds(node, bounds); 233 NodeProperties::SetBounds(node, bounds);
305 } 234 }
306 } 235 }
307 236
308 237
309 // ----------------------------------------------------------------------------- 238 // -----------------------------------------------------------------------------
310 239
311 240
312 Bounds Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
313 Bounds input = OperandType(node, 0);
314 Type* upper = input.upper->Is(Type::None())
315 ? Type::None()
316 : f(input.upper, typer_);
317 Type* lower = input.lower->Is(Type::None())
318 ? Type::None()
319 : (input.lower == input.upper || upper->IsConstant())
320 ? upper // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...?
321 : f(input.lower, typer_);
322 // TODO(neis): Figure out what to do with lower bound.
323 return Bounds(lower, upper);
324 }
325
326
327 Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
328 Bounds left = OperandType(node, 0);
329 Bounds right = OperandType(node, 1);
330 Type* upper = left.upper->Is(Type::None()) || right.upper->Is(Type::None())
331 ? Type::None()
332 : f(left.upper, right.upper, typer_);
333 Type* lower = left.lower->Is(Type::None()) || right.lower->Is(Type::None())
334 ? Type::None()
335 : ((left.lower == left.upper && right.lower == right.upper) ||
336 upper->IsConstant())
337 ? upper
338 : f(left.lower, right.lower, typer_);
339 // TODO(neis): Figure out what to do with lower bound.
340 return Bounds(lower, upper);
341 }
342
343
344 Type* Typer::Visitor::Invert(Type* type, Typer* t) {
345 if (type->Is(t->singleton_false)) return t->singleton_true;
346 if (type->Is(t->singleton_true)) return t->singleton_false;
347 return type;
348 }
349
350
351 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) {
352 if (type->Is(Type::Undefined())) return t->singleton_false;
353 return type;
354 }
355
356
357 // Type conversion.
358
359
360 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
361 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
362 return type;
363 }
364 return Type::Primitive();
365 }
366
367
368 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
369 if (type->Is(Type::Boolean())) return type;
370 if (type->Is(t->falsish)) return t->singleton_false;
371 if (type->Is(Type::DetectableReceiver())) return t->singleton_true;
372 if (type->Is(Type::OrderedNumber()) && (type->Max() < 0 || 0 < type->Min())) {
373 return t->singleton_true; // Ruled out nan, -0 and +0.
374 }
375 return Type::Boolean();
376 }
377
378
379 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
380 if (type->Is(Type::Number())) return type;
381 if (type->Is(Type::Undefined())) return Type::NaN();
382 if (type->Is(t->singleton_false)) return t->singleton_zero;
383 if (type->Is(t->singleton_true)) return t->singleton_one;
384 if (type->Is(Type::Boolean())) return t->zero_or_one;
385 return Type::Number();
386 }
387
388
389 Type* Typer::Visitor::ToString(Type* type, Typer* t) {
390 if (type->Is(Type::String())) return type;
391 return Type::String();
392 }
393
394
395 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
396 DCHECK(type->Is(Type::Number()));
397 if (type->Is(Type::Signed32())) return type;
398 if (type->Is(t->zeroish)) return t->singleton_zero;
399 return Type::Signed32();
400 }
401
402
403 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
404 DCHECK(type->Is(Type::Number()));
405 if (type->Is(Type::Unsigned32())) return type;
406 if (type->Is(t->zeroish)) return t->singleton_zero;
407 return Type::Unsigned32();
408 }
409
410
411 // -----------------------------------------------------------------------------
412
413
414 // Control operators. 241 // Control operators.
415 242
416
417 Bounds Typer::Visitor::TypeStart(Node* node) { 243 Bounds Typer::Visitor::TypeStart(Node* node) {
418 return Bounds(Type::Internal()); 244 return Bounds(Type::Internal(zone()));
419 } 245 }
420 246
421 247
422 // Common operators. 248 // Common operators.
423 249
424
425 Bounds Typer::Visitor::TypeParameter(Node* node) { 250 Bounds Typer::Visitor::TypeParameter(Node* node) {
426 return Bounds::Unbounded(zone()); 251 return Bounds::Unbounded(zone());
427 } 252 }
428 253
429 254
430 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { 255 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
431 Factory* f = zone()->isolate()->factory(); 256 // TODO(titzer): only call Type::Of() if the type is not already known.
432 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); 257 return Bounds(Type::Of(OpParameter<int32_t>(node), zone()));
433 return Bounds(Type::Intersect(
434 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone()));
435 } 258 }
436 259
437 260
438 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { 261 Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
439 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? 262 // TODO(titzer): only call Type::Of() if the type is not already known.
263 return Bounds(
264 Type::Of(static_cast<double>(OpParameter<int64_t>(node)), zone()));
440 } 265 }
441 266
442 267
443 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { 268 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) {
444 return Bounds(Type::Intersect( 269 // TODO(titzer): only call Type::Of() if the type is not already known.
445 Type::Of(OpParameter<float>(node), zone()), 270 return Bounds(Type::Of(OpParameter<float>(node), zone()));
446 Type::UntaggedFloat32(), zone()));
447 } 271 }
448 272
449 273
450 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { 274 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
451 return Bounds(Type::Intersect( 275 // TODO(titzer): only call Type::Of() if the type is not already known.
452 Type::Of(OpParameter<double>(node), zone()), 276 return Bounds(Type::Of(OpParameter<double>(node), zone()));
453 Type::UntaggedFloat64(), zone()));
454 } 277 }
455 278
456 279
457 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { 280 Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
458 Factory* f = zone()->isolate()->factory(); 281 // TODO(titzer): only call Type::Of() if the type is not already known.
459 return Bounds(Type::Constant( 282 return Bounds(Type::Of(OpParameter<double>(node), zone()));
460 f->NewNumber(OpParameter<double>(node)), zone()));
461 } 283 }
462 284
463 285
464 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { 286 Bounds Typer::Visitor::TypeHeapConstant(Node* node) {
465 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); 287 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle()));
466 } 288 }
467 289
468 290
469 Bounds Typer::Visitor::TypeExternalConstant(Node* node) { 291 Bounds Typer::Visitor::TypeExternalConstant(Node* node) {
470 return Bounds(Type::Internal()); 292 return Bounds(Type::Internal(zone()));
471 } 293 }
472 294
473 295
474 Bounds Typer::Visitor::TypePhi(Node* node) { 296 Bounds Typer::Visitor::TypePhi(Node* node) {
475 int arity = OperatorProperties::GetValueInputCount(node->op()); 297 int arity = OperatorProperties::GetValueInputCount(node->op());
476 Bounds bounds = OperandType(node, 0); 298 Bounds bounds = OperandType(node, 0);
477 for (int i = 1; i < arity; ++i) { 299 for (int i = 1; i < arity; ++i) {
478 bounds = Bounds::Either(bounds, OperandType(node, i), zone()); 300 bounds = Bounds::Either(bounds, OperandType(node, i), zone());
479 } 301 }
480 return bounds; 302 return bounds;
(...skipping 12 matching lines...) Expand all
493 } 315 }
494 316
495 317
496 Bounds Typer::Visitor::TypeFinish(Node* node) { 318 Bounds Typer::Visitor::TypeFinish(Node* node) {
497 return OperandType(node, 0); 319 return OperandType(node, 0);
498 } 320 }
499 321
500 322
501 Bounds Typer::Visitor::TypeFrameState(Node* node) { 323 Bounds Typer::Visitor::TypeFrameState(Node* node) {
502 // TODO(rossberg): Ideally FrameState wouldn't have a value output. 324 // TODO(rossberg): Ideally FrameState wouldn't have a value output.
503 return Bounds(Type::Internal()); 325 return Bounds(Type::Internal(zone()));
504 } 326 }
505 327
506 328
507 Bounds Typer::Visitor::TypeStateValues(Node* node) { 329 Bounds Typer::Visitor::TypeStateValues(Node* node) {
508 return Bounds(Type::Internal()); 330 return Bounds(Type::Internal(zone()));
509 } 331 }
510 332
511 333
512 Bounds Typer::Visitor::TypeCall(Node* node) { 334 Bounds Typer::Visitor::TypeCall(Node* node) {
513 return Bounds::Unbounded(zone()); 335 return Bounds::Unbounded(zone());
514 } 336 }
515 337
516 338
517 Bounds Typer::Visitor::TypeProjection(Node* node) { 339 Bounds Typer::Visitor::TypeProjection(Node* node) {
518 // TODO(titzer): use the output type of the input to determine the bounds. 340 // TODO(titzer): use the output type of the input to determine the bounds.
519 return Bounds::Unbounded(zone()); 341 return Bounds::Unbounded(zone());
520 } 342 }
521 343
522 344
523 // JS comparison operators. 345 // JS comparison operators.
524 346
525 347 #define DEFINE_METHOD(x) \
526 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { 348 Bounds Typer::Visitor::Type##x(Node* node) { \
527 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; 349 return Bounds(Type::Boolean(zone())); \
528 if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) {
529 return t->singleton_true;
530 } 350 }
531 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && 351 JS_COMPARE_BINOP_LIST(DEFINE_METHOD)
532 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { 352 #undef DEFINE_METHOD
533 return t->singleton_false;
534 }
535 if (lhs->IsConstant() && rhs->Is(lhs)) {
536 // Types are equal and are inhabited only by a single semantic value,
537 // which is not nan due to the earlier check.
538 // TODO(neis): Extend this to Range(x,x), MinusZero, ...?
539 return t->singleton_true;
540 }
541 return Type::Boolean();
542 }
543
544
545 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
546 return Invert(JSEqualTyper(lhs, rhs, t), t);
547 }
548
549
550 static Type* JSType(Type* type) {
551 if (type->Is(Type::Boolean())) return Type::Boolean();
552 if (type->Is(Type::String())) return Type::String();
553 if (type->Is(Type::Number())) return Type::Number();
554 if (type->Is(Type::Undefined())) return Type::Undefined();
555 if (type->Is(Type::Null())) return Type::Null();
556 if (type->Is(Type::Symbol())) return Type::Symbol();
557 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object"
558 return Type::Any();
559 }
560
561
562 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
563 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false;
564 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
565 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
566 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
567 return t->singleton_false;
568 }
569 if (lhs->IsConstant() && rhs->Is(lhs)) {
570 // Types are equal and are inhabited only by a single semantic value,
571 // which is not nan due to the earlier check.
572 return t->singleton_true;
573 }
574 return Type::Boolean();
575 }
576
577
578 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
579 return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
580 }
581
582
583 // The EcmaScript specification defines the four relational comparison operators
584 // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
585 // but returns undefined when the inputs cannot be compared.
586 // We implement the typing analogously.
587 Type* Typer::Visitor::JSCompareTyper(Type* lhs, Type* rhs, Typer* t) {
588 lhs = ToPrimitive(lhs, t);
589 rhs = ToPrimitive(rhs, t);
590 if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
591 return Type::Boolean();
592 }
593 lhs = ToNumber(lhs, t);
594 rhs = ToNumber(rhs, t);
595 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::Undefined();
596 if (lhs->IsConstant() && rhs->Is(lhs)) {
597 // Types are equal and are inhabited only by a single semantic value,
598 // which is not NaN due to the previous check.
599 return t->singleton_false;
600 }
601 if (lhs->Min() >= rhs->Max()) return t->singleton_false;
602 if (lhs->Max() < rhs->Min() &&
603 !lhs->Maybe(Type::NaN()) && !rhs->Maybe(Type::NaN())) {
604 return t->singleton_true;
605 }
606 return Type::Boolean();
607 }
608
609
610 Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
611 return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
612 }
613
614
615 Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
616 return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
617 }
618
619
620 Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
621 return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
622 }
623
624
625 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
626 Type* lhs, Type* rhs, Typer* t) {
627 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
628 }
629 353
630 354
631 // JS bitwise operators. 355 // JS bitwise operators.
632 356
633 357 Bounds Typer::Visitor::TypeJSBitwiseOr(Node* node) {
634 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 358 Bounds left = OperandType(node, 0);
635 Factory* f = t->zone()->isolate()->factory(); 359 Bounds right = OperandType(node, 1);
636 lhs = NumberToInt32(ToNumber(lhs, t), t); 360 Type* upper = Type::Union(left.upper, right.upper, zone());
637 rhs = NumberToInt32(ToNumber(rhs, t), t); 361 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
638 double lmin = lhs->Min(); 362 Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone());
639 double rmin = rhs->Min(); 363 return Bounds(lower, upper);
640 double lmax = lhs->Max();
641 double rmax = rhs->Max();
642 // Or-ing any two values results in a value no smaller than their minimum.
643 // Even no smaller than their maximum if both values are non-negative.
644 Handle<Object> min = f->NewNumber(
645 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin));
646 if (lmax < 0 || rmax < 0) {
647 // Or-ing two values of which at least one is negative results in a negative
648 // value.
649 Handle<Object> max = f->NewNumber(-1);
650 return Type::Range(min, max, t->zone());
651 }
652 Handle<Object> max = f->NewNumber(Type::Signed32()->Max());
653 return Type::Range(min, max, t->zone());
654 // TODO(neis): Be precise for singleton inputs, here and elsewhere.
655 } 364 }
656 365
657 366
658 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 367 Bounds Typer::Visitor::TypeJSBitwiseAnd(Node* node) {
659 Factory* f = t->zone()->isolate()->factory(); 368 Bounds left = OperandType(node, 0);
660 lhs = NumberToInt32(ToNumber(lhs, t), t); 369 Bounds right = OperandType(node, 1);
661 rhs = NumberToInt32(ToNumber(rhs, t), t); 370 Type* upper = Type::Union(left.upper, right.upper, zone());
662 double lmin = lhs->Min(); 371 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
663 double rmin = rhs->Min(); 372 Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone());
664 double lmax = lhs->Max(); 373 return Bounds(lower, upper);
665 double rmax = rhs->Max();
666 // And-ing any two values results in a value no larger than their maximum.
667 // Even no larger than their minimum if both values are non-negative.
668 Handle<Object> max = f->NewNumber(
669 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax));
670 if (lmin >= 0 || rmin >= 0) {
671 // And-ing two values of which at least one is non-negative results in a
672 // non-negative value.
673 Handle<Object> min = f->NewNumber(0);
674 return Type::Range(min, max, t->zone());
675 }
676 Handle<Object> min = f->NewNumber(Type::Signed32()->Min());
677 return Type::Range(min, max, t->zone());
678 } 374 }
679 375
680 376
681 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { 377 Bounds Typer::Visitor::TypeJSBitwiseXor(Node* node) {
682 lhs = NumberToInt32(ToNumber(lhs, t), t); 378 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
683 rhs = NumberToInt32(ToNumber(rhs, t), t);
684 double lmin = lhs->Min();
685 double rmin = rhs->Min();
686 double lmax = lhs->Max();
687 double rmax = rhs->Max();
688 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
689 // Xor-ing negative or non-negative values results in a non-negative value.
690 return t->non_negative_signed32;
691 }
692 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
693 // Xor-ing a negative and a non-negative value results in a negative value.
694 return t->negative_signed32;
695 }
696 return Type::Signed32();
697 } 379 }
698 380
699 381
700 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { 382 Bounds Typer::Visitor::TypeJSShiftLeft(Node* node) {
701 return Type::Signed32(); 383 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
702 } 384 }
703 385
704 386
705 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { 387 Bounds Typer::Visitor::TypeJSShiftRight(Node* node) {
706 lhs = NumberToInt32(ToNumber(lhs, t), t); 388 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
707 Factory* f = t->zone()->isolate()->factory();
708 if (lhs->Min() >= 0) {
709 // Right-shifting a non-negative value cannot make it negative, nor larger.
710 Handle<Object> min = f->NewNumber(0);
711 Handle<Object> max = f->NewNumber(lhs->Max());
712 return Type::Range(min, max, t->zone());
713 }
714 if (lhs->Max() < 0) {
715 // Right-shifting a negative value cannot make it non-negative, nor smaller.
716 Handle<Object> min = f->NewNumber(lhs->Min());
717 Handle<Object> max = f->NewNumber(-1);
718 return Type::Range(min, max, t->zone());
719 }
720 return Type::Signed32();
721 } 389 }
722 390
723 391
724 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 392 Bounds Typer::Visitor::TypeJSShiftRightLogical(Node* node) {
725 lhs = NumberToUint32(ToNumber(lhs, t), t); 393 return Bounds(Type::UnsignedSmall(zone()), Type::Unsigned32(zone()));
726 Factory* f = t->zone()->isolate()->factory();
727 // Logical right-shifting any value cannot make it larger.
728 Handle<Object> min = f->NewNumber(0);
729 Handle<Object> max = f->NewNumber(lhs->Max());
730 return Type::Range(min, max, t->zone());
731 } 394 }
732 395
733 396
734 // JS arithmetic operators. 397 // JS arithmetic operators.
735 398
736 399 Bounds Typer::Visitor::TypeJSAdd(Node* node) {
737 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 400 Bounds left = OperandType(node, 0);
738 lhs = ToPrimitive(lhs, t); 401 Bounds right = OperandType(node, 1);
739 rhs = ToPrimitive(rhs, t); 402 Type* lower =
740 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 403 left.lower->Is(Type::None()) || right.lower->Is(Type::None()) ?
741 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 404 Type::None(zone()) :
742 return Type::String(); 405 left.lower->Is(Type::Number()) && right.lower->Is(Type::Number()) ?
743 } else { 406 Type::SignedSmall(zone()) :
744 return Type::NumberOrString(); 407 left.lower->Is(Type::String()) || right.lower->Is(Type::String()) ?
745 } 408 Type::String(zone()) : Type::None(zone());
746 } 409 Type* upper =
747 lhs = ToNumber(lhs, t); 410 left.upper->Is(Type::None()) && right.upper->Is(Type::None()) ?
748 rhs = ToNumber(rhs, t); 411 Type::None(zone()) :
749 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 412 left.upper->Is(Type::Number()) && right.upper->Is(Type::Number()) ?
750 // TODO(neis): Do some analysis. 413 Type::Number(zone()) :
751 // TODO(neis): Deal with numeric bitsets here and elsewhere. 414 left.upper->Is(Type::String()) || right.upper->Is(Type::String()) ?
752 return Type::Number(); 415 Type::String(zone()) : Type::NumberOrString(zone());
416 return Bounds(lower, upper);
753 } 417 }
754 418
755 419
756 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 420 Bounds Typer::Visitor::TypeJSSubtract(Node* node) {
757 lhs = ToNumber(lhs, t); 421 return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
758 rhs = ToNumber(rhs, t);
759 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
760 // TODO(neis): Do some analysis.
761 return Type::Number();
762 } 422 }
763 423
764 424
765 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 425 Bounds Typer::Visitor::TypeJSMultiply(Node* node) {
766 lhs = ToNumber(lhs, t); 426 return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
767 rhs = ToNumber(rhs, t);
768 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
769 // TODO(neis): Do some analysis.
770 return Type::Number();
771 } 427 }
772 428
773 429
774 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 430 Bounds Typer::Visitor::TypeJSDivide(Node* node) {
775 lhs = ToNumber(lhs, t); 431 return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
776 rhs = ToNumber(rhs, t);
777 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
778 // TODO(neis): Do some analysis.
779 return Type::Number();
780 } 432 }
781 433
782 434
783 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 435 Bounds Typer::Visitor::TypeJSModulus(Node* node) {
784 lhs = ToNumber(lhs, t); 436 return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
785 rhs = ToNumber(rhs, t);
786 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
787 // TODO(neis): Do some analysis.
788 return Type::Number();
789 } 437 }
790 438
791 439
792 // JS unary operators. 440 // JS unary operators.
793 441
794
795 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
796 return Invert(ToBoolean(type, t), t);
797 }
798
799
800 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) { 442 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) {
801 return TypeUnaryOp(node, JSUnaryNotTyper); 443 return Bounds(Type::Boolean(zone()));
802 } 444 }
803 445
804 446
805 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) { 447 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) {
806 return Bounds(Type::InternalizedString()); 448 return Bounds(Type::InternalizedString(zone()));
807 } 449 }
808 450
809 451
810 // JS conversion operators. 452 // JS conversion operators.
811 453
812
813 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) { 454 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) {
814 return TypeUnaryOp(node, ToBoolean); 455 return Bounds(Type::Boolean(zone()));
815 } 456 }
816 457
817 458
818 Bounds Typer::Visitor::TypeJSToNumber(Node* node) { 459 Bounds Typer::Visitor::TypeJSToNumber(Node* node) {
819 return TypeUnaryOp(node, ToNumber); 460 return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
820 } 461 }
821 462
822 463
823 Bounds Typer::Visitor::TypeJSToString(Node* node) { 464 Bounds Typer::Visitor::TypeJSToString(Node* node) {
824 return TypeUnaryOp(node, ToString); 465 return Bounds(Type::None(zone()), Type::String(zone()));
825 } 466 }
826 467
827 468
828 Bounds Typer::Visitor::TypeJSToName(Node* node) { 469 Bounds Typer::Visitor::TypeJSToName(Node* node) {
829 return Bounds(Type::None(), Type::Name()); 470 return Bounds(Type::None(zone()), Type::Name(zone()));
830 } 471 }
831 472
832 473
833 Bounds Typer::Visitor::TypeJSToObject(Node* node) { 474 Bounds Typer::Visitor::TypeJSToObject(Node* node) {
834 return Bounds(Type::None(), Type::Receiver()); 475 return Bounds(Type::None(zone()), Type::Receiver(zone()));
835 } 476 }
836 477
837 478
838 // JS object operators. 479 // JS object operators.
839 480
840
841 Bounds Typer::Visitor::TypeJSCreate(Node* node) { 481 Bounds Typer::Visitor::TypeJSCreate(Node* node) {
842 return Bounds(Type::None(), Type::Object()); 482 return Bounds(Type::None(zone()), Type::Object(zone()));
843 }
844
845
846 Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
847 // TODO(rossberg): Use range types and sized array types to filter undefined.
848 if (object->IsArray() && name->Is(Type::Integral32())) {
849 return Type::Union(
850 object->AsArray()->Element(), Type::Undefined(), t->zone());
851 }
852 return Type::Any();
853 } 483 }
854 484
855 485
856 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { 486 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) {
857 return TypeBinaryOp(node, JSLoadPropertyTyper); 487 Bounds object = OperandType(node, 0);
488 Bounds name = OperandType(node, 1);
489 Bounds result = Bounds::Unbounded(zone());
490 // TODO(rossberg): Use range types and sized array types to filter undefined.
491 if (object.lower->IsArray() && name.lower->Is(Type::Integral32())) {
492 result.lower = Type::Union(
493 object.lower->AsArray()->Element(), Type::Undefined(zone()), zone());
494 }
495 if (object.upper->IsArray() && name.upper->Is(Type::Integral32())) {
496 result.upper = Type::Union(
497 object.upper->AsArray()->Element(), Type::Undefined(zone()), zone());
498 }
499 return result;
858 } 500 }
859 501
860 502
861 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { 503 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
862 return Bounds::Unbounded(zone()); 504 return Bounds::Unbounded(zone());
863 } 505 }
864 506
865 507
866 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { 508 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
867 UNREACHABLE(); 509 UNREACHABLE();
868 return Bounds(); 510 return Bounds();
869 } 511 }
870 512
871 513
872 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { 514 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
873 UNREACHABLE(); 515 UNREACHABLE();
874 return Bounds(); 516 return Bounds();
875 } 517 }
876 518
877 519
878 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) { 520 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) {
879 return Bounds(Type::Boolean()); 521 return Bounds(Type::Boolean(zone()));
880 } 522 }
881 523
882 524
883 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) { 525 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) {
884 return Bounds(Type::Boolean()); 526 return Bounds(Type::Boolean(zone()));
885 } 527 }
886 528
887 529
888 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) { 530 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) {
889 return Bounds(Type::Boolean()); 531 return Bounds(Type::Boolean(zone()));
890 } 532 }
891 533
892 534
893 // JS context operators. 535 // JS context operators.
894 536
895
896 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { 537 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
897 Bounds outer = OperandType(node, 0); 538 Bounds outer = OperandType(node, 0);
898 DCHECK(outer.upper->Maybe(Type::Internal())); 539 DCHECK(outer.upper->Maybe(Type::Internal()));
899 // TODO(rossberg): More precisely, instead of the above assertion, we should 540 // TODO(rossberg): More precisely, instead of the above assertion, we should
900 // back-propagate the constraint that it has to be a subtype of Internal. 541 // back-propagate the constraint that it has to be a subtype of Internal.
901 542
902 ContextAccess access = OpParameter<ContextAccess>(node); 543 ContextAccess access = OpParameter<ContextAccess>(node);
903 Type* context_type = outer.upper; 544 Type* context_type = outer.upper;
904 MaybeHandle<Context> context; 545 MaybeHandle<Context> context;
905 if (context_type->IsConstant()) { 546 if (context_type->IsConstant()) {
(...skipping 14 matching lines...) Expand all
920 context = handle(context.ToHandleChecked()->previous(), isolate()); 561 context = handle(context.ToHandleChecked()->previous(), isolate());
921 } 562 }
922 } 563 }
923 if (context.is_null()) { 564 if (context.is_null()) {
924 return Bounds::Unbounded(zone()); 565 return Bounds::Unbounded(zone());
925 } else { 566 } else {
926 Handle<Object> value = 567 Handle<Object> value =
927 handle(context.ToHandleChecked()->get(static_cast<int>(access.index())), 568 handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
928 isolate()); 569 isolate());
929 Type* lower = TypeConstant(value); 570 Type* lower = TypeConstant(value);
930 return Bounds(lower, Type::Any()); 571 return Bounds(lower, Type::Any(zone()));
931 } 572 }
932 } 573 }
933 574
934 575
935 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { 576 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) {
936 UNREACHABLE(); 577 UNREACHABLE();
937 return Bounds(); 578 return Bounds();
938 } 579 }
939 580
940 581
(...skipping 29 matching lines...) Expand all
970 611
971 612
972 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) { 613 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) {
973 Type* outer = ContextType(node); 614 Type* outer = ContextType(node);
974 return Bounds(Type::Context(outer, zone())); 615 return Bounds(Type::Context(outer, zone()));
975 } 616 }
976 617
977 618
978 // JS other operators. 619 // JS other operators.
979 620
980
981 Bounds Typer::Visitor::TypeJSYield(Node* node) { 621 Bounds Typer::Visitor::TypeJSYield(Node* node) {
982 return Bounds::Unbounded(zone()); 622 return Bounds::Unbounded(zone());
983 } 623 }
984 624
985 625
986 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) { 626 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) {
987 return Bounds(Type::None(), Type::Receiver()); 627 return Bounds(Type::None(zone()), Type::Receiver(zone()));
988 }
989
990
991 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
992 return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any();
993 } 628 }
994 629
995 630
996 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) { 631 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) {
997 return TypeUnaryOp(node, JSCallFunctionTyper); // We ignore argument types. 632 Bounds fun = OperandType(node, 0);
633 Type* lower = fun.lower->IsFunction()
634 ? fun.lower->AsFunction()->Result() : Type::None(zone());
635 Type* upper = fun.upper->IsFunction()
636 ? fun.upper->AsFunction()->Result() : Type::Any(zone());
637 return Bounds(lower, upper);
998 } 638 }
999 639
1000 640
1001 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) { 641 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
1002 return Bounds::Unbounded(zone()); 642 return Bounds::Unbounded(zone());
1003 } 643 }
1004 644
1005 645
1006 Bounds Typer::Visitor::TypeJSDebugger(Node* node) { 646 Bounds Typer::Visitor::TypeJSDebugger(Node* node) {
1007 return Bounds::Unbounded(zone()); 647 return Bounds::Unbounded(zone());
1008 } 648 }
1009 649
1010 650
1011 // Simplified operators. 651 // Simplified operators.
1012 652
653 Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
654 return Bounds(Type::Boolean(zone()));
655 }
1013 656
1014 Bounds Typer::Visitor::TypeBooleanNot(Node* node) { 657
658 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) {
659 return Bounds(Type::Number(zone()));
660 }
661
662
663 Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
664 return Bounds(Type::Boolean(zone()));
665 }
666
667
668 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) {
669 return Bounds(Type::Boolean(zone()));
670 }
671
672
673 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
674 return Bounds(Type::Boolean(zone()));
675 }
676
677
678 Bounds Typer::Visitor::TypeNumberAdd(Node* node) {
679 return Bounds(Type::Number(zone()));
680 }
681
682
683 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) {
684 return Bounds(Type::Number(zone()));
685 }
686
687
688 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) {
689 return Bounds(Type::Number(zone()));
690 }
691
692
693 Bounds Typer::Visitor::TypeNumberDivide(Node* node) {
694 return Bounds(Type::Number(zone()));
695 }
696
697
698 Bounds Typer::Visitor::TypeNumberModulus(Node* node) {
699 return Bounds(Type::Number(zone()));
700 }
701
702
703 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) {
704 Bounds arg = OperandType(node, 0);
705 Type* s32 = Type::Signed32(zone());
706 Type* lower = arg.lower->Is(s32) ? arg.lower : s32;
707 Type* upper = arg.upper->Is(s32) ? arg.upper : s32;
708 return Bounds(lower, upper);
709 }
710
711
712 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) {
713 Bounds arg = OperandType(node, 0);
714 Type* u32 = Type::Unsigned32(zone());
715 Type* lower = arg.lower->Is(u32) ? arg.lower : u32;
716 Type* upper = arg.upper->Is(u32) ? arg.upper : u32;
717 return Bounds(lower, upper);
718 }
719
720
721 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) {
722 return Bounds(Type::Boolean(zone()));
723 }
724
725
726 Bounds Typer::Visitor::TypeStringEqual(Node* node) {
727 return Bounds(Type::Boolean(zone()));
728 }
729
730
731 Bounds Typer::Visitor::TypeStringLessThan(Node* node) {
732 return Bounds(Type::Boolean(zone()));
733 }
734
735
736 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
737 return Bounds(Type::Boolean(zone()));
738 }
739
740
741 Bounds Typer::Visitor::TypeStringAdd(Node* node) {
742 return Bounds(Type::String(zone()));
743 }
744
745
746 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
747 // TODO(titzer): type is type of input, representation is Word32.
748 return Bounds(Type::Integral32());
749 }
750
751
752 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
753 return Bounds(Type::Integral32()); // TODO(titzer): add appropriate rep
754 }
755
756
757 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
758 // TODO(titzer): type is type of input, representation is Float64.
759 return Bounds(Type::Number());
760 }
761
762
763 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
764 // TODO(titzer): type is type of input, representation is Tagged.
765 return Bounds(Type::Integral32());
766 }
767
768
769 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
770 // TODO(titzer): type is type of input, representation is Tagged.
771 return Bounds(Type::Unsigned32());
772 }
773
774
775 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
776 // TODO(titzer): type is type of input, representation is Tagged.
777 return Bounds(Type::Number());
778 }
779
780
781 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
782 // TODO(titzer): type is type of input, representation is Bit.
1015 return Bounds(Type::Boolean()); 783 return Bounds(Type::Boolean());
1016 } 784 }
1017 785
1018 786
1019 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) { 787 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
1020 return Bounds(Type::Number()); 788 // TODO(titzer): type is type of input, representation is Tagged.
1021 }
1022
1023
1024 Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
1025 return Bounds(Type::Boolean()); 789 return Bounds(Type::Boolean());
1026 } 790 }
1027 791
1028 792
1029 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) {
1030 return Bounds(Type::Boolean());
1031 }
1032
1033
1034 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1035 return Bounds(Type::Boolean());
1036 }
1037
1038
1039 Bounds Typer::Visitor::TypeNumberAdd(Node* node) {
1040 return Bounds(Type::Number());
1041 }
1042
1043
1044 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) {
1045 return Bounds(Type::Number());
1046 }
1047
1048
1049 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) {
1050 return Bounds(Type::Number());
1051 }
1052
1053
1054 Bounds Typer::Visitor::TypeNumberDivide(Node* node) {
1055 return Bounds(Type::Number());
1056 }
1057
1058
1059 Bounds Typer::Visitor::TypeNumberModulus(Node* node) {
1060 return Bounds(Type::Number());
1061 }
1062
1063
1064 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) {
1065 return TypeUnaryOp(node, NumberToInt32);
1066 }
1067
1068
1069 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) {
1070 return TypeUnaryOp(node, NumberToUint32);
1071 }
1072
1073
1074 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) {
1075 return Bounds(Type::Boolean());
1076 }
1077
1078
1079 Bounds Typer::Visitor::TypeStringEqual(Node* node) {
1080 return Bounds(Type::Boolean());
1081 }
1082
1083
1084 Bounds Typer::Visitor::TypeStringLessThan(Node* node) {
1085 return Bounds(Type::Boolean());
1086 }
1087
1088
1089 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1090 return Bounds(Type::Boolean());
1091 }
1092
1093
1094 Bounds Typer::Visitor::TypeStringAdd(Node* node) {
1095 return Bounds(Type::String());
1096 }
1097
1098
1099 static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
1100 // TODO(neis): Enable when expressible.
1101 /*
1102 return Type::Union(
1103 Type::Intersect(type, Type::Semantic(), zone),
1104 Type::Intersect(rep, Type::Representation(), zone), zone);
1105 */
1106 return type;
1107 }
1108
1109
1110 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
1111 Bounds arg = OperandType(node, 0);
1112 DCHECK(arg.upper->Is(Type::Signed32()));
1113 return Bounds(
1114 ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
1115 ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
1116 }
1117
1118
1119 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
1120 Bounds arg = OperandType(node, 0);
1121 DCHECK(arg.upper->Is(Type::Unsigned32()));
1122 return Bounds(
1123 ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
1124 ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
1125 }
1126
1127
1128 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
1129 Bounds arg = OperandType(node, 0);
1130 DCHECK(arg.upper->Is(Type::Number()));
1131 return Bounds(
1132 ChangeRepresentation(arg.lower, Type::UntaggedFloat64(), zone()),
1133 ChangeRepresentation(arg.upper, Type::UntaggedFloat64(), zone()));
1134 }
1135
1136
1137 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
1138 Bounds arg = OperandType(node, 0);
1139 DCHECK(arg.upper->Is(Type::Signed32()));
1140 return Bounds(
1141 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1142 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
1143 }
1144
1145
1146 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
1147 Bounds arg = OperandType(node, 0);
1148 DCHECK(arg.upper->Is(Type::Unsigned32()));
1149 return Bounds(
1150 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1151 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
1152 }
1153
1154
1155 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
1156 Bounds arg = OperandType(node, 0);
1157 // CHECK(arg.upper->Is(Type::Number()));
1158 // TODO(neis): This check currently fails due to inconsistent typing.
1159 return Bounds(
1160 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1161 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
1162 }
1163
1164
1165 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
1166 Bounds arg = OperandType(node, 0);
1167 DCHECK(arg.upper->Is(Type::Boolean()));
1168 return Bounds(
1169 ChangeRepresentation(arg.lower, Type::UntaggedInt1(), zone()),
1170 ChangeRepresentation(arg.upper, Type::UntaggedInt1(), zone()));
1171 }
1172
1173
1174 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
1175 Bounds arg = OperandType(node, 0);
1176 DCHECK(arg.upper->Is(Type::Boolean()));
1177 return Bounds(
1178 ChangeRepresentation(arg.lower, Type::TaggedPtr(), zone()),
1179 ChangeRepresentation(arg.upper, Type::TaggedPtr(), zone()));
1180 }
1181
1182
1183 Bounds Typer::Visitor::TypeLoadField(Node* node) { 793 Bounds Typer::Visitor::TypeLoadField(Node* node) {
1184 return Bounds(FieldAccessOf(node->op()).type); 794 return Bounds(FieldAccessOf(node->op()).type);
1185 } 795 }
1186 796
1187 797
1188 Bounds Typer::Visitor::TypeLoadElement(Node* node) { 798 Bounds Typer::Visitor::TypeLoadElement(Node* node) {
1189 return Bounds(ElementAccessOf(node->op()).type); 799 return Bounds(ElementAccessOf(node->op()).type);
1190 } 800 }
1191 801
1192 802
1193 Bounds Typer::Visitor::TypeStoreField(Node* node) { 803 Bounds Typer::Visitor::TypeStoreField(Node* node) {
1194 UNREACHABLE(); 804 UNREACHABLE();
1195 return Bounds(); 805 return Bounds();
1196 } 806 }
1197 807
1198 808
1199 Bounds Typer::Visitor::TypeStoreElement(Node* node) { 809 Bounds Typer::Visitor::TypeStoreElement(Node* node) {
1200 UNREACHABLE(); 810 UNREACHABLE();
1201 return Bounds(); 811 return Bounds();
1202 } 812 }
1203 813
1204 814
1205 // Machine operators. 815 // Machine operators.
1206 816
1207
1208 // TODO(rossberg): implement 817 // TODO(rossberg): implement
1209 #define DEFINE_METHOD(x) \ 818 #define DEFINE_METHOD(x) \
1210 Bounds Typer::Visitor::Type##x(Node* node) { \ 819 Bounds Typer::Visitor::Type##x(Node* node) { return Bounds(Type::None()); }
1211 return Bounds::Unbounded(zone()); \
1212 }
1213 MACHINE_OP_LIST(DEFINE_METHOD) 820 MACHINE_OP_LIST(DEFINE_METHOD)
1214 #undef DEFINE_METHOD 821 #undef DEFINE_METHOD
1215 822
1216 823
1217 // Heap constants. 824 // Heap constants.
1218 825
1219 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { 826 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
1220 if (value->IsJSFunction()) { 827 if (value->IsJSFunction()) {
1221 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { 828 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
1222 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { 829 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 } 907 }
1301 908
1302 909
1303 void Typer::DecorateGraph(Graph* graph) { 910 void Typer::DecorateGraph(Graph* graph) {
1304 graph->AddDecorator(new (zone()) TyperDecorator(this)); 911 graph->AddDecorator(new (zone()) TyperDecorator(this));
1305 } 912 }
1306 913
1307 } 914 }
1308 } 915 }
1309 } // namespace v8::internal::compiler 916 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698