Revision: 6745
Author: [email protected]
Date: Fri Feb 11 03:57:11 2011
Log: Fix the semantics of delete on parameters.

Before, an attempt to delete a parameter in a function that used the
arguments object in any way would succeed with true and delete both
the parameter and the corresponding arguments object property.

Now, an attempt to delete such a parameter does not delete and
evaluates to false.

Parameters can be deleted, as before, from functions that use the
arguments object, by deleting the corresponding arguments object
property (this is a spec violation).

BUG=fixes v8:1136

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

Modified:
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Feb 10 12:04:54 2011 +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Feb 11 03:57:11 2011
@@ -3053,26 +3053,30 @@
         // Result of deleting non-global, non-dynamic variables is false.
         // The subexpression does not have side effects.
         context()->Plug(false);
-      } else {
-        // Property or variable reference.  Call the delete builtin with
-        // object and property name as arguments.
-        if (prop != NULL) {
+      } else if (prop != NULL) {
+        if (prop->is_synthetic()) {
+          // Result of deleting parameters is false, even when they rewrite
+          // to accesses on the arguments object.
+          context()->Plug(false);
+        } else {
           VisitForStackValue(prop->obj());
           VisitForStackValue(prop->key());
           __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
-        } else if (var->is_global()) {
-          __ ldr(r1, GlobalObjectOperand());
-          __ mov(r0, Operand(var->name()));
-          __ Push(r1, r0);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
-        } else {
-          // Non-global variable.  Call the runtime to delete from the
-          // context where the variable was introduced.
-          __ push(context_register());
-          __ mov(r2, Operand(var->name()));
-          __ push(r2);
-          __ CallRuntime(Runtime::kDeleteContextSlot, 2);
-        }
+          context()->Plug(r0);
+        }
+      } else if (var->is_global()) {
+        __ ldr(r1, GlobalObjectOperand());
+        __ mov(r0, Operand(var->name()));
+        __ Push(r1, r0);
+        __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
+        context()->Plug(r0);
+      } else {
+        // Non-global variable.  Call the runtime to try to delete from the
+        // context where the variable was introduced.
+        __ push(context_register());
+        __ mov(r2, Operand(var->name()));
+        __ push(r2);
+        __ CallRuntime(Runtime::kDeleteContextSlot, 2);
         context()->Plug(r0);
       }
       break;
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Feb 10 04:02:36 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Feb 11 03:57:11 2011
@@ -4653,12 +4653,18 @@
       // The subexpression does not have side effects.
       ast_context()->ReturnValue(graph()->GetConstantFalse());
     } else if (prop != NULL) {
-      VISIT_FOR_VALUE(prop->obj());
-      VISIT_FOR_VALUE(prop->key());
-      HValue* key = Pop();
-      HValue* obj = Pop();
-      ast_context()->ReturnInstruction(new HDeleteProperty(obj, key),
-                                       expr->id());
+      if (prop->is_synthetic()) {
+        // Result of deleting parameters is false, even when they rewrite
+        // to accesses on the arguments object.
+        ast_context()->ReturnValue(graph()->GetConstantFalse());
+      } else {
+        VISIT_FOR_VALUE(prop->obj());
+        VISIT_FOR_VALUE(prop->key());
+        HValue* key = Pop();
+        HValue* obj = Pop();
+        HDeleteProperty* instr = new HDeleteProperty(obj, key);
+        ast_context()->ReturnInstruction(instr, expr->id());
+      }
     } else if (var->is_global()) {
       BAILOUT("delete with global variable");
     } else {
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Feb 10 01:00:50 2011 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Feb 11 03:57:11 2011
@@ -3721,24 +3721,28 @@
         // Result of deleting non-global, non-dynamic variables is false.
         // The subexpression does not have side effects.
         context()->Plug(false);
-      } else {
-        // Property or variable reference.  Call the delete builtin with
-        // object and property name as arguments.
-        if (prop != NULL) {
+      } else if (prop != NULL) {
+        if (prop->is_synthetic()) {
+          // Result of deleting parameters is false, even when they rewrite
+          // to accesses on the arguments object.
+          context()->Plug(false);
+        } else {
           VisitForStackValue(prop->obj());
           VisitForStackValue(prop->key());
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
-        } else if (var->is_global()) {
-          __ push(GlobalObjectOperand());
-          __ push(Immediate(var->name()));
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
-        } else {
-          // Non-global variable.  Call the runtime to delete from the
-          // context where the variable was introduced.
-          __ push(context_register());
-          __ push(Immediate(var->name()));
-          __ CallRuntime(Runtime::kDeleteContextSlot, 2);
-        }
+          context()->Plug(eax);
+        }
+      } else if (var->is_global()) {
+        __ push(GlobalObjectOperand());
+        __ push(Immediate(var->name()));
+        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        context()->Plug(eax);
+      } else {
+        // Non-global variable.  Call the runtime to try to delete from the
+        // context where the variable was introduced.
+        __ push(context_register());
+        __ push(Immediate(var->name()));
+        __ CallRuntime(Runtime::kDeleteContextSlot, 2);
         context()->Plug(eax);
       }
       break;
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Feb 9 06:51:38 2011 +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Feb 11 03:57:11 2011
@@ -3060,24 +3060,28 @@
         // Result of deleting non-global, non-dynamic variables is false.
         // The subexpression does not have side effects.
         context()->Plug(false);
-      } else {
-        // Property or variable reference.  Call the delete builtin with
-        // object and property name as arguments.
-        if (prop != NULL) {
+      } else if (prop != NULL) {
+        if (prop->is_synthetic()) {
+          // Result of deleting parameters is false, even when they rewrite
+          // to accesses on the arguments object.
+          context()->Plug(false);
+        } else {
           VisitForStackValue(prop->obj());
           VisitForStackValue(prop->key());
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
-        } else if (var->is_global()) {
-          __ push(GlobalObjectOperand());
-          __ Push(var->name());
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
-        } else {
-          // Non-global variable.  Call the runtime to delete from the
-          // context where the variable was introduced.
-          __ push(context_register());
-          __ Push(var->name());
-          __ CallRuntime(Runtime::kDeleteContextSlot, 2);
-        }
+          context()->Plug(rax);
+        }
+      } else if (var->is_global()) {
+        __ push(GlobalObjectOperand());
+        __ Push(var->name());
+        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        context()->Plug(rax);
+      } else {
+        // Non-global variable.  Call the runtime to try to delete from the
+        // context where the variable was introduced.
+        __ push(context_register());
+        __ Push(var->name());
+        __ CallRuntime(Runtime::kDeleteContextSlot, 2);
         context()->Plug(rax);
       }
       break;

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

Reply via email to