Revision: 7561
Author:   [email protected]
Date:     Fri Apr  8 07:30:10 2011
Log:      Strict mode fixes.
- mutual inlining strict and non-strict functions in crankshaft.
- assignment to undefined variable with eval in scope.
- propagation of strict mode through lazy compilation.

BUG=
TEST=test/mjsunit/strict-mode.js test/mjsunit/strict-mode-opt.js

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

Added:
 /branches/bleeding_edge/test/mjsunit/strict-mode-opt.js
Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h
 /branches/bleeding_edge/test/mjsunit/strict-mode.js

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/strict-mode-opt.js Fri Apr 8 07:30:10 2011
@@ -0,0 +1,98 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var global = 0;
+var MAX = 1000000;
+
+// Attempt to inline strcit in non-strict.
+
+function strictToBeInlined(n) {
+  "use strict";
+  global = "strict";
+  if (n == MAX) { undefined_variable_strict = "value"; }
+}
+
+function nonstrictCallStrict(n) {
+  strictToBeInlined(n);
+}
+
+(function testInlineStrictInNonStrict() {
+  for (var i = 0; i <= MAX; i ++) {
+    try {
+      nonstrictCallStrict(i);
+    } catch (e) {
+      assertInstanceof(e, ReferenceError);
+      assertEquals(MAX, i);
+      return;
+    }
+  }
+  fail("ReferenceError after MAX iterations", "no exception");
+})();
+
+// Attempt to inline non-strict in strict.
+
+function nonstrictToBeInlined(n) {
+  global = "nonstrict";
+  if (n == MAX) { undefined_variable_nonstrict = "The nonstrict value"; }
+}
+
+function strictCallNonStrict(n) {
+  "use strict";
+  nonstrictToBeInlined(n);
+}
+
+(function testInlineNonStrictInStrict() {
+  for (var i = 0; i <= MAX; i ++) {
+    try {
+      strictCallNonStrict(i);
+    } catch (e) {
+      fail("no exception", "exception");
+    }
+  }
+  assertEquals("The nonstrict value", undefined_variable_nonstrict);
+})();
+
+// Optimize strict function.
+
+function strictAssignToUndefined(n) {
+  "use strict";
+  global = "strict";
+  if (n == MAX) { undefined_variable_strict_2 = "value"; }
+}
+
+(function testOptimizeStrictAssignToUndefined() {
+  for (var i = 0; i <= MAX; i ++) {
+    try {
+      strictAssignToUndefined(i);
+    } catch (e) {
+      assertInstanceof(e, ReferenceError);
+      assertEquals(MAX, i);
+      return;
+    }
+  }
+  fail("ReferenceError after MAX iterations", "no exception");
+})();
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Mon Apr  4 08:03:34 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Fri Apr  8 07:30:10 2011
@@ -1309,6 +1309,7 @@
   LOperand* global_object() { return InputAt(0); }
   Handle<Object> name() const { return hydrogen()->name(); }
   LOperand* value() { return InputAt(1); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1639,6 +1640,7 @@
   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
   Handle<Object> name() const { return hydrogen()->name(); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1678,6 +1680,7 @@
   LOperand* object() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };

class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Apr 7 08:01:20 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Apr 8 07:30:10 2011
@@ -2242,7 +2242,9 @@
   ASSERT(ToRegister(instr->value()).is(r0));

   __ mov(r2, Operand(instr->name()));
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
+  Handle<Code> ic = instr->strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
 }

@@ -3134,7 +3136,7 @@

   // Name is always in r2.
   __ mov(r2, Operand(instr->name()));
-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3222,7 +3224,7 @@
   ASSERT(ToRegister(instr->key()).is(r1));
   ASSERT(ToRegister(instr->value()).is(r0));

-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
=======================================
--- /branches/bleeding_edge/src/ast.h   Thu Apr  7 07:45:34 2011
+++ /branches/bleeding_edge/src/ast.h   Fri Apr  8 07:30:10 2011
@@ -1728,7 +1728,6 @@
   int start_position_;
   int end_position_;
   bool is_expression_;
-  bool strict_mode_;
   int function_token_position_;
   Handle<String> inferred_name_;
   bool pretenure_;
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Fri Apr  8 04:25:19 2011
+++ /branches/bleeding_edge/src/compiler.cc     Fri Apr  8 07:30:10 2011
@@ -603,6 +603,12 @@
     // rest of the function into account to avoid overlap with the lazy
     // parsing statistics.
     HistogramTimerScope timer(isolate->counters()->compile_lazy());
+
+    // After parsing we know function's strict mode. Remember it.
+    if (info->function()->strict_mode()) {
+      shared->set_strict_mode(true);
+      info->MarkAsStrictMode();
+    }

     // Compile the code.
     if (!MakeCode(info)) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Thu Apr 7 23:54:50 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Apr 8 07:30:10 2011
@@ -2910,8 +2910,10 @@
   HStoreGlobalGeneric(HValue* context,
                       HValue* global_object,
                       Handle<Object> name,
-                      HValue* value)
-      : name_(name) {
+                      HValue* value,
+                      bool strict_mode)
+      : name_(name),
+        strict_mode_(strict_mode) {
     SetOperandAt(0, context);
     SetOperandAt(1, global_object);
     SetOperandAt(2, value);
@@ -2923,6 +2925,7 @@
   HValue* global_object() { return OperandAt(1); }
   Handle<Object> name() const { return name_; }
   HValue* value() { return OperandAt(2); }
+  bool strict_mode() { return strict_mode_; }

   virtual void PrintDataTo(StringStream* stream);

@@ -2934,6 +2937,7 @@

  private:
   Handle<Object> name_;
+  bool strict_mode_;
 };


@@ -3265,8 +3269,10 @@
   HStoreNamedGeneric(HValue* context,
                      HValue* object,
                      Handle<String> name,
-                     HValue* value)
-      : name_(name) {
+                     HValue* value,
+                     bool strict_mode)
+      : name_(name),
+        strict_mode_(strict_mode) {
     SetOperandAt(0, object);
     SetOperandAt(1, value);
     SetOperandAt(2, context);
@@ -3277,6 +3283,7 @@
   HValue* value() { return OperandAt(1); }
   HValue* context() { return OperandAt(2); }
   Handle<String> name() { return name_; }
+  bool strict_mode() { return strict_mode_; }

   virtual void PrintDataTo(StringStream* stream);

@@ -3288,6 +3295,7 @@

  private:
   Handle<String> name_;
+  bool strict_mode_;
 };


@@ -3365,7 +3373,9 @@
   HStoreKeyedGeneric(HValue* context,
                      HValue* object,
                      HValue* key,
-                     HValue* value) {
+                     HValue* value,
+                     bool strict_mode)
+      : strict_mode_(strict_mode) {
     SetOperandAt(0, object);
     SetOperandAt(1, key);
     SetOperandAt(2, value);
@@ -3377,6 +3387,7 @@
   HValue* key() { return OperandAt(1); }
   HValue* value() { return OperandAt(2); }
   HValue* context() { return OperandAt(3); }
+  bool strict_mode() { return strict_mode_; }

   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
@@ -3385,6 +3396,9 @@
   virtual void PrintDataTo(StringStream* stream);

   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
+
+ private:
+  bool strict_mode_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Apr  7 07:45:34 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Apr  8 07:30:10 2011
@@ -2981,7 +2981,12 @@
             HValue* value = Pop();
             Handle<String> name = Handle<String>::cast(key->handle());
             HStoreNamedGeneric* store =
- new(zone()) HStoreNamedGeneric(context, literal, name, value);
+                new(zone()) HStoreNamedGeneric(
+                                context,
+                                literal,
+                                name,
+                                value,
+                                function_strict_mode());
             AddInstruction(store);
             AddSimulate(key->id());
           } else {
@@ -3122,7 +3127,12 @@
                                                     HValue* value) {
   HContext* context = new(zone()) HContext;
   AddInstruction(context);
-  return new(zone()) HStoreNamedGeneric(context, object, name, value);
+  return new(zone()) HStoreNamedGeneric(
+                         context,
+                         object,
+                         name,
+                         value,
+                         function_strict_mode());
 }


@@ -3300,7 +3310,8 @@
         new(zone()) HStoreGlobalGeneric(context,
                                         global_object,
                                         var->name(),
-                                        value);
+                                        value,
+                                        function_strict_mode());
     instr->set_position(position);
     AddInstruction(instr);
     ASSERT(instr->HasSideEffects());
@@ -3628,7 +3639,12 @@
                                                     HValue* value) {
   HContext* context = new(zone()) HContext;
   AddInstruction(context);
-  return new(zone()) HStoreKeyedGeneric(context, object, key, value);
+  return new(zone()) HStoreKeyedGeneric(
+                         context,
+                         object,
+                         key,
+                         value,
+                         function_strict_mode());
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Thu Apr  7 02:51:25 2011
+++ /branches/bleeding_edge/src/hydrogen.h      Fri Apr  8 07:30:10 2011
@@ -709,6 +709,9 @@
   void ClearInlinedTestContext() {
     function_state()->ClearInlinedTestContext();
   }
+  bool function_strict_mode() {
+    return function_state()->compilation_info()->is_strict_mode();
+  }

   // Generators for inline runtime functions.
 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize)      \
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Apr 7 06:32:45 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Apr 8 07:30:10 2011
@@ -2108,7 +2108,9 @@
   ASSERT(ToRegister(instr->value()).is(eax));

   __ mov(ecx, instr->name());
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
+  Handle<Code> ic = instr->strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED);
 }

@@ -2997,7 +2999,7 @@
   ASSERT(ToRegister(instr->value()).is(eax));

   __ mov(ecx, instr->name());
-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
@@ -3097,7 +3099,7 @@
   ASSERT(ToRegister(instr->key()).is(ecx));
   ASSERT(ToRegister(instr->value()).is(eax));

-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Mon Apr  4 08:03:34 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Fri Apr  8 07:30:10 2011
@@ -1346,6 +1346,7 @@
   LOperand* global_object() { return InputAt(1); }
   Handle<Object> name() const { return hydrogen()->name(); }
   LOperand* value() { return InputAt(2); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1694,6 +1695,7 @@
   LOperand* object() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
   Handle<Object> name() const { return hydrogen()->name(); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1755,6 +1757,7 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)

   virtual void PrintDataTo(StringStream* stream);

@@ -1762,6 +1765,7 @@
   LOperand* object() { return inputs_[1]; }
   LOperand* key() { return inputs_[2]; }
   LOperand* value() { return inputs_[3]; }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


=======================================
--- /branches/bleeding_edge/src/runtime.cc      Wed Apr  6 10:54:39 2011
+++ /branches/bleeding_edge/src/runtime.cc      Fri Apr  8 07:30:10 2011
@@ -7820,8 +7820,17 @@
     // The property exists in the extension context.
     context_ext = Handle<JSObject>::cast(holder);
   } else {
- // The property was not found. It needs to be stored in the global context.
+    // The property was not found.
     ASSERT(attributes == ABSENT);
+
+    if (strict_mode == kStrictMode) {
+      // Throw in strict mode (assignment to undefined variable).
+      Handle<Object> error =
+        isolate->factory()->NewReferenceError(
+            "not_defined", HandleVector(&name, 1));
+      return isolate->Throw(*error);
+    }
+    // In non-strict mode, the property is stored in the global context.
     attributes = NONE;
     context_ext = Handle<JSObject>(isolate->context()->global());
   }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Apr 7 06:32:45 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Apr 8 07:30:10 2011
@@ -2115,7 +2115,9 @@
   ASSERT(ToRegister(instr->value()).is(rax));

   __ Move(rcx, instr->name());
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
+  Handle<Code> ic = instr->strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
 }

@@ -2979,7 +2981,7 @@
   ASSERT(ToRegister(instr->value()).is(rax));

   __ Move(rcx, instr->hydrogen()->name());
-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3075,7 +3077,7 @@
   ASSERT(ToRegister(instr->key()).is(rcx));
   ASSERT(ToRegister(instr->value()).is(rax));

-  Handle<Code> ic = info_->is_strict_mode()
+  Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Mon Apr  4 08:03:34 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Fri Apr  8 07:30:10 2011
@@ -1295,6 +1295,7 @@
   LOperand* global_object() { return InputAt(0); }
   Handle<Object> name() const { return hydrogen()->name(); }
   LOperand* value() { return InputAt(1); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1616,6 +1617,7 @@
   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
   Handle<Object> name() const { return hydrogen()->name(); }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


@@ -1671,12 +1673,14 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)

   virtual void PrintDataTo(StringStream* stream);

   LOperand* object() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
+  bool strict_mode() { return hydrogen()->strict_mode(); }
 };


=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode.js Sun Mar 27 23:11:08 2011 +++ /branches/bleeding_edge/test/mjsunit/strict-mode.js Fri Apr 8 07:30:10 2011
@@ -387,10 +387,9 @@
   testFutureReservedWord(future_reserved_words[i]);
 }

-function testAssignToUndefined(should_throw) {
-  "use strict";
+function testAssignToUndefined(test, should_throw) {
   try {
-    possibly_undefined_variable_for_strict_mode_test = "should throw?";
+    test();
   } catch (e) {
     assertTrue(should_throw, "strict mode");
     assertInstanceof(e, ReferenceError, "strict mode");
@@ -399,33 +398,78 @@
   assertFalse(should_throw, "strict mode");
 }

-testAssignToUndefined(true);
-testAssignToUndefined(true);
-testAssignToUndefined(true);
+function repeat(n, f) {
+  for (var i = 0; i < n; i ++) { f(); }
+}
+
+function assignToUndefined() {
+  "use strict";
+  possibly_undefined_variable_for_strict_mode_test = "should throw?";
+}
+
+testAssignToUndefined(assignToUndefined, true);
+testAssignToUndefined(assignToUndefined, true);
+testAssignToUndefined(assignToUndefined, true);

 possibly_undefined_variable_for_strict_mode_test = "value";

-testAssignToUndefined(false);
-testAssignToUndefined(false);
-testAssignToUndefined(false);
+testAssignToUndefined(assignToUndefined, false);
+testAssignToUndefined(assignToUndefined, false);
+testAssignToUndefined(assignToUndefined, false);

 delete possibly_undefined_variable_for_strict_mode_test;

-testAssignToUndefined(true);
-testAssignToUndefined(true);
-testAssignToUndefined(true);
-
-function repeat(n, f) {
- for (var i = 0; i < n; i ++) { f(); }
-}
-
-repeat(10, function() { testAssignToUndefined(true); });
+testAssignToUndefined(assignToUndefined, true);
+testAssignToUndefined(assignToUndefined, true);
+testAssignToUndefined(assignToUndefined, true);
+
+repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
 possibly_undefined_variable_for_strict_mode_test = "value";
-repeat(10, function() { testAssignToUndefined(false); });
+repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
 delete possibly_undefined_variable_for_strict_mode_test;
-repeat(10, function() { testAssignToUndefined(true); });
+repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
 possibly_undefined_variable_for_strict_mode_test = undefined;
-repeat(10, function() { testAssignToUndefined(false); });
+repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
+
+function assignToUndefinedWithEval() {
+  "use strict";
+ possibly_undefined_variable_for_strict_mode_test_with_eval = "should throw?";
+  eval("");
+}
+
+testAssignToUndefined(assignToUndefinedWithEval, true);
+testAssignToUndefined(assignToUndefinedWithEval, true);
+testAssignToUndefined(assignToUndefinedWithEval, true);
+
+possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
+
+testAssignToUndefined(assignToUndefinedWithEval, false);
+testAssignToUndefined(assignToUndefinedWithEval, false);
+testAssignToUndefined(assignToUndefinedWithEval, false);
+
+delete possibly_undefined_variable_for_strict_mode_test_with_eval;
+
+testAssignToUndefined(assignToUndefinedWithEval, true);
+testAssignToUndefined(assignToUndefinedWithEval, true);
+testAssignToUndefined(assignToUndefinedWithEval, true);
+
+repeat(10, function() {
+             testAssignToUndefined(assignToUndefinedWithEval, true);
+           });
+possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
+repeat(10, function() {
+             testAssignToUndefined(assignToUndefinedWithEval, false);
+           });
+delete possibly_undefined_variable_for_strict_mode_test_with_eval;
+repeat(10, function() {
+             testAssignToUndefined(assignToUndefinedWithEval, true);
+           });
+possibly_undefined_variable_for_strict_mode_test_with_eval = undefined;
+repeat(10, function() {
+             testAssignToUndefined(assignToUndefinedWithEval, false);
+           });
+
+

 (function testDeleteNonConfigurable() {
   function delete_property(o) {

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

Reply via email to