Reviewers: rossberg, Dan Ehrenberg,

Message:
Andreas: PTAL.
Dan: FYI.

Description:
[turbofan] Fix broken dynamic TDZ check for let and const.

This fixes broken dynamic hole-checks for the temporal dead zone of
non-initializing assignments to {let} and {const} declared variables.
Also note that this exemplifies a case where the dynamic check for such
assignments to {let} declared variables can no longer be elided as the
comment suggested.

[email protected]
TEST=mjsunit/regress/regress-4388
BUG=v8:4388
LOG=n

Please review this at https://codereview.chromium.org/1318693002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+37, -5 lines):
  M src/compiler/ast-graph-builder.cc
  A test/mjsunit/regress/regress-4388.js


Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index e6acf4d157e35986d402e5f37bca597594946ae6..23305961d6bfd125fee2eb02b489f72038dc4c35 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -3505,13 +3505,10 @@ Node* AstGraphBuilder::BuildVariableAssignment(
         return value;
       } else if (mode == LET && op != Token::INIT_LET) {
         // Perform an initialization check for let declared variables.
- // Also note that the dynamic hole-check is only done to ensure that
-        // this does not break in the presence of do-expressions within the
-        // temporal dead zone of a let declared variable.
         Node* current = environment()->Lookup(variable);
         if (current->op() == the_hole->op()) {
           value = BuildThrowReferenceError(variable, bailout_id);
-        } else if (value->opcode() == IrOpcode::kPhi) {
+        } else if (current->opcode() == IrOpcode::kPhi) {
value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
         }
       } else if (mode == CONST && op == Token::INIT_CONST) {
@@ -3527,7 +3524,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(
         Node* current = environment()->Lookup(variable);
         if (current->op() == the_hole->op()) {
           return BuildThrowReferenceError(variable, bailout_id);
-        } else if (value->opcode() == IrOpcode::kPhi) {
+        } else if (current->opcode() == IrOpcode::kPhi) {
           BuildHoleCheckThenThrow(current, variable, value, bailout_id);
         }
         return BuildThrowConstAssignError(bailout_id);
Index: test/mjsunit/regress/regress-4388.js
diff --git a/test/mjsunit/regress/regress-4388.js b/test/mjsunit/regress/regress-4388.js
new file mode 100644
index 0000000000000000000000000000000000000000..908bcccb4e0ed4614223b77908a94897e42df533
--- /dev/null
+++ b/test/mjsunit/regress/regress-4388.js
@@ -0,0 +1,35 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --turbo-filter=test*
+
+// Tests that TurboFan emits a dynamic hole-check for the temporal dead zone at
+// a non-initializing assignments to a {let} variable.
+function test_hole_check_for_let(a) {
+  'use strict';
+  { switch (a) {
+      case 0: let x;
+      case 1: x = 9;
+    }
+  }
+}
+assertDoesNotThrow("test_hole_check_for_let(0)");
+assertThrows("test_hole_check_for_let(1)", ReferenceError);
+%OptimizeFunctionOnNextCall(test_hole_check_for_let)
+assertThrows("test_hole_check_for_let(1)", ReferenceError);
+
+// Tests that TurboFan emits a dynamic hole-check for the temporal dead zone at
+// a non-initializing assignments to a {const} variable.
+function test_hole_check_for_const(a) {
+  'use strict';
+  { switch (a) {
+      case 0: const x = 3;
+      case 1: x = 2;
+    }
+  }
+}
+assertThrows("test_hole_check_for_const(0)", TypeError);
+assertThrows("test_hole_check_for_const(1)", ReferenceError);
+%OptimizeFunctionOnNextCall(test_hole_check_for_const)
+assertThrows("test_hole_check_for_const(1)", ReferenceError);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to