Search in sources :

Example 1 with BlockScope

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);
}
Also used : BlockScope(com.github.anba.es6draft.ast.scope.BlockScope)

Example 2 with BlockScope

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;
}
Also used : BlockScope(com.github.anba.es6draft.ast.scope.BlockScope)

Example 3 with BlockScope

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;
}
Also used : Variable(com.github.anba.es6draft.compiler.assembler.Variable) InitializeBoundName(com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope)

Example 4 with BlockScope

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);
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 5 with BlockScope

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;
}
Also used : ComprehensionFor(com.github.anba.es6draft.ast.ComprehensionFor) MutableValue(com.github.anba.es6draft.compiler.assembler.MutableValue) Jump(com.github.anba.es6draft.compiler.assembler.Jump) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) ArrayList(java.util.ArrayList) List(java.util.List) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)

Aggregations

BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)13 Name (com.github.anba.es6draft.ast.scope.Name)9 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)8 DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)7 InitializeBoundName (com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName)5 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)5 Jump (com.github.anba.es6draft.compiler.assembler.Jump)3 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)2 Variable (com.github.anba.es6draft.compiler.assembler.Variable)2 ComprehensionFor (com.github.anba.es6draft.ast.ComprehensionFor)1 Scope (com.github.anba.es6draft.ast.scope.Scope)1 TopLevelScope (com.github.anba.es6draft.ast.scope.TopLevelScope)1 WithScope (com.github.anba.es6draft.ast.scope.WithScope)1 LabelledHashKey (com.github.anba.es6draft.compiler.CodeVisitor.LabelledHashKey)1 ValType (com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)1 BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)1 FieldName (com.github.anba.es6draft.compiler.assembler.FieldName)1 MutableValue (com.github.anba.es6draft.compiler.assembler.MutableValue)1 ScriptIterator (com.github.anba.es6draft.runtime.internal.ScriptIterator)1 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)1