Search in sources :

Example 1 with TempLabel

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

the class StatementGenerator method emitFinallyBlock.

private Completion emitFinallyBlock(TryStatement node, Variable<LexicalEnvironment<?>> savedEnv, Value<Object> completion, Completion tryResult, Completion catchResult, TryCatchLabel handlerFinally, TryCatchLabel handlerFinallyStackOverflow, Jump noException, List<TempLabel> tempLabels, CodeVisitor mv) {
    BlockStatement finallyBlock = node.getFinallyBlock();
    assert finallyBlock != null;
    // various finally blocks (1 - 4)
    // (1) finally block for abrupt throw completions within 'try-catch'
    mv.enterVariableScope();
    Variable<Throwable> throwable = mv.newVariable("throwable", Throwable.class);
    mv.catchHandler(handlerFinallyStackOverflow, Types.Error);
    mv.invoke(Methods.ErrorOperations_stackOverflowError);
    mv.catchHandler(handlerFinally, Types.ScriptException);
    mv.store(throwable);
    restoreEnvironment(savedEnv, mv);
    Completion finallyResult = finallyBlock.accept(this, mv);
    if (!finallyResult.isAbrupt()) {
        mv.load(throwable);
        mv.athrow();
    }
    mv.exitVariableScope();
    // (2) finally block if 'try' did not complete abruptly
    // (3) finally block if 'catch' did not complete abruptly
    Jump exceptionHandled = null;
    if (!tryResult.isAbrupt() || !catchResult.isAbrupt()) {
        mv.mark(noException);
        finallyBlock.accept(this, mv);
        if (!finallyResult.isAbrupt()) {
            if (node.hasCompletionValue()) {
                mv.storeCompletionValue(completion);
            }
            if (!tempLabels.isEmpty()) {
                exceptionHandled = new Jump();
                mv.goTo(exceptionHandled);
            }
        }
    }
    // (4) finally blocks for other abrupt completion (return, break, continue)
    for (TempLabel temp : tempLabels) {
        if (temp.isTarget()) {
            mv.mark(temp);
            restoreEnvironment(savedEnv, mv);
            finallyBlock.accept(this, mv);
            if (!finallyResult.isAbrupt()) {
                if (node.hasCompletionValue()) {
                    mv.storeCompletionValue(completion);
                }
                mv.goTo(temp, completion);
            }
        }
    }
    if (exceptionHandled != null) {
        mv.mark(exceptionHandled);
    }
    return finallyResult;
}
Also used : Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel)

Example 2 with TempLabel

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

the class StatementGenerator method visitTryCatchFinally.

/**
 * 13.15.8 Runtime Semantics: Evaluation<br>
 *
 * <code>try-catch-finally</code>
 *
 * @param node
 *            the try-statement
 * @param mv
 *            the code visitor
 * @return the completion value
 */
private Completion visitTryCatchFinally(TryStatement node, CodeVisitor mv) {
    TryCatchLabel startCatchFinally = new TryCatchLabel();
    TryCatchLabel endCatch = new TryCatchLabel(), handlerCatch = new TryCatchLabel();
    TryCatchLabel endFinally = new TryCatchLabel(), handlerFinally = new TryCatchLabel();
    TryCatchLabel handlerCatchStackOverflow = new TryCatchLabel();
    TryCatchLabel handlerFinallyStackOverflow = new TryCatchLabel();
    Jump noException = new Jump();
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(mv);
    MutableValue<Object> completion = mv.enterFinallyScoped(node);
    /* step 1 */
    // Emit try-block
    mv.mark(startCatchFinally);
    Completion tryResult = emitTryBlock(node, noException, mv);
    mv.mark(endCatch);
    /* steps 2-3 */
    // Emit catch-block
    Completion catchResult = emitCatchBlock(node, savedEnv, handlerCatch, handlerCatchStackOverflow, mv);
    if (!catchResult.isAbrupt()) {
        mv.goTo(noException);
    }
    mv.mark(endFinally);
    // Restore temporary abrupt targets
    List<TempLabel> tempLabels = mv.exitFinallyScoped();
    /* step 4 */
    // Emit finally-block
    Completion finallyResult = emitFinallyBlock(node, savedEnv, completion, tryResult, catchResult, handlerFinally, handlerFinallyStackOverflow, noException, tempLabels, mv);
    mv.exitVariableScope();
    mv.tryCatch(startCatchFinally, endCatch, handlerCatch, Types.ScriptException);
    mv.tryCatch(startCatchFinally, endCatch, handlerCatchStackOverflow, Types.Error);
    mv.tryCatch(startCatchFinally, endFinally, handlerFinally, Types.ScriptException);
    mv.tryCatch(startCatchFinally, endFinally, handlerFinallyStackOverflow, Types.Error);
    /* steps 5-8 */
    return finallyResult.then(tryResult.select(catchResult));
}
Also used : LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel)

Example 3 with TempLabel

use of com.github.anba.es6draft.compiler.Labels.TempLabel 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<ScriptIterator<?>> iterRec = mv.newVariable("iterRec", ScriptIterator.class).uncheckedCast();
    Variable<ScriptObject> iterator = mv.newVariable("iter", ScriptObject.class);
    // stack: [Iterator] -> []
    mv.store(iterRec);
    mv.load(iterRec);
    mv.invoke(Methods.ScriptIterator_getScriptObject);
    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);
    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);
    mv.load(iterRec);
    mv.invoke(Methods.ScriptIterator_nextIterResult);
    await(node, mv);
    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) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator) 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 4 with TempLabel

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

the class AbstractIterationGenerator method emitReturnHandler.

private void emitReturnHandler(NODE node, Variable<ITERATOR> iterator, Value<Object> completion, List<TempLabel> tempLabels, CodeVisitor mv) {
    // (1) Intercept return instructions
    for (TempLabel temp : tempLabels) {
        if (temp.isTarget()) {
            mv.mark(temp);
            IteratorClose(node, iterator, mv);
            mv.goTo(temp, completion);
        }
    }
}
Also used : TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel)

Example 5 with TempLabel

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

the class AbstractIterationGenerator method generate.

/**
 * Emit code for the wrapped iteration.
 *
 * @param node
 *            the ast node
 * @param iterator
 *            the iterator variable
 * @param target
 *            the target label
 * @param mv
 *            the code visitor
 * @return the completion value
 */
public final Completion generate(NODE node, Variable<ITERATOR> iterator, Jump target, CodeVisitor mv) {
    TryCatchLabel startIteration = new TryCatchLabel(), endIteration = new TryCatchLabel();
    TryCatchLabel handlerCatch = new TryCatchLabel();
    TryCatchLabel handlerCatchStackOverflow = null;
    if (codegen.isEnabled(Compiler.Option.IterationCatchStackOverflow)) {
        handlerCatchStackOverflow = new TryCatchLabel();
    }
    boolean hasTarget = target != null;
    if (!hasTarget) {
        target = new Jump();
    }
    mv.enterVariableScope();
    MutableValue<Object> completion = enterIteration(node, mv);
    // Emit loop body
    mv.mark(startIteration);
    Completion loopBodyResult = iterationBody(node, iterator, mv);
    if (!loopBodyResult.isAbrupt()) {
        mv.goTo(target);
    }
    mv.mark(endIteration);
    // Restore temporary abrupt targets
    List<TempLabel> tempLabels = exitIteration(node, mv);
    // Emit throw handler
    emitThrowHandler(node, iterator, handlerCatch, handlerCatchStackOverflow, mv);
    // Emit return handler
    emitReturnHandler(node, iterator, completion, tempLabels, mv);
    mv.exitVariableScope();
    mv.tryCatch(startIteration, endIteration, handlerCatch, Types.ScriptException);
    if (handlerCatchStackOverflow != null) {
        mv.tryCatch(startIteration, endIteration, handlerCatchStackOverflow, Types.Error);
    }
    if (!hasTarget) {
        mv.mark(target);
        epilogue(node, iterator, mv);
    }
    return loopBodyResult;
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel)

Aggregations

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