Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 5e6b42ebd7c36ee9b0ad346ca2a77faf6750e924..38676624c618eeb3fa19fb257c75d37c3191c186 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -2179,9 +2179,12 @@ void HGraphBuilder::VisitForControl(Expression* expr, |
| } |
| -void HGraphBuilder::VisitArgument(Expression* expr) { |
| - CHECK_ALIVE(VisitForValue(expr)); |
| - Push(AddInstruction(new(zone()) HPushArgument(Pop()))); |
| +HValue* HGraphBuilder::VisitArgument(Expression* expr) { |
| + VisitForValue(expr); |
| + if (HasStackOverflow() || current_block() == NULL) return NULL; |
| + HValue* value = Pop(); |
| + Push(AddInstruction(new(zone()) HPushArgument(value))); |
| + return value; |
| } |
| @@ -4691,7 +4694,7 @@ void HGraphBuilder::VisitCall(Call* expr) { |
| if (prop != NULL) { |
| if (!prop->key()->IsPropertyName()) { |
| // Keyed function call. |
| - CHECK_ALIVE(VisitForValue(prop->obj())); |
| + CHECK_ALIVE(VisitArgument(prop->obj())); |
| CHECK_ALIVE(VisitForValue(prop->key())); |
| // Push receiver and key like the non-optimized code generator expects it. |
| @@ -4700,13 +4703,12 @@ void HGraphBuilder::VisitCall(Call* expr) { |
| Push(key); |
| Push(receiver); |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| HValue* context = environment()->LookupContext(); |
| - call = PreProcessCall( |
| - new(zone()) HCallKeyed(context, key, argument_count)); |
| + call = new(zone()) HCallKeyed(context, key, argument_count); |
| call->set_position(expr->position()); |
| - Drop(1); // Key. |
| + Drop(argument_count + 1); // 1 is the key. |
| ast_context()->ReturnInstruction(call, expr->id()); |
| return; |
| } |
| @@ -4766,11 +4768,6 @@ void HGraphBuilder::VisitCall(Call* expr) { |
| Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
| - if (!global_call) { |
| - ++argument_count; |
| - CHECK_ALIVE(VisitForValue(expr->expression())); |
| - } |
| - |
| if (global_call) { |
| bool known_global_function = false; |
| // If there is a global property cell for the name at compile time and |
| @@ -4810,22 +4807,29 @@ void HGraphBuilder::VisitCall(Call* expr) { |
| argument_count)); |
| } else { |
| HValue* context = environment()->LookupContext(); |
| - PushAndAdd(new(zone()) HGlobalObject(context)); |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + HGlobalObject* receiver = new(zone()) HGlobalObject(context); |
| + AddInstruction(receiver); |
| + PushAndAdd(new(zone()) HPushArgument(receiver)); |
| + CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| - call = PreProcessCall(new(zone()) HCallGlobal(context, |
| - var->name(), |
| - argument_count)); |
| + call = new(zone()) HCallGlobal(context, var->name(), argument_count); |
| + Drop(argument_count); |
| } |
| } else { |
| + CHECK_ALIVE(VisitArgument(expr->expression())); |
| HValue* context = environment()->LookupContext(); |
| HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| + HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
| AddInstruction(global_object); |
| - PushAndAdd(new(zone()) HGlobalReceiver(global_object)); |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + AddInstruction(receiver); |
| + PushAndAdd(new(zone()) HPushArgument(receiver)); |
| + CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| - call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); |
| + // 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); |
| } |
| } |
| @@ -4840,18 +4844,18 @@ void HGraphBuilder::VisitCallNew(CallNew* expr) { |
| ASSERT(current_block()->HasPredecessor()); |
| // The constructor function is also used as the receiver argument to the |
| // JS construct call builtin. |
| - CHECK_ALIVE(VisitForValue(expr->expression())); |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + HValue* constructor = NULL; |
| + CHECK_ALIVE(constructor = VisitArgument(expr->expression())); |
|
Kevin Millikin (Chromium)
2011/06/28 10:51:29
I realize this is kind of ugly. Feel free to sugg
|
| + CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| HValue* context = environment()->LookupContext(); |
| // The constructor is both an operand to the instruction and an argument |
| // to the construct call. |
| int arg_count = expr->arguments()->length() + 1; // Plus constructor. |
| - HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); |
| HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); |
| call->set_position(expr->position()); |
| - PreProcessCall(call); |
| + Drop(arg_count); |
| ast_context()->ReturnInstruction(call, expr->id()); |
| } |