use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class Parser method tryStatement.
/**
* <strong>[13.15] The <code>try</code> Statement</strong>
*
* <pre>
* TryStatement<span><sub>[Yield, Return]</sub></span> :
* try Block<span><sub>[?Yield, ?Return]</sub></span> Catch<span><sub>[?Yield, ?Return]</sub></span>
* try Block<span><sub>[?Yield, ?Return]</sub></span> Finally<span><sub>[?Yield, ?Return]</sub></span>
* try Block<span><sub>[?Yield, ?Return]</sub></span> Catch<span><sub>[?Yield, ?Return]</sub></span> Finally<span><sub>[?Yield, ?Return]</sub></span>
* Catch<span><sub>[Yield, Return]</sub></span> :
* catch ( CatchParameter<span><sub>[?Yield]</sub></span> ) Block<span><sub>[?Yield, ?Return]</sub></span>
* Finally<span><sub>[Yield, Return]</sub></span> :
* finally Block<span><sub>[?Yield, ?Return]</sub></span>
* CatchParameter<span><sub>[Yield]</sub></span> :
* BindingIdentifier<span><sub>[?Yield]</sub></span>
* BindingPattern<span><sub>[?Yield]</sub></span>
* </pre>
*
* @return the parsed try-statement node
*/
private TryStatement tryStatement() {
BlockStatement tryBlock, finallyBlock = null;
CatchNode catchNode = null;
List<GuardedCatchNode> guardedCatchNodes = emptyList();
long begin = ts.beginPosition();
consume(Token.TRY);
tryBlock = block(NO_INHERITED_BINDING);
Token tok = token();
if (tok == Token.CATCH) {
if (isEnabled(CompatibilityOption.GuardedCatch)) {
guardedCatchNodes = newList();
while (token() == Token.CATCH && catchNode == null) {
long beginCatch = ts.beginPosition();
consume(Token.CATCH);
consume(Token.LP);
BlockScope catchScope = enterCatchScope();
Binding catchParameter = binding(true);
addLexDeclaredName(catchParameter);
Expression guard;
if (token() == Token.IF) {
consume(Token.IF);
guard = expression(true);
} else {
guard = null;
}
consume(Token.RP);
// CatchBlock receives a list of non-available lexical declarable names to
// fulfill the early error restriction that the BoundNames of CatchParameter
// must not also occur in either the LexicallyDeclaredNames or the
// VarDeclaredNames of CatchBlock.
BlockStatement catchBlock = block(singletonList(catchParameter));
exitCatchContext();
if (guard != null) {
GuardedCatchNode guardedCatchNode = new GuardedCatchNode(beginCatch, ts.endPosition(), catchScope, catchParameter, guard, catchBlock);
assignCatchScopeNode(catchScope, guardedCatchNode);
guardedCatchNodes.add(guardedCatchNode);
} else {
catchNode = new CatchNode(beginCatch, ts.endPosition(), catchScope, catchParameter, catchBlock);
assignCatchScopeNode(catchScope, catchNode);
}
}
} else {
long beginCatch = ts.beginPosition();
consume(Token.CATCH);
consume(Token.LP);
BlockScope catchScope = enterCatchScope();
Binding catchParameter = binding(true);
addLexDeclaredName(catchParameter);
consume(Token.RP);
// CatchBlock receives a list of non-available lexical declarable names to
// fulfill the early error restriction that the BoundNames of CatchParameter
// must not also occur in either the LexicallyDeclaredNames or the
// VarDeclaredNames of CatchBlock.
BlockStatement catchBlock = block(singletonList(catchParameter));
exitCatchContext();
catchNode = new CatchNode(beginCatch, ts.endPosition(), catchScope, catchParameter, catchBlock);
assignCatchScopeNode(catchScope, catchNode);
}
if (token() == Token.FINALLY) {
consume(Token.FINALLY);
finallyBlock = block(NO_INHERITED_BINDING);
}
} else {
consume(Token.FINALLY);
finallyBlock = block(NO_INHERITED_BINDING);
}
return new TryStatement(begin, ts.endPosition(), tryBlock, catchNode, guardedCatchNodes, finallyBlock);
}
use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class StatementGenerator method visit.
/**
* 13.2 Block
* <p>
* 13.2.13 Runtime Semantics: Evaluation
*/
@Override
public Completion visit(BlockStatement node, CodeVisitor mv) {
if (node.getStatements().isEmpty()) {
// -> Return NormalCompletion(empty)
return Completion.Normal;
}
/* steps 1-4 */
BlockScope scope = node.getScope();
if (scope.isPresent()) {
newDeclarativeEnvironment(scope, mv);
codegen.blockInit(node, mv);
pushLexicalEnvironment(mv);
}
/* step 5 */
mv.enterScope(node);
Completion result = Completion.Normal;
{
/* steps 1-4 */
for (StatementListItem statement : node.getStatements()) {
if ((result = statement.accept(this, mv)).isAbrupt()) {
break;
}
}
}
mv.exitScope();
/* step 6 */
if (scope.isPresent() && !result.isAbrupt()) {
popLexicalEnvironment(mv);
}
/* step 7 */
return result;
}
use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class StatementGenerator method ForInOfBodyEvaluationInner.
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion ForInOfBodyEvaluationInner(FORSTATEMENT node, Variable<Object> nextValue, CodeVisitor mv) {
BlockScope scope = node.getScope();
Node lhs = node.getHead();
/* steps 5.f-j */
if (lhs instanceof Expression) {
/* steps 5.f, 5.h-j */
LeftHandSideExpression lhsExpr = (LeftHandSideExpression) lhs;
if (!(lhsExpr instanceof AssignmentPattern)) {
ReferenceOp<LeftHandSideExpression> op = ReferenceOp.of(lhsExpr);
/* step 5.f.i.1 */
// stack: [] -> [<ref>]
ValType ref = op.reference(lhsExpr, mv, codegen);
/* steps 5.h.i, 5.h.iii */
// stack: [<ref>] -> []
mv.load(nextValue);
op.putValue(lhsExpr, ref, ValType.Any, mv);
} else {
/* step 5.i.i */
mv.load(nextValue);
DestructuringAssignment(codegen, (AssignmentPattern) lhs, mv);
}
} else if (lhs instanceof VariableStatement) {
/* steps 5.f, 5.h-j */
Binding binding = forVarDeclarationBinding((VariableStatement) lhs);
if (binding instanceof BindingIdentifier) {
BindingIdentifier bindingId = (BindingIdentifier) binding;
/* step 5.f.i.1 */
// 13.7.5.14 Runtime Semantics: Evaluation
IdReferenceOp op = IdReferenceOp.of(bindingId);
op.resolveBinding(bindingId, mv);
/* steps 5.h.i, 5.h.iii */
// stack: [<ref>] -> []
mv.load(nextValue);
op.putValue(bindingId, ValType.Any, mv);
} else {
/* step 5.i.ii */
mv.load(nextValue);
BindingInitialization(codegen, (BindingPattern) binding, mv);
}
} else {
/* steps 5.g-j */
Binding binding = forDeclarationBinding((LexicalDeclaration) lhs);
Variable<DeclarativeEnvironmentRecord> envRec = null;
if (scope.isPresent()) {
mv.enterVariableScope();
envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
newDeclarativeEnvironment(scope, mv);
getEnvRec(envRec, mv);
BindingInstantiation(envRec, (LexicalDeclaration) lhs, mv);
pushLexicalEnvironment(mv);
}
mv.enterScope(node);
/* step 5.h */
if (binding instanceof BindingIdentifier) {
/* step 5.h.ii */
BindingIdentifier bindingId = (BindingIdentifier) binding;
Name name = bindingId.getName();
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.initializeBinding(envRec, name, nextValue, mv);
} else {
/* step 5.i.iii */
// 13.7.5.9 Runtime Semantics: BindingInitialization
BindingInitialization(codegen, envRec, (BindingPattern) binding, nextValue, mv);
}
if (scope.isPresent()) {
mv.exitVariableScope();
}
}
/* step 5.k */
Completion result = node.getStatement().accept(this, mv);
/* step 5.l */
if (lhs 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 SwitchStatementGenerator method visit.
/**
* 13.12.11 Runtime Semantics: Evaluation
*/
@Override
public Completion visit(SwitchStatement node, CodeVisitor mv) {
final boolean defaultClausePresent = hasDefaultClause(node);
final SwitchType type = SwitchType.of(node);
// stack -> switchValue
ValType switchValueType = expression(node.getExpression(), mv);
boolean defaultOrReturn = false;
if (isDefaultSwitch(node)) {
defaultOrReturn = true;
} else if (type == SwitchType.Int) {
if (!switchValueType.isNumber() && switchValueType != ValType.Any) {
defaultOrReturn = true;
}
} else if (type == SwitchType.Char) {
if (switchValueType != ValType.String && switchValueType != ValType.Any) {
defaultOrReturn = true;
}
} else if (type == SwitchType.String) {
if (switchValueType != ValType.String && switchValueType != ValType.Any) {
defaultOrReturn = true;
}
} else {
mv.toBoxed(switchValueType);
switchValueType = ValType.Any;
}
if (defaultOrReturn) {
// never true -> emit default switch or return
mv.pop(switchValueType);
if (!defaultClausePresent) {
return Completion.Normal;
}
}
mv.enterVariableScope();
Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
Variable<?> switchValue = null;
if (!defaultOrReturn) {
switchValue = mv.newVariable("switchValue", switchValueType.toClass());
mv.store(switchValue);
}
BlockScope scope = node.getScope();
if (scope.isPresent()) {
newDeclarativeEnvironment(scope, mv);
codegen.blockInit(node, mv);
pushLexicalEnvironment(mv);
}
Jump lblExit = new Jump();
BreakLabel lblBreak = new BreakLabel();
mv.enterScope(node);
mv.enterBreakable(node, lblBreak);
Completion result;
if (defaultOrReturn) {
result = DefaultCaseBlockEvaluation(node, mv);
} else {
result = CaseBlockEvaluation(node, type, defaultClausePresent, lblExit, switchValue, mv);
}
mv.exitBreakable(node);
mv.exitScope();
if (!defaultClausePresent) {
mv.mark(lblExit);
}
if (scope.isPresent() && !result.isAbrupt()) {
popLexicalEnvironment(mv);
}
if (lblBreak.isTarget()) {
mv.mark(lblBreak);
restoreEnvironment(savedEnv, mv);
}
mv.exitVariableScope();
return result.normal(lblBreak.isTarget() || !defaultClausePresent);
}
use of com.github.anba.es6draft.ast.scope.BlockScope in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionComponentEvaluation
* <p>
* ComprehensionFor : for ( ForBinding of AssignmentExpression )
*/
@Override
public Void visit(ComprehensionFor node, CodeVisitor mv) {
Jump lblTest = new Jump(), lblLoop = new Jump();
Variable<ScriptIterator<?>> iter = iterators.next();
/* steps 1-2 */
expressionBoxed(node.getExpression(), mv);
/* steps 3-4 */
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
mv.invoke(Methods.IteratorOperations_iterate);
mv.store(iter);
/* step 5 (not applicable) */
/* step 6 */
mv.nonDestructiveGoTo(lblTest);
/* steps 6.d-e */
mv.mark(lblLoop);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_next);
/* steps 6.f-j */
BlockScope scope = node.getScope();
if (scope.isPresent()) {
mv.enterVariableScope();
Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> env = mv.newVariable("env", LexicalEnvironment.class).uncheckedCast();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
// stack: [nextValue] -> []
Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
mv.store(nextValue);
newDeclarativeEnvironment(scope, mv);
mv.store(env);
getEnvRec(env, envRec, mv);
for (Name name : BoundNames(node.getBinding())) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
}
BindingInitialization(codegen, envRec, node.getBinding(), nextValue, mv);
mv.load(env);
pushLexicalEnvironment(mv);
mv.exitVariableScope();
} else {
// stack: [nextValue] -> []
mv.pop();
}
/* step 6.k */
mv.enterScope(node);
new IterationGenerator<ComprehensionFor>(codegen) {
@Override
protected Completion iterationBody(ComprehensionFor node, Variable<ScriptIterator<?>> iterator, CodeVisitor mv) {
elements.next().accept(ComprehensionGenerator.this, mv);
return Completion.Normal;
}
@Override
protected MutableValue<Object> enterIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.enterIteration();
}
@Override
protected List<TempLabel> exitIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.exitIteration();
}
}.generate(node, iter, mv);
mv.exitScope();
/* steps 6.l-m */
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
/* steps 6.a-c */
mv.mark(lblTest);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_hasNext);
mv.ifne(lblLoop);
return null;
}
Aggregations