Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 96f7b65be2cfbbd51a6b5f6b754695affe952a89..91bcf5147063175f891595e0007a7813cc2f4039 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -231,7 +231,11 @@ class Typer::Visitor : public Reducer { |
static Type* ToPrimitive(Type*, Typer*); |
static Type* ToBoolean(Type*, Typer*); |
+ static Type* ToInteger(Type*, Typer*); |
+ static Type* ToLength(Type*, Typer*); |
+ static Type* ToName(Type*, Typer*); |
static Type* ToNumber(Type*, Typer*); |
+ static Type* ToObject(Type*, Typer*); |
static Type* ToString(Type*, Typer*); |
static Type* NumberToInt32(Type*, Typer*); |
static Type* NumberToUint32(Type*, Typer*); |
@@ -402,6 +406,39 @@ Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { |
} |
+// static |
+Type* Typer::Visitor::ToInteger(Type* type, Typer* t) { |
+ // ES6 section 7.1.4 ToInteger ( argument ) |
+ type = ToNumber(type, t); |
+ if (type->Is(t->cache_.kIntegerOrMinusZero)) return type; |
+ return t->cache_.kIntegerOrMinusZero; |
+} |
+ |
+ |
+// static |
+Type* Typer::Visitor::ToLength(Type* type, Typer* t) { |
+ // ES6 section 7.1.15 ToLength ( argument ) |
+ type = ToInteger(type, t); |
+ double min = type->Min(); |
+ double max = type->Max(); |
+ if (min <= 0.0) min = 0.0; |
+ if (max > kMaxSafeInteger) max = kMaxSafeInteger; |
+ if (max <= min) max = min; |
+ return Type::Range(min, max, t->zone()); |
+} |
+ |
+ |
+// static |
+Type* Typer::Visitor::ToName(Type* type, Typer* t) { |
+ // ES6 section 7.1.14 ToPropertyKey ( argument ) |
+ type = ToPrimitive(type, t); |
+ if (type->Is(Type::Name())) return type; |
+ if (type->Maybe(Type::Symbol())) return Type::Name(); |
+ return ToString(type, t); |
+} |
+ |
+ |
+// static |
Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
if (type->Is(Type::Number())) return type; |
if (type->Is(Type::NullOrUndefined())) { |
@@ -424,7 +461,20 @@ Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
} |
+// static |
+Type* Typer::Visitor::ToObject(Type* type, Typer* t) { |
+ // ES6 section 7.1.13 ToObject ( argument ) |
+ if (type->Is(Type::Receiver())) return type; |
+ if (type->Is(Type::Primitive())) return Type::OtherObject(); |
+ if (!type->Maybe(Type::Undetectable())) return Type::DetectableReceiver(); |
+ return Type::Receiver(); |
+} |
+ |
+ |
+// static |
Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
+ // ES6 section 7.1.12 ToString ( argument ) |
+ type = ToPrimitive(type, t); |
if (type->Is(Type::String())) return type; |
return Type::String(); |
} |
@@ -995,7 +1045,7 @@ Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, |
(rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || |
(rhs->Maybe(t->cache_.kSingletonZero) && |
(lmin == -V8_INFINITY || lmax == +V8_INFINITY)); |
- if (maybe_nan) return t->cache_.kWeakint; // Giving up. |
+ if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up. |
bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) || |
(rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0); |
Type* range = |
@@ -1142,10 +1192,14 @@ Type* Typer::Visitor::TypeJSToString(Node* node) { |
} |
-Type* Typer::Visitor::TypeJSToName(Node* node) { return Type::Name(); } |
+Type* Typer::Visitor::TypeJSToName(Node* node) { |
+ return TypeUnaryOp(node, ToName); |
+} |
-Type* Typer::Visitor::TypeJSToObject(Node* node) { return Type::Receiver(); } |
+Type* Typer::Visitor::TypeJSToObject(Node* node) { |
+ return TypeUnaryOp(node, ToObject); |
+} |
// JS object operators. |
@@ -1394,7 +1448,7 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { |
case kMathFloor: |
case kMathRound: |
case kMathCeil: |
- return t->cache_.kWeakint; |
+ return t->cache_.kIntegerOrMinusZeroOrNaN; |
// Unary math functions. |
case kMathAbs: |
case kMathLog: |
@@ -1468,8 +1522,22 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { |
return Type::Range(0, 32, zone()); |
case Runtime::kInlineStringGetLength: |
return Type::Range(0, String::kMaxLength, zone()); |
+ case Runtime::kInlineToInteger: |
+ return TypeUnaryOp(node, ToInteger); |
+ case Runtime::kInlineToLength: |
+ return TypeUnaryOp(node, ToLength); |
+ case Runtime::kInlineToName: |
+ return TypeUnaryOp(node, ToName); |
+ case Runtime::kInlineToNumber: |
+ return TypeUnaryOp(node, ToNumber); |
case Runtime::kInlineToObject: |
- return Type::Receiver(); |
+ return TypeUnaryOp(node, ToObject); |
+ case Runtime::kInlineToPrimitive: |
+ case Runtime::kInlineToPrimitive_Number: |
+ case Runtime::kInlineToPrimitive_String: |
+ return TypeUnaryOp(node, ToPrimitive); |
+ case Runtime::kInlineToString: |
+ return TypeUnaryOp(node, ToString); |
default: |
break; |
} |