Index: src/arm/codegen-arm.cc |
=================================================================== |
--- src/arm/codegen-arm.cc (revision 2983) |
+++ src/arm/codegen-arm.cc (working copy) |
@@ -2907,11 +2907,11 @@ |
VirtualFrame::SpilledScope spilled_scope; |
Comment cmnt(masm_, "[ Call"); |
+ Expression* function = node->expression(); |
ZoneList<Expression*>* args = node->arguments(); |
// Standard function call. |
// Check if the function is a variable or a property. |
- Expression* function = node->expression(); |
Variable* var = function->AsVariableProxy()->AsVariable(); |
Property* property = function->AsProperty(); |
@@ -2924,8 +2924,57 @@ |
// 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 stack for call to resolved function. |
+ LoadAndSpill(function); |
+ __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
+ frame_->EmitPush(r2); // Slot for receiver |
+ int arg_count = args->length(); |
+ for (int i = 0; i < arg_count; i++) { |
+ LoadAndSpill(args->at(i)); |
+ } |
+ |
+ // Prepare stack for call to ResolvePossiblyDirectEval. |
+ __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize)); |
+ frame_->EmitPush(r1); |
+ if (arg_count > 0) { |
+ __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
+ frame_->EmitPush(r1); |
+ } else { |
+ frame_->EmitPush(r2); |
+ } |
+ |
+ // Resolve the call. |
+ frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); |
+ |
+ // Touch up stack with the right values for the function and the receiver. |
+ __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); |
+ __ str(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
+ __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); |
+ __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
+ |
+ // Call the function. |
+ CodeForSourcePosition(node->position()); |
+ |
+ InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
+ CallFunctionStub call_function(arg_count, in_loop); |
+ frame_->CallStub(&call_function, arg_count + 1); |
+ |
+ __ ldr(cp, frame_->Context()); |
+ // Remove the function from the stack. |
+ frame_->Drop(); |
+ frame_->EmitPush(r0); |
+ |
+ } else if (var != NULL && !var->is_this() && var->is_global()) { |
+ // ---------------------------------- |
// JavaScript example: 'foo(1, 2, 3)' // foo is global |
// ---------------------------------- |
@@ -3049,63 +3098,6 @@ |
} |
-void CodeGenerator::VisitCallEval(CallEval* node) { |
-#ifdef DEBUG |
- int original_height = frame_->height(); |
-#endif |
- VirtualFrame::SpilledScope spilled_scope; |
- 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 stack for call to resolved function. |
- LoadAndSpill(function); |
- __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
- frame_->EmitPush(r2); // Slot for receiver |
- int arg_count = args->length(); |
- for (int i = 0; i < arg_count; i++) { |
- LoadAndSpill(args->at(i)); |
- } |
- |
- // Prepare stack for call to ResolvePossiblyDirectEval. |
- __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize)); |
- frame_->EmitPush(r1); |
- if (arg_count > 0) { |
- __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
- frame_->EmitPush(r1); |
- } else { |
- frame_->EmitPush(r2); |
- } |
- |
- // Resolve the call. |
- frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); |
- |
- // Touch up stack with the right values for the function and the receiver. |
- __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); |
- __ str(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
- __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); |
- __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
- |
- // Call the function. |
- CodeForSourcePosition(node->position()); |
- |
- InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
- CallFunctionStub call_function(arg_count, in_loop); |
- frame_->CallStub(&call_function, arg_count + 1); |
- |
- __ ldr(cp, frame_->Context()); |
- // Remove the function from the stack. |
- frame_->Drop(); |
- frame_->EmitPush(r0); |
- ASSERT(frame_->height() == original_height + 1); |
-} |
- |
- |
void CodeGenerator::VisitCallNew(CallNew* node) { |
#ifdef DEBUG |
int original_height = frame_->height(); |