| 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: \
|
|
|