Search in sources :

Example 26 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump 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)

Example 27 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump 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()) {
            // stack: [] -> [TDZ]
            newDeclarativeEnvironment(scope, mv);
            mv.enterVariableScope();
            Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
            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 || iterationKind == IterationKind.EnumerateValues) {
        /* 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 */
        if (codegen.isEnabled(CompatibilityOption.LegacyGenerator)) {
            // legacy generator mode, both, for-in and for-each, perform Iterate on generators
            Jump l0 = new Jump(), l1 = new Jump();
            mv.dup();
            mv.instanceOf(Types.GeneratorObject);
            mv.ifeq(l0);
            mv.dup();
            mv.checkcast(Types.GeneratorObject);
            mv.invoke(Methods.GeneratorObject_isLegacyGenerator);
            mv.ifeq(l0);
            mv.loadExecutionContext();
            mv.lineInfo(expr);
            mv.invoke(Methods.ScriptRuntime_iterate);
            mv.goTo(l1);
            mv.mark(l0);
            mv.loadExecutionContext();
            if (iterationKind == IterationKind.Enumerate) {
                mv.lineInfo(expr);
                mv.invoke(Methods.ScriptRuntime_enumerate);
            } else {
                mv.lineInfo(expr);
                mv.invoke(Methods.ScriptRuntime_enumerateValues);
            }
            mv.mark(l1);
        } else if (iterationKind == IterationKind.Enumerate) {
            mv.loadExecutionContext();
            mv.lineInfo(expr);
            mv.invoke(Methods.ScriptRuntime_enumerate);
        } else {
            mv.loadExecutionContext();
            mv.lineInfo(expr);
            mv.invoke(Methods.ScriptRuntime_enumerateValues);
        }
    } else if (iterationKind == IterationKind.AsyncIterate) {
        mv.loadExecutionContext();
        mv.lineInfo(expr);
        mv.invoke(Methods.ScriptRuntime_asyncIterate);
    } else {
        /* step 8 */
        assert iterationKind == IterationKind.Iterate;
        mv.loadExecutionContext();
        mv.lineInfo(expr);
        mv.invoke(Methods.ScriptRuntime_iterate);
    }
    return type;
}
Also used : BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) Jump(com.github.anba.es6draft.compiler.assembler.Jump) InitializeBoundName(com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name)

Example 28 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class StatementGenerator method visitForInOfLoop.

/**
     * 13.7.5.11 Runtime Semantics: LabelledEvaluation
     * 
     * @param <FORSTATEMENT>
     *            the for-statement node type
     * @param node
     *            the for-statement node
     * @param expr
     *            the expression node
     * @param lhs
     *            the left-hand side node
     * @param stmt
     *            the statement node
     * @param iterationKind
     *            the for-statement's iteration kind
     * @param mv
     *            the code visitor
     * @return the completion value
     */
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion visitForInOfLoop(FORSTATEMENT node, IterationKind iterationKind, CodeVisitor mv) {
    assert mv.getStackSize() == 0;
    Jump lblFail = new Jump();
    /* steps 1-2 */
    ValType type = ForInOfHeadEvaluation(node, iterationKind, lblFail, mv);
    /* step 3 */
    Completion result;
    if (iterationKind != IterationKind.AsyncIterate) {
        result = ForInOfBodyEvaluation(node, mv);
    } else {
        result = AsyncForInOfBodyEvaluation(node, mv);
    }
    if (type != ValType.Object) {
        mv.mark(lblFail);
    }
    return result;
}
Also used : Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 29 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class StatementGenerator method ForInOfBodyEvaluation.

/**
     * 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 ForInOfBodyEvaluation(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<?>> iterator = mv.newVariable("iter", ScriptIterator.class).uncheckedCast();
    // stack: [Iterator] -> []
    mv.store(iterator);
    Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
    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);
    mv.load(iterator);
    mv.lineInfo(node);
    mv.invoke(Methods.Iterator_next);
    mv.store(nextValue);
    /* steps 5.f-l */
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        mv.enterWrapped();
        new IterationGenerator<FORSTATEMENT>(codegen) {

            @Override
            protected Completion iterationBody(FORSTATEMENT node, Variable<ScriptIterator<?>> 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);
            }
        }.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(iterator);
    mv.lineInfo(node);
    mv.invoke(Methods.Iterator_hasNext);
    mv.ifne(enter);
    /* steps 5.m-n */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    return Completion.Normal;
}
Also used : 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 30 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class StatementGenerator method ForBodyEvaluation.

/**
     * 13.7.4.8 Runtime Semantics: ForBodyEvaluation(test, increment, stmt, perIterationBindings,
     * labelSet)
     */
private Completion ForBodyEvaluation(ForStatement node, boolean perIterationsLets, CodeVisitor mv) {
    assert mv.getStackSize() == 0;
    mv.enterVariableScope();
    /* step 1 */
    if (node.hasCompletionValue()) {
        mv.storeUndefinedAsCompletionValue();
    }
    /* steps 2-3 */
    Variable<LexicalEnvironment<?>> savedEnv;
    if (perIterationsLets) {
        savedEnv = mv.newVariable("savedEnv", LexicalEnvironment.class).uncheckedCast();
        CreatePerIterationEnvironment(savedEnv, mv);
    } else {
        savedEnv = saveEnvironment(node, mv);
    }
    Jump lblTest = new Jump(), lblStmt = new Jump();
    ContinueLabel lblContinue = new ContinueLabel();
    BreakLabel lblBreak = new BreakLabel();
    Bool btest = node.getTest() != null ? Bool.evaluate(node.getTest()) : Bool.True;
    /* steps 4.b-d */
    Completion result;
    if (btest != Bool.True) {
        mv.nonDestructiveGoTo(lblTest);
    }
    mv.mark(lblStmt);
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        result = node.getStatement().accept(this, mv);
        mv.exitIteration(node);
    }
    /* step 4.c (abrupt completion - continue) */
    if (lblContinue.isTarget()) {
        mv.mark(lblContinue);
        restoreEnvironment(savedEnv, mv);
    }
    /* steps 4.e-f */
    if (perIterationsLets && (!result.isAbrupt() || lblContinue.isTarget())) {
        CreatePerIterationEnvironment(savedEnv, mv);
    }
    /* step 4.g */
    if (node.getStep() != null && (!result.isAbrupt() || lblContinue.isTarget())) {
        ValType type = expression(node.getStep().emptyCompletion(), mv);
        mv.pop(type);
    }
    /* step 4.a */
    if (btest != Bool.True) {
        mv.mark(lblTest);
        ValType type = expression(node.getTest(), mv);
        ToBoolean(type, mv);
        mv.ifne(lblStmt);
    } else {
        mv.goTo(lblStmt);
    }
    /* step 4.c (abrupt completion - break) */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    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

Jump (com.github.anba.es6draft.compiler.assembler.Jump)46 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)14 Name (com.github.anba.es6draft.ast.scope.Name)10 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)9 DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)9 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)8 TryCatchLabel (com.github.anba.es6draft.compiler.assembler.TryCatchLabel)7 GlobalEnvironmentRecord (com.github.anba.es6draft.runtime.GlobalEnvironmentRecord)7 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)7 ScriptName (com.github.anba.es6draft.compiler.CodeGenerator.ScriptName)6 BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)6 TempLabel (com.github.anba.es6draft.compiler.Labels.TempLabel)6 Variable (com.github.anba.es6draft.compiler.assembler.Variable)6 EnvironmentRecord (com.github.anba.es6draft.runtime.EnvironmentRecord)6 ContinueLabel (com.github.anba.es6draft.compiler.Labels.ContinueLabel)5 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)5 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)4 FunctionDeclaration (com.github.anba.es6draft.ast.FunctionDeclaration)3 HoistableDeclaration (com.github.anba.es6draft.ast.HoistableDeclaration)3 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)3