/** See {@link GeneratorAdapter#tableSwitch(int[], TableSwitchGenerator)} */ public void tableSwitch(int[] keys, TableSwitchGenerator generator) { adapter.tableSwitch(keys, generator); }
/** See {@link GeneratorAdapter#tableSwitch(int[], TableSwitchGenerator, boolean)} */ public void tableSwitch(int[] keys, TableSwitchGenerator generator, boolean useTable) { adapter.tableSwitch(keys, generator, useTable); }
/** * 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); } }, // Use tableswitch instead of lookupswitch. TableSwitch is appropriate because our case // labels are sequential integers in the range [0, N). This means that switch is O(1) // and // there are no 'holes' meaning that it is compact in the bytecode. true); } }; }