8134865: Need to restore for container block from lexical context in finally
authoraw
Tue, 01 Sep 2015 18:19:29 +0200
changeset 32437 153cb8aeb422
parent 32436 a6328e0a8dd6
child 32438 58a722811c59
8134865: Need to restore for container block from lexical context in finally Reviewed-by: attila, mhaupt
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
nashorn/test/script/basic/JDK-8134865.js
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Tue Sep 01 18:28:11 2015 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Tue Sep 01 18:19:29 2015 +0200
@@ -716,7 +716,7 @@
 
         restoreBlock(body);
         body.setFlag(Block.NEEDS_SCOPE);
-        final Block programBody = new Block(functionToken, functionLine, body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
+        final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
         lc.pop(script);
         script.setLastToken(token);
 
@@ -1216,11 +1216,10 @@
         final long forToken = token;
         final int forLine = line;
         // start position of this for statement. This is used
-        // for sort order for variables declared in the initialzer
+        // for sort order for variables declared in the initializer
         // part of this 'for' statement (if any).
         final int forStart = Token.descPosition(forToken);
         // When ES6 for-let is enabled we create a container block to capture the LET.
-        final int startLine = start;
         final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
 
         // Create FOR node, capturing FOR token.
@@ -1341,22 +1340,24 @@
             body = getStatement();
         } finally {
             lc.pop(forNode);
-        }
-
-        if (vars != null) {
-            for (final VarNode var : vars) {
-                appendStatement(var);
+
+            if (vars != null) {
+                for (final VarNode var : vars) {
+                    appendStatement(var);
+                }
+            }
+            if (body != null) {
+                appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
             }
-        }
-        if (body != null) {
-            appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
-        }
-        if (outer != null) {
-            restoreBlock(outer);
-            appendStatement(new BlockStatement(startLine, new Block(
-                    outer.getToken(),
-                    body.getFinish(),
-                    outer.getStatements())));
+            if (outer != null) {
+                restoreBlock(outer);
+                if (body != null) {
+                    appendStatement(new BlockStatement(forLine, new Block(
+                                    outer.getToken(),
+                                    body.getFinish(),
+                                    outer.getStatements())));
+                }
+            }
         }
     }
 
@@ -2053,13 +2054,13 @@
         // LBRACKET tested in caller.
         next();
 
-        // Prepare to accummulating elements.
+        // Prepare to accumulate elements.
         final List<Expression> elements = new ArrayList<>();
         // Track elisions.
         boolean elision = true;
 loop:
         while (true) {
-             switch (type) {
+            switch (type) {
             case RBRACKET:
                 next();
 
@@ -2284,7 +2285,7 @@
                 }
             }
 
-            propertyName =  createIdentNode(propertyToken, finish, ident).setIsPropertyName();
+            propertyName = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
         } else {
             propertyName = propertyName();
         }
@@ -2553,7 +2554,7 @@
             final long callToken = token;
 
             switch (type) {
-            case LBRACKET:
+            case LBRACKET: {
                 next();
 
                 // Get array index.
@@ -2565,8 +2566,8 @@
                 lhs = new IndexNode(callToken, finish, lhs, index);
 
                 break;
-
-            case PERIOD:
+            }
+            case PERIOD: {
                 if (lhs == null) {
                     throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
                 }
@@ -2579,7 +2580,7 @@
                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
 
                 break;
-
+            }
             default:
                 break loop;
             }
@@ -3107,15 +3108,6 @@
         return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
     }
 
-    /*
-     * parse LHS [a, b, ..., c].
-     *
-     * JavaScript 1.8.
-     */
-    //private Node destructureExpression() {
-    //    return null;
-    //}
-
     /**
      * PostfixExpression :
      *      LeftHandSideExpression
@@ -3127,7 +3119,7 @@
      * UnaryExpression :
      *      PostfixExpression
      *      delete UnaryExpression
-     *      Node UnaryExpression
+     *      void UnaryExpression
      *      typeof UnaryExpression
      *      ++ UnaryExpression
      *      -- UnaryExpression
@@ -3333,7 +3325,6 @@
         // This method is protected so that subclass can get details
         // at expression start point!
 
-        // TODO - Destructuring array.
         // Include commas in expression parsing.
         return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
     }
@@ -3407,7 +3398,6 @@
         // This method is protected so that subclass can get details
         // at assignment expression start point!
 
-        // TODO - Handle decompose.
         // Exclude commas in expression parsing.
         return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8134865.js	Tue Sep 01 18:19:29 2015 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8134865: Need to restore for container block from lexical context in finally
+ *
+ * @test
+ * @option --language=es6
+ */
+
+try {
+  eval("function f() { for (x : y) { } }");
+  throw "should not reach here";
+} catch (e) {
+  if (!(e instanceof SyntaxError)) throw e;
+}