src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java
Print this page
*** 311,327 ****
*
* @return Symbol for given name or null for redefinition.
*/
private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
int flags = symbolFlags;
! final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
Symbol symbol;
final FunctionNode function;
! if (isBlockScope) {
! // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
symbol = block.getExistingSymbol(name);
function = lc.getCurrentFunction();
} else {
symbol = findSymbol(block, name);
function = lc.getFunction(block);
--- 311,327 ----
*
* @return Symbol for given name or null for redefinition.
*/
private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
int flags = symbolFlags;
! final boolean isLexicalScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
Symbol symbol;
final FunctionNode function;
! if (isLexicalScope) {
! // lexically scoped variables always live in current block, no need to look for existing symbols in parent blocks.
symbol = block.getExistingSymbol(name);
function = lc.getCurrentFunction();
} else {
symbol = findSymbol(block, name);
function = lc.getFunction(block);
*** 348,363 ****
} else if (symbol.isParam()) {
// Duplicate parameter. Null return will force an error.
throw new AssertionError("duplicate parameter");
}
} else if (isVar) {
! if (isBlockScope) {
// Check redeclaration in same block
if (symbol.hasBeenDeclared()) {
throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
} else {
symbol.setHasBeenDeclared();
}
} else if ((flags & IS_INTERNAL) != 0) {
// Always create a new definition.
symbol = null;
} else {
--- 348,367 ----
} else if (symbol.isParam()) {
// Duplicate parameter. Null return will force an error.
throw new AssertionError("duplicate parameter");
}
} else if (isVar) {
! if (isLexicalScope) {
// Check redeclaration in same block
if (symbol.hasBeenDeclared()) {
throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
} else {
symbol.setHasBeenDeclared();
+ // Set scope flag on top-level lexical symbols
+ if (function.isProgram() && function.getBody() == block) {
+ symbol.setIsScope();
+ }
}
} else if ((flags & IS_INTERNAL) != 0) {
// Always create a new definition.
symbol = null;
} else {
*** 376,386 ****
if (symbol == null) {
// If not found, then create a new one.
final Block symbolBlock;
// Determine where to create it.
! if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
symbolBlock = block; //internal vars are always defined in the block closest to them
} else if (isGlobal) {
symbolBlock = lc.getOutermostFunction().getBody();
} else {
symbolBlock = lc.getFunctionBody(function);
--- 380,390 ----
if (symbol == null) {
// If not found, then create a new one.
final Block symbolBlock;
// Determine where to create it.
! if (isVar && ((flags & IS_INTERNAL) != 0 || isLexicalScope)) {
symbolBlock = block; //internal vars are always defined in the block closest to them
} else if (isGlobal) {
symbolBlock = lc.getOutermostFunction().getBody();
} else {
symbolBlock = lc.getFunctionBody(function);
*** 538,548 ****
private void defineVarIdent(final VarNode varNode) {
final IdentNode ident = varNode.getName();
final int flags;
if (varNode.isAnonymousFunctionDeclaration()) {
flags = IS_INTERNAL;
! } else if (lc.getCurrentFunction().isProgram()) {
flags = IS_SCOPE;
} else {
flags = 0;
}
defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);
--- 542,552 ----
private void defineVarIdent(final VarNode varNode) {
final IdentNode ident = varNode.getName();
final int flags;
if (varNode.isAnonymousFunctionDeclaration()) {
flags = IS_INTERNAL;
! } else if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) {
flags = IS_SCOPE;
} else {
flags = 0;
}
defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);