Mon, 13 Oct 2014 20:10:14 +0200
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 }