< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
Print this page
*** 255,264 ****
--- 255,267 ----
private final IntDeque labeledBlockBreakLiveLocals = new IntDeque();
//is this a rest of compilation
private final int[] continuationEntryPoints;
+ // Scope object creators needed for for-of and for-in loops
+ private Deque<FieldObjectCreator<?>> scopeObjectCreators = new ArrayDeque<>();
+
/**
* Constructor.
*
* @param compiler
*/
*** 1295,1304 ****
--- 1298,1310 ----
}
private void popBlockScope(final Block block) {
final Label breakLabel = block.getBreakLabel();
+ if (block.providesScopeCreator()) {
+ scopeObjectCreators.pop();
+ }
if(!block.needsScope() || lc.isFunctionBody()) {
emitBlockBreakLabel(breakLabel);
return;
}
*** 1810,1819 ****
--- 1816,1833 ----
}.emit();
}
}.store();
body.accept(this);
+ if (forNode.needsScopeCreator() && lc.getCurrentBlock().providesScopeCreator()) {
+ // for-in loops with lexical declaration need a new scope for each iteration.
+ final FieldObjectCreator<?> creator = scopeObjectCreators.peek();
+ assert creator != null;
+ creator.createForInIterationScope(method);
+ method.storeCompilerConstant(SCOPE);
+ }
+
if(method.isReachable()) {
method._goto(continueLabel);
}
method.label(breakLabel);
}
*** 1921,1936 ****
/*
* Create a new object based on the symbols and values, generate
* bootstrap code for object
*/
! new FieldObjectCreator<Symbol>(this, tuples, true, hasArguments) {
@Override
protected void loadValue(final Symbol value, final Type type) {
method.load(value, type);
}
! }.makeObject(method);
// program function: merge scope into global
if (isFunctionBody && function.isProgram()) {
method.invoke(ScriptRuntime.MERGE_SCOPE);
}
--- 1935,1954 ----
/*
* Create a new object based on the symbols and values, generate
* bootstrap code for object
*/
! final FieldObjectCreator<Symbol> creator = new FieldObjectCreator<Symbol>(this, tuples, true, hasArguments) {
@Override
protected void loadValue(final Symbol value, final Type type) {
method.load(value, type);
}
! };
! creator.makeObject(method);
! if (block.providesScopeCreator()) {
! scopeObjectCreators.push(creator);
! }
// program function: merge scope into global
if (isFunctionBody && function.isProgram()) {
method.invoke(ScriptRuntime.MERGE_SCOPE);
}
*** 4478,4488 ****
@Override
public boolean enterIdentNode(final IdentNode node) {
final Symbol symbol = node.getSymbol();
assert symbol != null;
if (symbol.isScope()) {
! final int flags = getScopeCallSiteFlags(symbol);
if (isFastScope(symbol)) {
storeFastScopeVar(symbol, flags);
} else {
method.dynamicSet(node.getName(), flags, false);
}
--- 4496,4506 ----
@Override
public boolean enterIdentNode(final IdentNode node) {
final Symbol symbol = node.getSymbol();
assert symbol != null;
if (symbol.isScope()) {
! final int flags = getScopeCallSiteFlags(symbol) | (node.isDeclaredHere() ? CALLSITE_DECLARE : 0);
if (isFastScope(symbol)) {
storeFastScopeVar(symbol, flags);
} else {
method.dynamicSet(node.getName(), flags, false);
}
< prev index next >