| 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;
 | 
|    }
 | 
| 
 |