Revision: 3204
Author: [email protected]
Date: Tue Nov  3 04:47:19 2009
Log: Fix a latent bug in the top-level compilation of function calls.

Calls to a non-global variable would go through the "call to a global"
path, rather than the "call to an arbitrary (other) expression" path.

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

Modified:
  /branches/bleeding_edge/src/arm/fast-codegen-arm.cc
  /branches/bleeding_edge/src/compiler.cc
  /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc
  /branches/bleeding_edge/src/x64/fast-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov  2 07:01:06  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Tue Nov  3 04:47:19  
2009
@@ -769,30 +769,40 @@


  void FastCodeGenerator::VisitCall(Call* expr) {
+  Comment cmnt(masm_, "[ Call");
    Expression* fun = expr->expression();
    Variable* var = fun->AsVariableProxy()->AsVariable();

-  if (var != NULL &&
-      var->is_possibly_eval()) {
-    // Call to eval.
+  if (var != NULL && var->is_possibly_eval()) {
+    // Call to the identifier 'eval'.
+    UNREACHABLE();
+  } else if (var != NULL && !var->is_this() && var->is_global()) {
+    // Call to a global variable.
+    __ mov(r1, Operand(var->name()));
+    // Push global object as receiver for the call IC lookup.
+    __ ldr(r0, CodeGenerator::GlobalObject());
+    __ stm(db_w, sp, r1.bit() | r0.bit());
+    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
+  } else if (var != NULL && var->slot() != NULL &&
+             var->slot()->type() == Slot::LOOKUP) {
+    // Call to a lookup slot.
      UNREACHABLE();
    } else if (fun->AsProperty() != NULL) {
-    // Call on a property.
+    // Call to an object property.
      Property* prop = fun->AsProperty();
      Literal* key = prop->key()->AsLiteral();
      if (key != NULL && key->handle()->IsSymbol()) {
-      // Call on a named property: foo.x(1,2,3)
+      // Call to a named property, use call IC.
        __ mov(r0, Operand(key->handle()));
        __ push(r0);
        Visit(prop->obj());
-      // Use call IC.
        EmitCallWithIC(expr, RelocInfo::CODE_TARGET);
      } else {
-      // Call on a keyed property : foo[key](1,2,3)
-      // Use a keyed load IC followed by a call IC.
+      // Call to a keyed property, use keyed load IC followed by function
+      // call.
        Visit(prop->obj());
        Visit(prop->key());
-      // Record source position of property.
+      // Record source code position for IC call.
        SetSourcePosition(prop->position());
        Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
        __ Call(ic, RelocInfo::CODE_TARGET);
@@ -807,21 +817,8 @@
        __ str(r1, MemOperand(sp));
        EmitCallWithStub(expr);
      }
-  } else if (var != NULL) {
-    // Call on a global variable
-    ASSERT(var != NULL && !var->is_this() && var->is_global());
-    ASSERT(!var->is_possibly_eval());
-    __ mov(r1, Operand(var->name()));
-    // Push global object as receiver.
-    __ ldr(r0, CodeGenerator::GlobalObject());
-    __ stm(db_w, sp, r1.bit() | r0.bit());
-    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
-  } else if (var != NULL && var->slot() != NULL &&
-             var->slot()->type() == Slot::LOOKUP) {
-    // Call inside a with-statement
-    UNREACHABLE();
    } else {
-    // Call with an arbitrary function expression.
+    // Call to some other function expression.
      Visit(expr->expression());
      // Load global receiver object.
      __ ldr(r1, CodeGenerator::GlobalObject());
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Mon Nov  2 07:01:06 2009
+++ /branches/bleeding_edge/src/compiler.cc     Tue Nov  3 04:47:19 2009
@@ -800,18 +800,13 @@

    // Check for supported calls
    if (var != NULL && var->is_possibly_eval()) {
-    // ----------------------------------
-    // JavaScript example: 'eval(arg)'  // eval is not known to be shadowed
-    // ----------------------------------
-    BAILOUT("Call to a function named 'eval'");
+    BAILOUT("call to the identifier 'eval'");
    } else if (var != NULL && !var->is_this() && var->is_global()) {
-    // ----------------------------------
-    // JavaScript example: 'foo(1, 2, 3)'  // foo is global
-    // ----------------------------------
+    // Calls to global variables are supported.
+  } else if (var != NULL && var->slot() != NULL &&
+             var->slot()->type() == Slot::LOOKUP) {
+    BAILOUT("call to a lookup slot");
    } else if (fun->AsProperty() != NULL) {
-    // ------------------------------------------------------------------
-    // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
-    // ------------------------------------------------------------------
      Property* prop = fun->AsProperty();
      Literal* literal_key = prop->key()->AsLiteral();
      if (literal_key != NULL && literal_key->handle()->IsSymbol()) {
@@ -823,19 +818,11 @@
        ProcessExpression(prop->key(), Expression::kValue);
        CHECK_BAILOUT;
      }
-  } else if (var != NULL && var->slot() != NULL &&
-             var->slot()->type() == Slot::LOOKUP) {
-    // ----------------------------------
-    // JavaScript example: 'with (obj) foo(1, 2, 3)'  // foo is in obj
-    // ----------------------------------
-    BAILOUT("Call inside a with-statement");
    } else {
-    // ----------------------------------
-    // JavaScript example: 'foo(1, 2, 3)'  // foo is any expression, not  
global
-    // ----------------------------------
+    // Otherwise the call is supported if the function expression is.
      ProcessExpression(fun, Expression::kValue);
    }
-  // Check all arguments to the call.  (Relies on TEMP meaning STACK.)
+  // Check all arguments to the call.
    for (int i = 0; i < args->length(); i++) {
      ProcessExpression(args->at(i), Expression::kValue);
      CHECK_BAILOUT;
=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Mon Nov  2  
07:01:06 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Tue Nov  3  
04:47:19 2009
@@ -787,29 +787,38 @@


  void FastCodeGenerator::VisitCall(Call* expr) {
+  Comment cmnt(masm_, "[ Call");
    Expression* fun = expr->expression();
    Variable* var = fun->AsVariableProxy()->AsVariable();

-  if (var != NULL &&
-      var->is_possibly_eval()) {
-    // Call to eval.
+  if (var != NULL && var->is_possibly_eval()) {
+    // Call to the identifier 'eval'.
+    UNREACHABLE();
+  } else if (var != NULL && !var->is_this() && var->is_global()) {
+    // Call to a global variable.
+    __ push(Immediate(var->name()));
+    // Push global object as receiver for the call IC lookup.
+    __ push(CodeGenerator::GlobalObject());
+    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
+  } else if (var != NULL && var->slot() != NULL &&
+             var->slot()->type() == Slot::LOOKUP) {
+    // Call to a lookup slot.
      UNREACHABLE();
    } else if (fun->AsProperty() != NULL) {
-    // Call on a property.
+    // Call to an object property.
      Property* prop = fun->AsProperty();
      Literal* key = prop->key()->AsLiteral();
      if (key != NULL && key->handle()->IsSymbol()) {
-      // Call on a named property: foo.x(1,2,3)
+      // Call to a named property, use call IC.
        __ push(Immediate(key->handle()));
        Visit(prop->obj());
-      // Use call IC.
        EmitCallWithIC(expr, RelocInfo::CODE_TARGET);
      } else {
-      // Call on a keyed property: foo[key](1,2,3)
-      // Use a keyed load IC followed by a call IC.
+      // Call to a keyed property, use keyed load IC followed by function
+      // call.
        Visit(prop->obj());
        Visit(prop->key());
-      // Record source position of property.
+      // Record source code position for IC call.
        SetSourcePosition(prop->position());
        Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
        __ call(ic, RelocInfo::CODE_TARGET);
@@ -830,22 +839,8 @@
        }
        EmitCallWithStub(expr);
      }
-  } else if (var != NULL) {
-    // Call on a global variable
-    ASSERT(var != NULL);
-    ASSERT(!var->is_this());
-    ASSERT(var->is_global());
-    ASSERT(!var->is_possibly_eval());
-    __ push(Immediate(var->name()));
-    // Push global object (receiver).
-    __ push(CodeGenerator::GlobalObject());
-    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
-  } else if (var != NULL && var->slot() != NULL &&
-             var->slot()->type() == Slot::LOOKUP) {
-    // Call inside a with-statement
-    UNREACHABLE();
    } else {
-    // Call with an arbitrary function expression.
+    // Call to some other function expression.
      Visit(expr->expression());
      // Load global receiver object.
      __ mov(ebx, CodeGenerator::GlobalObject());
=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov  2 07:01:06  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Tue Nov  3 04:47:19  
2009
@@ -802,29 +802,38 @@


  void FastCodeGenerator::VisitCall(Call* expr) {
+  Comment cmnt(masm_, "[ Call");
    Expression* fun = expr->expression();
    Variable* var = fun->AsVariableProxy()->AsVariable();

-  if (var != NULL &&
-      var->is_possibly_eval()) {
-    // Call to eval.
+  if (var != NULL && var->is_possibly_eval()) {
+    // Call to the identifier 'eval'.
+    UNREACHABLE();
+  } else if (var != NULL && !var->is_this() && var->is_global()) {
+    // Call to a global variable.
+    __ Push(var->name());
+    // Push global object as receiver for the call IC lookup.
+    __ push(CodeGenerator::GlobalObject());
+    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
+  } else if (var != NULL && var->slot() != NULL &&
+             var->slot()->type() == Slot::LOOKUP) {
+    // Call to a lookup slot.
      UNREACHABLE();
    } else if (fun->AsProperty() != NULL) {
-    // Call on a property.
+    // Call to an object property.
      Property* prop = fun->AsProperty();
      Literal* key = prop->key()->AsLiteral();
      if (key != NULL && key->handle()->IsSymbol()) {
-      // Call on a named property: foo.x(1,2,3)
+      // Call to a named property, use call IC.
        __ Push(key->handle());
        Visit(prop->obj());
-      // Use call IC
        EmitCallWithIC(expr, RelocInfo::CODE_TARGET);
      } else {
-      // Call on a keyed property: foo[key](1,2,3)
-      // Use a keyed load IC followed by a call IC.
+      // Call to a keyed property, use keyed load IC followed by function
+      // call.
        Visit(prop->obj());
        Visit(prop->key());
-      // Record source position of property.
+      // Record source code position for IC call.
        SetSourcePosition(prop->position());
        Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
        __ call(ic, RelocInfo::CODE_TARGET);
@@ -845,20 +854,8 @@
        }
        EmitCallWithStub(expr);
      }
-  } else if (var != NULL) {
-    // Call on a global variable
-    ASSERT(var != NULL && !var->is_this() && var->is_global());
-    ASSERT(!var->is_possibly_eval());
-    __ Push(var->name());
-    // Push global object (receiver).
-    __ push(CodeGenerator::GlobalObject());
-    EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
-  } else if (var != NULL && var->slot() != NULL &&
-             var->slot()->type() == Slot::LOOKUP) {
-    // Call inside a with-statement
-    UNREACHABLE();
    } else {
-    // Call with an arbitrary function expression.
+    // Call to some other function expression.
      Visit(expr->expression());
      // Load global receiver object.
      __ movq(rbx, CodeGenerator::GlobalObject());

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

Reply via email to