Search in sources :

Example 1 with BreakLabel

use of com.github.anba.es6draft.compiler.Labels.BreakLabel in project es6draft by anba.

the class StatementGenerator method visit.

/**
     * 13.13 Labelled Statements
     * <p>
     * 13.13.15 Runtime Semantics: Evaluation<br>
     * 13.13.14 Runtime Semantics: LabelledEvaluation
     */
@Override
public Completion visit(LabelledStatement node, CodeVisitor mv) {
    assert mv.getStackSize() == 0;
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    /* steps 1-3 */
    BreakLabel label = new BreakLabel();
    mv.enterLabelled(node, label);
    Completion result = node.getStatement().accept(this, mv);
    mv.exitLabelled(node);
    /* step 4 */
    if (label.isTarget()) {
        mv.mark(label);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    /* steps 4-5 */
    return result.normalOrEmpty(label.isTarget());
}
Also used : LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel)

Example 2 with BreakLabel

use of com.github.anba.es6draft.compiler.Labels.BreakLabel in project es6draft by anba.

the class StatementGenerator method AsyncForInOfBodyEvaluation.

/**
     * 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation (lhs, stmt, iterator, lhsKind, labelSet)
     * <p>
     * stack: [Iterator] {@literal ->} []
     * 
     * @param <FORSTATEMENT>
     *            the for-statement node type
     * @param node
     *            the for-statement node
     * @param mv
     *            the code visitor
     * @return the completion value
     */
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion AsyncForInOfBodyEvaluation(FORSTATEMENT node, CodeVisitor mv) {
    assert mv.getStackSize() == 1;
    ContinueLabel lblContinue = new ContinueLabel();
    BreakLabel lblBreak = new BreakLabel();
    Jump enter = new Jump(), test = new Jump();
    mv.enterVariableScope();
    Variable<ScriptObject> iterator = mv.newVariable("iter", ScriptObject.class);
    // stack: [Iterator] -> []
    mv.store(iterator);
    Variable<ScriptObject> nextResult = mv.newVariable("nextResult", ScriptObject.class);
    mv.anull();
    mv.store(nextResult);
    Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
    mv.anull();
    mv.store(nextValue);
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    /* step 2 */
    if (node.hasCompletionValue()) {
        mv.storeUndefinedAsCompletionValue();
    }
    /* steps 3-4 (not applicable) */
    /* step 5 (repeat loop) */
    mv.nonDestructiveGoTo(test);
    /* steps 5.d-e */
    mv.mark(enter);
    IteratorValue(node, nextResult, mv);
    await(node, mv);
    mv.store(nextValue);
    /* steps 5.f-l */
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        mv.enterWrapped();
        new AbstractIterationGenerator<FORSTATEMENT, ScriptObject>(codegen) {

            @Override
            protected Completion iterationBody(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
                return ForInOfBodyEvaluationInner(node, nextValue, mv);
            }

            @Override
            protected MutableValue<Object> enterIteration(FORSTATEMENT node, CodeVisitor mv) {
                return mv.enterIterationBody(node);
            }

            @Override
            protected List<TempLabel> exitIteration(FORSTATEMENT node, CodeVisitor mv) {
                return mv.exitIterationBody(node);
            }

            @Override
            protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, Variable<? extends Throwable> throwable, CodeVisitor mv) {
                asyncIteratorClose(node, iterator, throwable, mv);
            }

            @Override
            protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
                asyncIteratorClose(node, iterator, mv);
            }
        }.generate(node, iterator, test, mv);
        mv.exitWrapped();
        mv.exitIteration(node);
    }
    /* steps 5.m-n */
    if (lblContinue.isTarget()) {
        mv.mark(lblContinue);
        restoreEnvironment(savedEnv, mv);
    }
    /* steps 5.a-c */
    mv.mark(test);
    IteratorNext(node, iterator, mv);
    await(node, mv);
    // FIXME: spec bug - missing type check after await
    requireObjectResult(node, "next", mv);
    mv.store(nextResult);
    IteratorComplete(node, nextResult, mv);
    mv.ifeq(enter);
    /* steps 5.m-n */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    return Completion.Normal;
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) Variable(com.github.anba.es6draft.compiler.assembler.Variable) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel) ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel)

Example 3 with BreakLabel

use of com.github.anba.es6draft.compiler.Labels.BreakLabel in project es6draft by anba.

the class StatementGenerator method visit.

/**
     * 13.7.2 The do-while Statement
     * <p>
     * 13.1.8 Runtime Semantics: Evaluation<br>
     * 13.1.7 Runtime Semantics: LabelledEvaluation<br>
     * 13.7.2.6 Runtime Semantics: LabelledEvaluation
     */
@Override
public Completion visit(DoWhileStatement node, CodeVisitor mv) {
    assert mv.getStackSize() == 0;
    Jump lblNext = new Jump();
    ContinueLabel lblContinue = new ContinueLabel();
    BreakLabel lblBreak = new BreakLabel();
    Bool btest = Bool.evaluate(node.getTest());
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    /* step 1 */
    if (node.hasCompletionValue()) {
        mv.storeUndefinedAsCompletionValue();
    }
    /* step 2 (repeat loop) */
    mv.mark(lblNext);
    /* steps 2.a-c */
    Completion result;
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        result = node.getStatement().accept(this, mv);
        mv.exitIteration(node);
    }
    /* step 2.b (abrupt completion - continue) */
    if (lblContinue.isTarget()) {
        mv.mark(lblContinue);
        restoreEnvironment(savedEnv, mv);
    }
    /* steps 2.d-g */
    if (!result.isAbrupt() || lblContinue.isTarget()) {
        if (btest == Bool.Any) {
            ValType type = expression(node.getTest(), mv);
            ToBoolean(type, mv);
            mv.ifne(lblNext);
        } else if (btest == Bool.True) {
            mv.goTo(lblNext);
        }
    }
    /* step 2.b (abrupt completion - break) */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    /* steps 2.b, 2.g */
    if (btest == Bool.True) {
        if (!result.isAbrupt() && !lblBreak.isTarget()) {
            // infinite loop
            return Completion.Abrupt;
        }
        return result.normal(lblBreak.isTarget());
    }
    return result.normal(lblContinue.isTarget() || lblBreak.isTarget());
}
Also used : ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 4 with BreakLabel

use of com.github.anba.es6draft.compiler.Labels.BreakLabel in project es6draft by anba.

the class SwitchStatementGenerator method visit.

/**
     * 13.12.11 Runtime Semantics: Evaluation
     */
@Override
public Completion visit(SwitchStatement node, CodeVisitor mv) {
    // stack -> switchValue
    ValType switchValueType = expression(node.getExpression(), mv);
    SwitchType type = SwitchType.of(node);
    boolean defaultOrReturn = false;
    if (type == SwitchType.Int) {
        if (!switchValueType.isNumeric() && 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 if (type == SwitchType.Generic) {
        mv.toBoxed(switchValueType);
        switchValueType = ValType.Any;
    } else {
        assert type == SwitchType.Default;
        defaultOrReturn = true;
    }
    final boolean defaultClausePresent = hasDefaultClause(node);
    if (defaultOrReturn) {
        // never true -> emit default switch or return
        mv.pop(switchValueType);
        if (defaultClausePresent) {
            type = SwitchType.Default;
        } else {
            return Completion.Normal;
        }
    }
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    Variable<?> switchValue = null;
    if (type != SwitchType.Default) {
        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 = CaseBlockEvaluation(node, type, 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());
}
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 BreakLabel

use of com.github.anba.es6draft.compiler.Labels.BreakLabel in project es6draft by anba.

the class StatementGenerator method visit.

/**
     * 13.7.3 The while Statement
     * <p>
     * 13.1.8 Runtime Semantics: Evaluation<br>
     * 13.1.7 Runtime Semantics: LabelledEvaluation<br>
     * 13.7.3.6 Runtime Semantics: LabelledEvaluation
     */
@Override
public Completion visit(WhileStatement node, CodeVisitor mv) {
    assert mv.getStackSize() == 0;
    Jump lblNext = new Jump(), lblTest = new Jump();
    ContinueLabel lblContinue = new ContinueLabel();
    BreakLabel lblBreak = new BreakLabel();
    Bool btest = Bool.evaluate(node.getTest());
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    /* step 1 */
    if (node.hasCompletionValue()) {
        mv.storeUndefinedAsCompletionValue();
    }
    /* step 2 (repeat loop) */
    if (btest != Bool.True) {
        mv.nonDestructiveGoTo(lblTest);
    }
    mv.mark(lblNext);
    /* steps 2.e-g */
    Completion result;
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        result = node.getStatement().accept(this, mv);
        mv.exitIteration(node);
    }
    /* step 2.f (abrupt completion - continue) */
    if (lblContinue.isTarget()) {
        mv.mark(lblContinue);
        restoreEnvironment(savedEnv, mv);
    }
    /* steps 2.a-d */
    if (btest != Bool.True) {
        mv.mark(lblTest);
        ValType type = expression(node.getTest(), mv);
        ToBoolean(type, mv);
        mv.ifne(lblNext);
    } else if (!result.isAbrupt() || lblContinue.isTarget()) {
        mv.goTo(lblNext);
    }
    /* step 2.f (abrupt completion - break) */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    /* steps 2.d, 2.f */
    if (btest == Bool.True) {
        if (!result.isAbrupt() && !lblBreak.isTarget()) {
            // infinite loop
            return Completion.Abrupt;
        }
        return result.normal(lblBreak.isTarget());
    }
    return Completion.Normal;
}
Also used : ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Aggregations

BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)7 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)7 Jump (com.github.anba.es6draft.compiler.assembler.Jump)6 ContinueLabel (com.github.anba.es6draft.compiler.Labels.ContinueLabel)5 TempLabel (com.github.anba.es6draft.compiler.Labels.TempLabel)2 Variable (com.github.anba.es6draft.compiler.assembler.Variable)2 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)2 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)2 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)1 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)1 ScriptIterator (com.github.anba.es6draft.runtime.internal.ScriptIterator)1