Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 76698a4f64ab90ef861063743f8d5bde329ed502..2430d40e00a5df787f9f1a0b4f737144af17e2ea 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -1373,12 +1373,64 @@ Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { |
Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { |
- return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any(); |
+ if (fun->IsFunction()) { |
+ return fun->AsFunction()->Result(); |
+ } |
+ if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) { |
+ Handle<JSFunction> function = |
+ Handle<JSFunction>::cast(fun->AsConstant()->Value()); |
+ if (function->shared()->HasBuiltinFunctionId()) { |
+ switch (function->shared()->builtin_function_id()) { |
+ case kMathRandom: |
+ return Type::OrderedNumber(); |
+ case kMathFloor: |
+ case kMathRound: |
+ case kMathCeil: |
+ return t->cache_.kWeakint; |
+ // Unary math functions. |
+ case kMathAbs: |
+ case kMathLog: |
+ case kMathExp: |
+ case kMathSqrt: |
+ case kMathCos: |
+ case kMathSin: |
+ case kMathTan: |
+ case kMathAcos: |
+ case kMathAsin: |
+ case kMathAtan: |
+ case kMathFround: |
+ return Type::Number(); |
+ // Binary math functions. |
+ case kMathAtan2: |
+ case kMathPow: |
+ case kMathMax: |
+ case kMathMin: |
+ return Type::Number(); |
+ case kMathImul: |
+ return Type::Signed32(); |
+ case kMathClz32: |
+ return t->cache_.kZeroToThirtyTwo; |
+ // String functions. |
+ case kStringCharAt: |
+ case kStringFromCharCode: |
+ return Type::String(); |
+ // Array functions. |
+ case kArrayIndexOf: |
+ case kArrayLastIndexOf: |
+ return Type::Number(); |
+ default: |
+ break; |
+ } |
+ } |
+ } |
+ return Type::Any(); |
} |
Type* Typer::Visitor::TypeJSCallFunction(Node* node) { |
- return TypeUnaryOp(node, JSCallFunctionTyper); // We ignore argument types. |
+ // TODO(bmeurer): We could infer better types if we wouldn't ignore the |
+ // argument types for the JSCallFunctionTyper above. |
+ return TypeUnaryOp(node, JSCallFunctionTyper); |
} |
@@ -2043,64 +2095,7 @@ Type* Typer::Visitor::TypeCheckedStore(Node* node) { |
Type* Typer::Visitor::TypeConstant(Handle<Object> value) { |
- if (value->IsJSFunction()) { |
- if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { |
- switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { |
- case kMathRandom: |
- return typer_->cache_.kRandomFunc0; |
- case kMathFloor: |
- case kMathRound: |
- case kMathCeil: |
- return typer_->cache_.kWeakintFunc1; |
- // Unary math functions. |
- case kMathAbs: // TODO(rossberg): can't express overloading |
- case kMathLog: |
- case kMathExp: |
- case kMathSqrt: |
- case kMathCos: |
- case kMathSin: |
- case kMathTan: |
- case kMathAcos: |
- case kMathAsin: |
- case kMathAtan: |
- case kMathFround: |
- return typer_->cache_.kNumberFunc1; |
- // Binary math functions. |
- case kMathAtan2: |
- case kMathPow: |
- case kMathMax: |
- case kMathMin: |
- return typer_->cache_.kNumberFunc2; |
- case kMathImul: |
- return typer_->cache_.kImulFunc; |
- case kMathClz32: |
- return typer_->cache_.kClz32Func; |
- default: |
- break; |
- } |
- } |
- int const arity = |
- JSFunction::cast(*value)->shared()->internal_formal_parameter_count(); |
- switch (arity) { |
- case SharedFunctionInfo::kDontAdaptArgumentsSentinel: |
- // Some smart optimization at work... &%$!&@+$! |
- break; |
- case 0: |
- return typer_->cache_.kAnyFunc0; |
- case 1: |
- return typer_->cache_.kAnyFunc1; |
- case 2: |
- return typer_->cache_.kAnyFunc2; |
- case 3: |
- return typer_->cache_.kAnyFunc3; |
- default: { |
- DCHECK_LT(3, arity); |
- Type** const params = zone()->NewArray<Type*>(arity); |
- std::fill(¶ms[0], ¶ms[arity], Type::Any(zone())); |
- return Type::Function(Type::Any(zone()), arity, params, zone()); |
- } |
- } |
- } else if (value->IsJSTypedArray()) { |
+ if (value->IsJSTypedArray()) { |
switch (JSTypedArray::cast(*value)->type()) { |
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
case kExternal##Type##Array: \ |