Search in sources :

Example 1 with TableSwitchGenerator

use of org.objectweb.asm.commons.TableSwitchGenerator in project closure-templates by google.

the class DetachState method generateReattachTable.

/**
 * Returns a statement that generates the reattach jump table.
 *
 * <p>Note: This statement should be the <em>first</em> statement in any detachable method.
 */
Statement generateReattachTable() {
    final Expression readField = stateField.accessor(thisExpr);
    final Statement defaultCase = Statement.throwExpression(MethodRef.RUNTIME_UNEXPECTED_STATE_ERROR.invoke(readField));
    return new Statement() {

        @Override
        protected void doGen(final CodeBuilder adapter) {
            int[] keys = new int[reattaches.size()];
            for (int i = 0; i < keys.length; i++) {
                keys[i] = i;
            }
            readField.gen(adapter);
            // Generate a switch table.  Note, while it might be preferable to just 'goto state', Java
            // doesn't allow computable gotos (probably because it makes verification impossible).  So
            // instead we emulate that with a jump table.  And anyway we still need to execute 'restore'
            // logic to repopulate the local variable tables, so the 'case' statements are a natural
            // place for that logic to live.
            adapter.tableSwitch(keys, new TableSwitchGenerator() {

                @Override
                public void generateCase(int key, Label end) {
                    if (key == 0) {
                        // State 0 is special, it means initial state, so we just jump to the very end
                        adapter.goTo(end);
                        return;
                    }
                    ReattachState reattachState = reattaches.get(key);
                    // restore and jump!
                    reattachState.restoreStatement().gen(adapter);
                    adapter.goTo(reattachState.reattachPoint());
                }

                @Override
                public void generateDefault() {
                    defaultCase.gen(adapter);
                }
            }, // there are no 'holes' meaning that it is compact in the bytecode.
            true);
        }
    };
}
Also used : Expression(com.google.template.soy.jbcsrc.restricted.Expression) Statement.returnExpression(com.google.template.soy.jbcsrc.restricted.Statement.returnExpression) TableSwitchGenerator(org.objectweb.asm.commons.TableSwitchGenerator) Statement(com.google.template.soy.jbcsrc.restricted.Statement) Label(org.objectweb.asm.Label) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder)

Aggregations

CodeBuilder (com.google.template.soy.jbcsrc.restricted.CodeBuilder)1 Expression (com.google.template.soy.jbcsrc.restricted.Expression)1 Statement (com.google.template.soy.jbcsrc.restricted.Statement)1 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)1 Label (org.objectweb.asm.Label)1 TableSwitchGenerator (org.objectweb.asm.commons.TableSwitchGenerator)1