Search in sources :

Example 6 with SwitchClause

use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.

the class SwitchStatementGenerator method Entries.

private static long[] Entries(List<SwitchClause> clauses, ToIntFunction<Expression> value) {
    boolean hasDefault = hasDefaultClause(clauses);
    long[] entries = new long[clauses.size() - (hasDefault ? 1 : 0)];
    for (int i = 0, j = 0, size = clauses.size(); i < size; ++i) {
        SwitchClause switchClause = clauses.get(i);
        if (!switchClause.isDefaultClause()) {
            entries[j++] = Entry(value.applyAsInt(switchClause.getExpression()), i);
        }
    }
    // sort values in ascending order
    Arrays.sort(entries);
    return entries;
}
Also used : SwitchClause(com.github.anba.es6draft.ast.SwitchClause)

Example 7 with SwitchClause

use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.

the class SwitchStatementGenerator method emitGenericSwitch.

/**
 * <h3>Generic-switch</h3>
 *
 * <pre>
 * switch (v) {
 * case key1: ...
 * case key2: ...
 * }
 *
 * var $v = v;
 * if (strictEquals($v, key1)) goto L1
 * if (strictEquals($v, key2)) goto L2
 * goTo (default | break)
 * L1: ...
 * L2: ...
 * </pre>
 *
 * @param clauses
 *            the switch clauses
 * @param switchValue
 *            the variable which holds the switch value
 * @param labels
 *            the labels for each switch clause
 * @param defaultOrExit
 *            the default clause or exit label
 * @param mv
 *            the code visitor
 */
private void emitGenericSwitch(List<SwitchClause> clauses, Variable<?> switchValue, Jump[] labels, Jump defaultOrExit, CodeVisitor mv) {
    assert switchValue.getType().equals(Types.Object);
    int index = 0;
    for (SwitchClause switchClause : clauses) {
        Jump caseLabel = labels[index++];
        if (!switchClause.isDefaultClause()) {
            mv.load(switchValue);
            // 13.11.10 Runtime Semantics: CaseSelectorEvaluation
            expressionBoxed(switchClause.getExpression(), mv);
            invokeDynamicOperator(BinaryExpression.Operator.SHEQ, mv);
            mv.ifne(caseLabel);
        }
    }
    mv.goTo(defaultOrExit);
}
Also used : SwitchClause(com.github.anba.es6draft.ast.SwitchClause) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 8 with SwitchClause

use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.

the class SwitchStatementGenerator method caseBlock.

/**
 * Generates a case-block method.
 *
 * @param caseBlock
 *            the case-block
 * @param mv
 *            the code visitor
 * @return the outlined-call object
 */
private OutlinedCall caseBlock(SwitchStatementGenerator.CaseBlock caseBlock, CodeVisitor mv) {
    SwitchClause firstClause = caseBlock.clauses.get(0);
    MethodTypeDescriptor methodDescriptor = SwitchBlockCodeVisitor.methodDescriptor(mv);
    MethodCode method = codegen.method(mv, "case", methodDescriptor);
    return outlined(new SwitchBlockCodeVisitor(firstClause, method, mv), body -> {
        Variable<Integer> switchTarget = body.getSwitchTargetParameter();
        List<SwitchClause> clauses = caseBlock.clauses;
        int[] switchTargets = caseBlock.switchTargets;
        int numTargets = caseBlock.numTargets();
        Completion lastResult = Completion.Normal;
        if (numTargets > 1) {
            Jump[] labels = new Jump[numTargets];
            for (int i = 0; i < labels.length; ++i) {
                labels[i] = new Jump();
            }
            Jump defaultInstr = new Jump();
            body.load(switchTarget);
            body.tableswitch(1, numTargets, defaultInstr, labels);
            body.mark(defaultInstr);
            for (int i = 0, lastTarget = 0; i < clauses.size(); ++i) {
                if (lastTarget != switchTargets[i]) {
                    lastTarget = switchTargets[i];
                    body.mark(labels[lastTarget - 1]);
                }
                lastResult = clauses.get(i).accept(this, body);
            }
        } else {
            for (SwitchClause clause : clauses) {
                lastResult = clause.accept(this, body);
            }
        }
        return lastResult;
    });
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) SwitchClause(com.github.anba.es6draft.ast.SwitchClause) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) Jump(com.github.anba.es6draft.compiler.assembler.Jump) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Aggregations

SwitchClause (com.github.anba.es6draft.ast.SwitchClause)8 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)5 Jump (com.github.anba.es6draft.compiler.assembler.Jump)5 MethodCode (com.github.anba.es6draft.compiler.assembler.Code.MethodCode)3 MethodTypeDescriptor (com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)3 OutlinedCall (com.github.anba.es6draft.compiler.CodeVisitor.OutlinedCall)2