8059842: Creating symbols for declared functions shouldn't be a special case

Mon, 13 Oct 2014 20:10:14 +0200

author
attila
date
Mon, 13 Oct 2014 20:10:14 +0200
changeset 1052
c3fb7c0a95d9
parent 1051
5aac3287ea5d
child 1053
a35c8136c045

8059842: Creating symbols for declared functions shouldn't be a special case
Reviewed-by: hannesw, lagergren

src/jdk/nashorn/internal/codegen/AssignSymbols.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/VarNode.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Fri Oct 10 19:09:18 2014 +0530
     1.2 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Mon Oct 13 20:10:14 2014 +0200
     1.3 @@ -511,16 +511,6 @@
     1.4  
     1.5          thisProperties.push(new HashSet<String>());
     1.6  
     1.7 -        if (functionNode.isDeclared()) {
     1.8 -            // Can't use lc.getCurrentBlock() as we can have an outermost function in our lexical context that
     1.9 -            // is not a program - it is a function being compiled on-demand.
    1.10 -            final Iterator<Block> blocks = lc.getBlocks();
    1.11 -            if (blocks.hasNext()) {
    1.12 -                final IdentNode ident = functionNode.getIdent();
    1.13 -                defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
    1.14 -            }
    1.15 -        }
    1.16 -
    1.17          // Every function has a body, even the ones skipped on reparse (they have an empty one). We're
    1.18          // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that
    1.19          // are used in them.
    1.20 @@ -532,14 +522,34 @@
    1.21      @Override
    1.22      public boolean enterVarNode(final VarNode varNode) {
    1.23          start(varNode);
    1.24 +        // Normally, a symbol assigned in a var statement is not live for its RHS. Since we also represent function
    1.25 +        // declarations as VarNodes, they are exception to the rule, as they need to have the symbol visible to the
    1.26 +        // body of the declared function for self-reference.
    1.27 +        if (varNode.isFunctionDeclaration()) {
    1.28 +            defineVarIdent(varNode);
    1.29 +        }
    1.30          return true;
    1.31      }
    1.32  
    1.33      @Override
    1.34      public Node leaveVarNode(final VarNode varNode) {
    1.35 +        if (!varNode.isFunctionDeclaration()) {
    1.36 +            defineVarIdent(varNode);
    1.37 +        }
    1.38 +        return super.leaveVarNode(varNode);
    1.39 +    }
    1.40 +
    1.41 +    private void defineVarIdent(final VarNode varNode) {
    1.42          final IdentNode ident = varNode.getName();
    1.43 -        defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
    1.44 -        return super.leaveVarNode(varNode);
    1.45 +        final int flags;
    1.46 +        if (varNode.isAnonymousFunctionDeclaration()) {
    1.47 +            flags = IS_INTERNAL;
    1.48 +        } else if (lc.getCurrentFunction().isProgram()) {
    1.49 +            flags = IS_SCOPE;
    1.50 +        } else {
    1.51 +            flags = 0;
    1.52 +        }
    1.53 +        defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);
    1.54      }
    1.55  
    1.56      private Symbol exceptionSymbol() {
     2.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java	Fri Oct 10 19:09:18 2014 +0530
     2.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java	Mon Oct 13 20:10:14 2014 +0200
     2.3 @@ -272,4 +272,12 @@
     2.4      public boolean isFunctionDeclaration() {
     2.5          return init instanceof FunctionNode && ((FunctionNode)init).isDeclared();
     2.6      }
     2.7 +
     2.8 +    /**
     2.9 +     * Returns true if this is an anonymous function declaration.
    2.10 +     * @return true if this is an anonymous function declaration.
    2.11 +     */
    2.12 +    public boolean isAnonymousFunctionDeclaration() {
    2.13 +        return isFunctionDeclaration() && ((FunctionNode)init).isAnonymous();
    2.14 +    }
    2.15  }

mercurial