use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class StatementGenerator method visit.
/**
* 13.7.4 The for Statement
* <p>
* 13.1.8 Runtime Semantics: Evaluation<br>
* 13.1.7 Runtime Semantics: LabelledEvaluation<br>
* 13.7.4.7 Runtime Semantics: LabelledEvaluation
*/
@Override
public Completion visit(ForStatement node, CodeVisitor mv) {
assert mv.getStackSize() == 0;
boolean perIterationsLets = false;
BlockScope scope = node.getScope();
Node head = node.getHead();
if (head == null) {
// empty
} else if (head instanceof Expression) {
ValType type = expression(((Expression) head).emptyCompletion(), mv);
mv.pop(type);
} else if (head instanceof VariableStatement) {
head.accept(this, mv);
} else {
assert head instanceof LexicalDeclaration;
LexicalDeclaration lexDecl = (LexicalDeclaration) head;
List<Name> boundNames = BoundNames(lexDecl);
boolean isConst = IsConstantDeclaration(lexDecl);
perIterationsLets = !isConst && !boundNames.isEmpty();
if (scope.isPresent()) {
mv.enterVariableScope();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
// stack: [] -> [loopEnv]
newDeclarativeEnvironment(scope, mv);
// stack: [loopEnv] -> [loopEnv]
getEnvRec(envRec, mv);
// stack: [loopEnv] -> [loopEnv]
for (Name dn : boundNames) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, dn);
if (isConst) {
op.createImmutableBinding(envRec, dn, true, mv);
} else {
op.createMutableBinding(envRec, dn, false, mv);
}
}
// stack: [loopEnv] -> []
pushLexicalEnvironment(mv);
mv.exitVariableScope();
}
mv.enterScope(node);
lexDecl.accept(this, mv);
}
Completion result = ForBodyEvaluation(node, perIterationsLets, mv);
if (head instanceof LexicalDeclaration) {
mv.exitScope();
if (scope.isPresent() && !result.isAbrupt()) {
popLexicalEnvironment(mv);
}
}
return result;
}
use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class StatementGenerator method ForInOfHeadEvaluation.
/**
* 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation (TDZnames, expr, iterationKind, labelSet)
* <p>
* stack: [] {@literal ->} [Iterator]
*
* @param <FORSTATEMENT>
* the for-statement node type
* @param node
* the for-statement node
* @param iterationKind
* the for-statement's iteration kind
* @param lblFail
* the target instruction if the expression node does not produce an object type
* @param mv
* the code visitor
* @return the value type of the expression
*/
private <FORSTATEMENT extends IterationStatement & ForIterationNode> ValType ForInOfHeadEvaluation(FORSTATEMENT node, IterationKind iterationKind, Jump lblFail, CodeVisitor mv) {
/* steps 1-2 */
BlockScope scope = node.getScope();
Node lhs = node.getHead();
List<Name> tdzNames = null;
if (lhs instanceof LexicalDeclaration) {
tdzNames = BoundNames(forDeclarationBinding((LexicalDeclaration) lhs));
assert scope.isPresent() == !tdzNames.isEmpty();
if (scope.isPresent()) {
mv.enterVariableScope();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
// stack: [] -> [TDZ]
newDeclarativeEnvironment(scope, mv);
// stack: [TDZ] -> [TDZ]
getEnvRec(envRec, mv);
// stack: [TDZ] -> [TDZ]
for (Name name : tdzNames) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
}
mv.exitVariableScope();
// stack: [TDZ] -> []
pushLexicalEnvironment(mv);
}
mv.enterScope(node);
}
/* steps 3, 5-6 */
Expression expr = node.getExpression();
ValType type = expressionBoxed(expr, mv);
/* step 4 */
if (tdzNames != null) {
mv.exitScope();
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
}
/* steps 7-8 */
if (iterationKind == IterationKind.Enumerate) {
/* step 7.a */
if (type != ValType.Object) {
Jump loopstart = new Jump();
mv.dup();
isUndefinedOrNull(mv);
mv.ifeq(loopstart);
mv.pop();
mv.goTo(lblFail);
mv.mark(loopstart);
}
/* steps 7.b-c */
mv.loadExecutionContext();
mv.lineInfo(expr);
mv.invoke(Methods.IteratorOperations_enumerate);
} else if (iterationKind == IterationKind.AsyncIterate) {
mv.loadExecutionContext();
mv.lineInfo(expr);
mv.invoke(Methods.IteratorOperations_asyncIterate);
} else {
/* step 8 */
assert iterationKind == IterationKind.Iterate;
mv.loadExecutionContext();
mv.lineInfo(expr);
mv.invoke(Methods.IteratorOperations_iterate);
}
return type;
}
use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class ExpressionGenerator method isEnclosedByLexicalDeclaration.
private boolean isEnclosedByLexicalDeclaration(Scope currentScope) {
final boolean catchVar = codegen.isEnabled(CompatibilityOption.CatchVarStatement);
TopLevelScope top = currentScope.getTop();
for (Scope scope : currentScope) {
if (scope instanceof BlockScope) {
if (catchVar) {
ScopedNode node = scope.getNode();
if (node instanceof CatchClause && ((CatchClause) node).getCatchParameter() instanceof BindingIdentifier) {
continue;
}
}
if (!((BlockScope) scope).lexicallyDeclaredNames().isEmpty()) {
return true;
}
} else if (scope == top) {
break;
}
}
if (!top.lexicallyDeclaredNames().isEmpty()) {
TopLevelNode<?> topNode = top.getNode();
if (topNode instanceof Script) {
return ((Script) topNode).isEvalScript();
}
return true;
}
return codegen.isEnabled(Parser.Option.EnclosedByLexicalDeclaration);
}
Aggregations