Revision: 2984
Author: [email protected]
Date: Tue Sep 29 06:28:30 2009
Log: Remove CallEval as a subclass of the Call AST node type.  We were not
differentiating between Call and CallEval except in the code
generator, and the difference can be detected from a regular Call AST
node at code generation time.

Review URL: http://codereview.chromium.org/245042
http://code.google.com/p/v8/source/detail?r=2984

Modified:
  /branches/bleeding_edge/src/arm/codegen-arm.cc
  /branches/bleeding_edge/src/ast.cc
  /branches/bleeding_edge/src/ast.h
  /branches/bleeding_edge/src/cfg.cc
  /branches/bleeding_edge/src/ia32/codegen-ia32.cc
  /branches/bleeding_edge/src/parser.cc
  /branches/bleeding_edge/src/prettyprinter.cc
  /branches/bleeding_edge/src/rewriter.cc
  /branches/bleeding_edge/src/usage-analyzer.cc
  /branches/bleeding_edge/src/variables.h
  /branches/bleeding_edge/src/x64/codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc      Mon Sep 28 05:01:05 2009
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc      Tue Sep 29 06:28:30 2009
@@ -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
      // ----------------------------------

@@ -3047,63 +3096,6 @@
    }
    ASSERT(frame_->height() == original_height + 1);
  }
-
-
-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) {
=======================================
--- /branches/bleeding_edge/src/ast.cc  Thu Jul 30 05:09:05 2009
+++ /branches/bleeding_edge/src/ast.cc  Tue Sep 29 06:28:30 2009
@@ -40,7 +40,6 @@
  ValidLeftHandSideSentinel ValidLeftHandSideSentinel::instance_;
  Property Property::this_property_(VariableProxySentinel::this_proxy(),  
NULL, 0);
  Call Call::sentinel_(NULL, NULL, 0);
-CallEval CallEval::sentinel_(NULL, NULL, 0);


  //  
----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/ast.h   Mon Sep 28 05:01:05 2009
+++ /branches/bleeding_edge/src/ast.h   Tue Sep 29 06:28:30 2009
@@ -85,7 +85,6 @@
    V(Throw)                                      \
    V(Property)                                   \
    V(Call)                                       \
-  V(CallEval)                                   \
    V(CallNew)                                    \
    V(CallRuntime)                                \
    V(UnaryOperation)                             \
@@ -991,24 +990,6 @@
  };


-// The CallEval class represents a call of the form 'eval(...)' where eval
-// cannot be seen to be overwritten at compile time. It is potentially a
-// direct (i.e. not aliased) eval call. The real nature of the call is
-// determined at runtime.
-class CallEval: public Call {
- public:
-  CallEval(Expression* expression, ZoneList<Expression*>* arguments, int  
pos)
-      : Call(expression, arguments, pos) { }
-
-  virtual void Accept(AstVisitor* v);
-
-  static CallEval* sentinel() { return &sentinel_; }
-
- private:
-  static CallEval sentinel_;
-};
-
-
  // The CallRuntime class does not represent any official JavaScript
  // language construct. Instead it is used to call a C or JS function
  // with a set of arguments. This is used from the builtins that are
=======================================
--- /branches/bleeding_edge/src/cfg.cc  Wed Sep  9 03:49:40 2009
+++ /branches/bleeding_edge/src/cfg.cc  Tue Sep 29 06:28:30 2009
@@ -396,11 +396,6 @@
  void ExpressionCfgBuilder::VisitCall(Call* expr) {
    BAILOUT("Call");
  }
-
-
-void ExpressionCfgBuilder::VisitCallEval(CallEval* expr) {
-  BAILOUT("CallEval");
-}


  void ExpressionCfgBuilder::VisitCallNew(CallNew* expr) {
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Tue Sep 29 02:21:19  
2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Tue Sep 29 06:28:30  
2009
@@ -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
      // ----------------------------------

@@ -4614,64 +4670,6 @@
    // Replace the function on the stack with the result.
    frame_->SetElementAt(0, &result);
  }
-
-
-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) {
=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Aug 31 08:02:54 2009
+++ /branches/bleeding_edge/src/parser.cc       Tue Sep 29 06:28:30 2009
@@ -797,12 +797,6 @@
                                int pos) {
      return Call::sentinel();
    }
-
-  virtual Expression* NewCallEval(Expression* expression,
-                                  ZoneList<Expression*>* arguments,
-                                  int pos) {
-    return CallEval::sentinel();
-  }

    virtual Statement* EmptyStatement() {
      return NULL;
@@ -853,12 +847,6 @@
                                int pos) {
      return new Call(expression, arguments, pos);
    }
-
-  virtual Expression* NewCallEval(Expression* expression,
-                                  ZoneList<Expression*>* arguments,
-                                  int pos) {
-    return new CallEval(expression, arguments, pos);
-  }

    virtual Statement* EmptyStatement();
  };
@@ -3074,8 +3062,6 @@
          // declared in the current scope chain. These calls are marked as
          // potentially direct eval calls. Whether they are actually direct  
calls
          // to eval is determined at run time.
-
-        bool is_potentially_direct_eval = false;
          if (!is_pre_parsing_) {
            VariableProxy* callee = result->AsVariableProxy();
            if (callee != NULL &&  
callee->IsVariable(Factory::eval_symbol())) {
@@ -3083,16 +3069,10 @@
              Variable* var = top_scope_->Lookup(name);
              if (var == NULL) {
                top_scope_->RecordEvalCall();
-              is_potentially_direct_eval = true;
              }
            }
          }
-
-        if (is_potentially_direct_eval) {
-          result = factory()->NewCallEval(result, args, pos);
-        } else {
-          result = factory()->NewCall(result, args, pos);
-        }
+        result = factory()->NewCall(result, args, pos);
          break;
        }

=======================================
--- /branches/bleeding_edge/src/prettyprinter.cc        Thu Jul 30 04:53:29 2009
+++ /branches/bleeding_edge/src/prettyprinter.cc        Tue Sep 29 06:28:30 2009
@@ -356,11 +356,6 @@
    Visit(node->expression());
    PrintArguments(node->arguments());
  }
-
-
-void PrettyPrinter::VisitCallEval(CallEval* node) {
-  VisitCall(node);
-}


  void PrettyPrinter::VisitCallNew(CallNew* node) {
@@ -1038,11 +1033,6 @@
    Visit(node->expression());
    PrintArguments(node->arguments());
  }
-
-
-void AstPrinter::VisitCallEval(CallEval* node) {
-  VisitCall(node);
-}


  void AstPrinter::VisitCallNew(CallNew* node) {
=======================================
--- /branches/bleeding_edge/src/rewriter.cc     Thu Jul 30 05:09:05 2009
+++ /branches/bleeding_edge/src/rewriter.cc     Tue Sep 29 06:28:30 2009
@@ -381,12 +381,6 @@
    Visit(node->expression());
    OptimizeArguments(node->arguments());
  }
-
-
-void AstOptimizer::VisitCallEval(CallEval* node) {
-  Visit(node->expression());
-  OptimizeArguments(node->arguments());
-}


  void AstOptimizer::VisitCallNew(CallNew* node) {
@@ -757,12 +751,6 @@
    USE(node);
    UNREACHABLE();
  }
-
-
-void Processor::VisitCallEval(CallEval* node) {
-  USE(node);
-  UNREACHABLE();
-}


  void Processor::VisitCallNew(CallNew* node) {
=======================================
--- /branches/bleeding_edge/src/usage-analyzer.cc       Thu Jul 30 04:53:29 2009
+++ /branches/bleeding_edge/src/usage-analyzer.cc       Tue Sep 29 06:28:30 2009
@@ -75,7 +75,6 @@
    void VisitThrow(Throw* node);
    void VisitProperty(Property* node);
    void VisitCall(Call* node);
-  void VisitCallEval(CallEval* node);
    void VisitCallNew(CallNew* node);
    void VisitCallRuntime(CallRuntime* node);
    void VisitUnaryOperation(UnaryOperation* node);
@@ -327,11 +326,6 @@
    Read(node->expression());
    ReadList(node->arguments());
  }
-
-
-void UsageComputer::VisitCallEval(CallEval* node) {
-  VisitCall(node);
-}


  void UsageComputer::VisitCallNew(CallNew* node) {
=======================================
--- /branches/bleeding_edge/src/variables.h     Mon Aug  3 03:59:00 2009
+++ /branches/bleeding_edge/src/variables.h     Tue Sep 29 06:28:30 2009
@@ -171,7 +171,7 @@
    UseCount* var_uses()  { return &var_uses_; }
    UseCount* obj_uses()  { return &obj_uses_; }

-  bool IsVariable(Handle<String> n) {
+  bool IsVariable(Handle<String> n) const {
      return !is_this() && name().is_identical_to(n);
    }

@@ -184,6 +184,12 @@
    bool is_global() const;
    bool is_this() const { return kind_ == THIS; }
    bool is_arguments() const { return kind_ == ARGUMENTS; }
+
+  // True if the variable is named eval and not known to be shadowed.
+  bool is_possibly_eval() const {
+    return IsVariable(Factory::eval_symbol()) &&
+        (mode_ == DYNAMIC || mode_ == DYNAMIC_GLOBAL);
+  }

    Variable* local_if_not_shadowed() const {
      ASSERT(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL);
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Sep 28 05:01:05 2009
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Sep 29 06:28:30 2009
@@ -2704,8 +2704,65 @@
    // 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());
+    __ movq(scratch.reg(),
+            FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(0)));
+    frame_->SetElementAt(arg_count + 1, &scratch);
+
+    // We can reuse the result register now.
+    frame_->Spill(result.reg());
+    __ movq(result.reg(),
+            FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(1)));
+    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
      // ----------------------------------

@@ -2731,6 +2788,7 @@
      frame_->RestoreContextRegister();
      // Replace the function on the stack with the result.
      frame_->SetElementAt(0, &result);
+
    } else if (var != NULL && var->slot() != NULL &&
               var->slot()->type() == Slot::LOOKUP) {
      // ----------------------------------
@@ -2757,6 +2815,7 @@

      // Call the function.
      CallWithArguments(args, node->position());
+
    } else if (property != NULL) {
      // Check if the key is a literal string.
      Literal* literal = property->key()->AsLiteral();
@@ -2822,6 +2881,7 @@
        // Call the function.
        CallWithArguments(args, node->position());
      }
+
    } else {
      // ----------------------------------
      // JavaScript example: 'foo(1, 2, 3)'  // foo is not global
@@ -2837,65 +2897,6 @@
      CallWithArguments(args, node->position());
    }
  }
-
-
-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());
-  __ movq(scratch.reg(),
-          FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(0)));
-  frame_->SetElementAt(arg_count + 1, &scratch);
-
-  // We can reuse the result register now.
-  frame_->Spill(result.reg());
-  __ movq(result.reg(),
-          FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(1)));
-  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::VisitCallNew(CallNew* node) {

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to