Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 955c7e5e73faa23516e5d6f0686ff0b6ce7bf163..9df0fe44f9f24438d5eb76061fc6401886a90ae8 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -5096,7 +5096,8 @@ void HGraphBuilder::VisitCall(Call* expr) { |
} |
} else { |
- CHECK_ALIVE(VisitArgument(expr->expression())); |
+ CHECK_ALIVE(VisitForValue(expr->expression())); |
+ HValue* function = Top(); |
HValue* context = environment()->LookupContext(); |
HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
@@ -5105,9 +5106,7 @@ void HGraphBuilder::VisitCall(Call* expr) { |
PushAndAdd(new(zone()) HPushArgument(receiver)); |
CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
- // The function to call is treated as an argument to the call function |
- // stub. |
- call = new(zone()) HCallFunction(context, argument_count + 1); |
+ call = new(zone()) HCallFunction(context, function, argument_count); |
Drop(argument_count + 1); |
} |
} |
@@ -6329,12 +6328,37 @@ void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); |
} |
CHECK_ALIVE(VisitForValue(call->arguments()->last())); |
+ |
HValue* function = Pop(); |
HValue* context = environment()->LookupContext(); |
- HInvokeFunction* result = |
- new(zone()) HInvokeFunction(context, function, arg_count); |
+ |
+ // Branch for function proxies, or other non-functions. |
+ HHasInstanceTypeAndBranch* typecheck = |
+ new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); |
+ HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); |
+ HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); |
+ HBasicBlock* join = graph()->CreateBasicBlock(); |
+ typecheck->SetSuccessorAt(0, if_jsfunction); |
+ typecheck->SetSuccessorAt(1, if_nonfunction); |
+ current_block()->Finish(typecheck); |
+ |
+ set_current_block(if_jsfunction); |
+ HInstruction* invoke_result = AddInstruction( |
+ new(zone()) HInvokeFunction(context, function, arg_count)); |
Drop(arg_count); |
- return ast_context()->ReturnInstruction(result, call->id()); |
+ Push(invoke_result); |
+ if_jsfunction->Goto(join); |
+ |
+ set_current_block(if_nonfunction); |
+ HInstruction* call_result = AddInstruction( |
+ new(zone()) HCallFunction(context, function, arg_count)); |
+ Drop(arg_count); |
+ Push(call_result); |
+ if_nonfunction->Goto(join); |
+ |
+ set_current_block(join); |
+ join->SetJoinId(call->id()); |
+ return ast_context()->ReturnValue(Pop()); |
} |