8055042: Compile-time expression evaluator was missing variables
authorattila
Thu, 14 Aug 2014 14:35:44 +0200
changeset 26064 8c8604a11c57
parent 26063 98eee061a92a
child 26065 d15adb218527
8055042: Compile-time expression evaluator was missing variables Reviewed-by: jlaskey, lagergren
nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java
nashorn/src/jdk/nashorn/internal/codegen/TypeEvaluator.java
--- a/nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Aug 13 21:03:37 2014 +0530
+++ b/nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Thu Aug 14 14:35:44 2014 +0200
@@ -382,10 +382,6 @@
             symbol.setFlags(flags);
         }
 
-        if((isVar || isParam) && compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
-            compiler.declareLocalSymbol(name);
-        }
-
         return symbol;
     }
 
@@ -688,6 +684,22 @@
     }
 
     @Override
+    public Node leaveBlock(final Block block) {
+        // It's not necessary to guard the marking of symbols as locals with this "if"condition for correctness, it's
+        // just an optimization -- runtime type calculation is not used when the compilation is not an on-demand
+        // optimistic compilation, so we can skip locals marking then.
+        if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
+            for (final Symbol symbol: block.getSymbols()) {
+                if (!symbol.isScope()) {
+                    assert symbol.isVar() || symbol.isParam();
+                    compiler.declareLocalSymbol(symbol.getName());
+                }
+            }
+        }
+        return block;
+    }
+
+    @Override
     public Node leaveDELETE(final UnaryNode unaryNode) {
         final FunctionNode currentFunctionNode = lc.getCurrentFunction();
         final boolean      strictMode          = currentFunctionNode.isStrict();
--- a/nashorn/src/jdk/nashorn/internal/codegen/TypeEvaluator.java	Wed Aug 13 21:03:37 2014 +0530
+++ b/nashorn/src/jdk/nashorn/internal/codegen/TypeEvaluator.java	Thu Aug 14 14:35:44 2014 +0200
@@ -115,6 +115,14 @@
         return Type.typeFor(JSType.unboxedFieldType(value));
     }
 
+    /**
+     * Declares a symbol name as belonging to a non-scoped local variable during an on-demand compilation of a single
+     * function. This method will add an explicit Undefined binding for the local into the runtime scope if it's
+     * otherwise implicitly undefined so that when an expression is evaluated for the name, it won't accidentally find
+     * an unrelated value higher up the scope chain. It is only required to call this method when doing an optimistic
+     * on-demand compilation.
+     * @param symbolName the name of the symbol that is to be declared as being a non-scoped local variable.
+     */
     void declareLocalSymbol(final String symbolName) {
         assert
             compiler.useOptimisticTypes() &&