Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 955c7e5e73faa23516e5d6f0686ff0b6ce7bf163..712f5d8dc5d5bd90e0da7ad309ae2f748e8dd243 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 = Pop(); |
|
Kevin Millikin (Chromium)
2011/11/07 14:34:50
I don't think this is right. In the unoptimized c
rossberg
2011/11/07 16:03:05
Done.
|
| HValue* context = environment()->LookupContext(); |
| HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
| @@ -5105,10 +5106,8 @@ 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); |
| - Drop(argument_count + 1); |
| + call = new(zone()) HCallFunction(context, function, argument_count); |
| + Drop(argument_count); |
| } |
| } |
| @@ -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()); |
| } |