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.