| Index: src/ia32/codegen-ia32.cc | 
| =================================================================== | 
| --- src/ia32/codegen-ia32.cc	(revision 2983) | 
| +++ src/ia32/codegen-ia32.cc	(working copy) | 
| @@ -4431,10 +4431,10 @@ | 
| void CodeGenerator::VisitCall(Call* node) { | 
| Comment cmnt(masm_, "[ Call"); | 
|  | 
| +  Expression* function = node->expression(); | 
| ZoneList<Expression*>* args = node->arguments(); | 
|  | 
| // Check if the function is a variable or a property. | 
| -  Expression* function = node->expression(); | 
| Variable* var = function->AsVariableProxy()->AsVariable(); | 
| Property* property = function->AsProperty(); | 
|  | 
| @@ -4447,8 +4447,64 @@ | 
| // is resolved in cache misses (this also holds for megamorphic calls). | 
| // ------------------------------------------------------------------------ | 
|  | 
| -  if (var != NULL && !var->is_this() && var->is_global()) { | 
| +  if (var != NULL && var->is_possibly_eval()) { | 
| // ---------------------------------- | 
| +    // JavaScript example: 'eval(arg)'  // eval is not known to be shadowed | 
| +    // ---------------------------------- | 
| + | 
| +    // In a call to eval, we first call %ResolvePossiblyDirectEval to | 
| +    // resolve the function we need to call and the receiver of the | 
| +    // call.  Then we call the resolved function using the given | 
| +    // arguments. | 
| + | 
| +    // Prepare the stack for the call to the resolved function. | 
| +    Load(function); | 
| + | 
| +    // Allocate a frame slot for the receiver. | 
| +    frame_->Push(Factory::undefined_value()); | 
| +    int arg_count = args->length(); | 
| +    for (int i = 0; i < arg_count; i++) { | 
| +      Load(args->at(i)); | 
| +    } | 
| + | 
| +    // Prepare the stack for the call to ResolvePossiblyDirectEval. | 
| +    frame_->PushElementAt(arg_count + 1); | 
| +    if (arg_count > 0) { | 
| +      frame_->PushElementAt(arg_count); | 
| +    } else { | 
| +      frame_->Push(Factory::undefined_value()); | 
| +    } | 
| + | 
| +    // Resolve the call. | 
| +    Result result = | 
| +        frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); | 
| + | 
| +    // Touch up the stack with the right values for the function and the | 
| +    // receiver.  Use a scratch register to avoid destroying the result. | 
| +    Result scratch = allocator_->Allocate(); | 
| +    ASSERT(scratch.is_valid()); | 
| +    __ mov(scratch.reg(), FieldOperand(result.reg(), FixedArray::kHeaderSize)); | 
| +    frame_->SetElementAt(arg_count + 1, &scratch); | 
| + | 
| +    // We can reuse the result register now. | 
| +    frame_->Spill(result.reg()); | 
| +    __ mov(result.reg(), | 
| +           FieldOperand(result.reg(), FixedArray::kHeaderSize + kPointerSize)); | 
| +    frame_->SetElementAt(arg_count, &result); | 
| + | 
| +    // Call the function. | 
| +    CodeForSourcePosition(node->position()); | 
| +    InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; | 
| +    CallFunctionStub call_function(arg_count, in_loop); | 
| +    result = frame_->CallStub(&call_function, arg_count + 1); | 
| + | 
| +    // Restore the context and overwrite the function on the stack with | 
| +    // the result. | 
| +    frame_->RestoreContextRegister(); | 
| +    frame_->SetElementAt(0, &result); | 
| + | 
| +  } else if (var != NULL && !var->is_this() && var->is_global()) { | 
| +    // ---------------------------------- | 
| // JavaScript example: 'foo(1, 2, 3)'  // foo is global | 
| // ---------------------------------- | 
|  | 
| @@ -4616,64 +4672,6 @@ | 
| } | 
|  | 
|  | 
| -void CodeGenerator::VisitCallEval(CallEval* node) { | 
| -  Comment cmnt(masm_, "[ CallEval"); | 
| - | 
| -  // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve | 
| -  // the function we need to call and the receiver of the call. | 
| -  // Then we call the resolved function using the given arguments. | 
| - | 
| -  ZoneList<Expression*>* args = node->arguments(); | 
| -  Expression* function = node->expression(); | 
| - | 
| -  // Prepare the stack for the call to the resolved function. | 
| -  Load(function); | 
| - | 
| -  // Allocate a frame slot for the receiver. | 
| -  frame_->Push(Factory::undefined_value()); | 
| -  int arg_count = args->length(); | 
| -  for (int i = 0; i < arg_count; i++) { | 
| -    Load(args->at(i)); | 
| -  } | 
| - | 
| -  // Prepare the stack for the call to ResolvePossiblyDirectEval. | 
| -  frame_->PushElementAt(arg_count + 1); | 
| -  if (arg_count > 0) { | 
| -    frame_->PushElementAt(arg_count); | 
| -  } else { | 
| -    frame_->Push(Factory::undefined_value()); | 
| -  } | 
| - | 
| -  // Resolve the call. | 
| -  Result result = | 
| -      frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); | 
| - | 
| -  // Touch up the stack with the right values for the function and the | 
| -  // receiver.  Use a scratch register to avoid destroying the result. | 
| -  Result scratch = allocator_->Allocate(); | 
| -  ASSERT(scratch.is_valid()); | 
| -  __ mov(scratch.reg(), FieldOperand(result.reg(), FixedArray::kHeaderSize)); | 
| -  frame_->SetElementAt(arg_count + 1, &scratch); | 
| - | 
| -  // We can reuse the result register now. | 
| -  frame_->Spill(result.reg()); | 
| -  __ mov(result.reg(), | 
| -         FieldOperand(result.reg(), FixedArray::kHeaderSize + kPointerSize)); | 
| -  frame_->SetElementAt(arg_count, &result); | 
| - | 
| -  // Call the function. | 
| -  CodeForSourcePosition(node->position()); | 
| -  InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; | 
| -  CallFunctionStub call_function(arg_count, in_loop); | 
| -  result = frame_->CallStub(&call_function, arg_count + 1); | 
| - | 
| -  // Restore the context and overwrite the function on the stack with | 
| -  // the result. | 
| -  frame_->RestoreContextRegister(); | 
| -  frame_->SetElementAt(0, &result); | 
| -} | 
| - | 
| - | 
| void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { | 
| ASSERT(args->length() == 1); | 
| Load(args->at(0)); | 
|  |