| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
package jdk.internal.org.objectweb.asm.commons;  | 
 | 
 | 
 | 
import java.util.ArrayList;  | 
 | 
import java.util.HashMap;  | 
 | 
import java.util.List;  | 
 | 
import java.util.Map;  | 
 | 
 | 
 | 
import jdk.internal.org.objectweb.asm.Handle;  | 
 | 
import jdk.internal.org.objectweb.asm.Label;  | 
 | 
import jdk.internal.org.objectweb.asm.MethodVisitor;  | 
 | 
import jdk.internal.org.objectweb.asm.Opcodes;  | 
 | 
import jdk.internal.org.objectweb.asm.Type;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class AnalyzerAdapter extends MethodVisitor { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public List<Object> locals;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public List<Object> stack;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private List<Label> labels;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public Map<Object, Object> uninitializedTypes;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private int maxStack;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private int maxLocals;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private String owner;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public AnalyzerAdapter(final String owner, final int access,  | 
 | 
            final String name, final String desc, final MethodVisitor mv) { | 
 | 
        this(Opcodes.ASM6, owner, access, name, desc, mv);  | 
 | 
        if (getClass() != AnalyzerAdapter.class) { | 
 | 
            throw new IllegalStateException();  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected AnalyzerAdapter(final int api, final String owner,  | 
 | 
            final int access, final String name, final String desc,  | 
 | 
            final MethodVisitor mv) { | 
 | 
        super(api, mv);  | 
 | 
        this.owner = owner;  | 
 | 
        locals = new ArrayList<Object>();  | 
 | 
        stack = new ArrayList<Object>();  | 
 | 
        uninitializedTypes = new HashMap<Object, Object>();  | 
 | 
 | 
 | 
        if ((access & Opcodes.ACC_STATIC) == 0) { | 
 | 
            if ("<init>".equals(name)) { | 
 | 
                locals.add(Opcodes.UNINITIALIZED_THIS);  | 
 | 
            } else { | 
 | 
                locals.add(owner);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        Type[] types = Type.getArgumentTypes(desc);  | 
 | 
        for (int i = 0; i < types.length; ++i) { | 
 | 
            Type type = types[i];  | 
 | 
            switch (type.getSort()) { | 
 | 
            case Type.BOOLEAN:  | 
 | 
            case Type.CHAR:  | 
 | 
            case Type.BYTE:  | 
 | 
            case Type.SHORT:  | 
 | 
            case Type.INT:  | 
 | 
                locals.add(Opcodes.INTEGER);  | 
 | 
                break;  | 
 | 
            case Type.FLOAT:  | 
 | 
                locals.add(Opcodes.FLOAT);  | 
 | 
                break;  | 
 | 
            case Type.LONG:  | 
 | 
                locals.add(Opcodes.LONG);  | 
 | 
                locals.add(Opcodes.TOP);  | 
 | 
                break;  | 
 | 
            case Type.DOUBLE:  | 
 | 
                locals.add(Opcodes.DOUBLE);  | 
 | 
                locals.add(Opcodes.TOP);  | 
 | 
                break;  | 
 | 
            case Type.ARRAY:  | 
 | 
                locals.add(types[i].getDescriptor());  | 
 | 
                break;  | 
 | 
              | 
 | 
            default:  | 
 | 
                locals.add(types[i].getInternalName());  | 
 | 
            }  | 
 | 
        }  | 
 | 
        maxLocals = locals.size();  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitFrame(final int type, final int nLocal,  | 
 | 
            final Object[] local, final int nStack, final Object[] stack) { | 
 | 
        if (type != Opcodes.F_NEW) {  | 
 | 
            throw new IllegalStateException(  | 
 | 
                    "ClassReader.accept() should be called with EXPAND_FRAMES flag");  | 
 | 
        }  | 
 | 
 | 
 | 
        if (mv != null) { | 
 | 
            mv.visitFrame(type, nLocal, local, nStack, stack);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (this.locals != null) { | 
 | 
            this.locals.clear();  | 
 | 
            this.stack.clear();  | 
 | 
        } else { | 
 | 
            this.locals = new ArrayList<Object>();  | 
 | 
            this.stack = new ArrayList<Object>();  | 
 | 
        }  | 
 | 
        visitFrameTypes(nLocal, local, this.locals);  | 
 | 
        visitFrameTypes(nStack, stack, this.stack);  | 
 | 
        maxStack = Math.max(maxStack, this.stack.size());  | 
 | 
    }  | 
 | 
 | 
 | 
    private static void visitFrameTypes(final int n, final Object[] types,  | 
 | 
            final List<Object> result) { | 
 | 
        for (int i = 0; i < n; ++i) { | 
 | 
            Object type = types[i];  | 
 | 
            result.add(type);  | 
 | 
            if (type == Opcodes.LONG || type == Opcodes.DOUBLE) { | 
 | 
                result.add(Opcodes.TOP);  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitInsn(final int opcode) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitInsn(opcode);  | 
 | 
        }  | 
 | 
        execute(opcode, 0, null);  | 
 | 
        if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)  | 
 | 
                || opcode == Opcodes.ATHROW) { | 
 | 
            this.locals = null;  | 
 | 
            this.stack = null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitIntInsn(final int opcode, final int operand) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitIntInsn(opcode, operand);  | 
 | 
        }  | 
 | 
        execute(opcode, operand, null);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitVarInsn(final int opcode, final int var) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitVarInsn(opcode, var);  | 
 | 
        }  | 
 | 
        execute(opcode, var, null);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitTypeInsn(final int opcode, final String type) { | 
 | 
        if (opcode == Opcodes.NEW) { | 
 | 
            if (labels == null) { | 
 | 
                Label l = new Label();  | 
 | 
                labels = new ArrayList<Label>(3);  | 
 | 
                labels.add(l);  | 
 | 
                if (mv != null) { | 
 | 
                    mv.visitLabel(l);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            for (int i = 0; i < labels.size(); ++i) { | 
 | 
                uninitializedTypes.put(labels.get(i), type);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        if (mv != null) { | 
 | 
            mv.visitTypeInsn(opcode, type);  | 
 | 
        }  | 
 | 
        execute(opcode, 0, type);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitFieldInsn(final int opcode, final String owner,  | 
 | 
            final String name, final String desc) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitFieldInsn(opcode, owner, name, desc);  | 
 | 
        }  | 
 | 
        execute(opcode, 0, desc);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Deprecated  | 
 | 
    @Override  | 
 | 
    public void visitMethodInsn(final int opcode, final String owner,  | 
 | 
            final String name, final String desc) { | 
 | 
        if (api >= Opcodes.ASM5) { | 
 | 
            super.visitMethodInsn(opcode, owner, name, desc);  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        doVisitMethodInsn(opcode, owner, name, desc,  | 
 | 
                opcode == Opcodes.INVOKEINTERFACE);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitMethodInsn(final int opcode, final String owner,  | 
 | 
            final String name, final String desc, final boolean itf) { | 
 | 
        if (api < Opcodes.ASM5) { | 
 | 
            super.visitMethodInsn(opcode, owner, name, desc, itf);  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        doVisitMethodInsn(opcode, owner, name, desc, itf);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void doVisitMethodInsn(int opcode, final String owner,  | 
 | 
            final String name, final String desc, final boolean itf) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitMethodInsn(opcode, owner, name, desc, itf);  | 
 | 
        }  | 
 | 
        if (this.locals == null) { | 
 | 
            labels = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        pop(desc);  | 
 | 
        if (opcode != Opcodes.INVOKESTATIC) { | 
 | 
            Object t = pop();  | 
 | 
            if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') { | 
 | 
                Object u;  | 
 | 
                if (t == Opcodes.UNINITIALIZED_THIS) { | 
 | 
                    u = this.owner;  | 
 | 
                } else { | 
 | 
                    u = uninitializedTypes.get(t);  | 
 | 
                }  | 
 | 
                for (int i = 0; i < locals.size(); ++i) { | 
 | 
                    if (locals.get(i) == t) { | 
 | 
                        locals.set(i, u);  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                for (int i = 0; i < stack.size(); ++i) { | 
 | 
                    if (stack.get(i) == t) { | 
 | 
                        stack.set(i, u);  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
        pushDesc(desc);  | 
 | 
        labels = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,  | 
 | 
            Object... bsmArgs) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);  | 
 | 
        }  | 
 | 
        if (this.locals == null) { | 
 | 
            labels = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        pop(desc);  | 
 | 
        pushDesc(desc);  | 
 | 
        labels = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitJumpInsn(final int opcode, final Label label) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitJumpInsn(opcode, label);  | 
 | 
        }  | 
 | 
        execute(opcode, 0, null);  | 
 | 
        if (opcode == Opcodes.GOTO) { | 
 | 
            this.locals = null;  | 
 | 
            this.stack = null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitLabel(final Label label) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitLabel(label);  | 
 | 
        }  | 
 | 
        if (labels == null) { | 
 | 
            labels = new ArrayList<Label>(3);  | 
 | 
        }  | 
 | 
        labels.add(label);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitLdcInsn(final Object cst) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitLdcInsn(cst);  | 
 | 
        }  | 
 | 
        if (this.locals == null) { | 
 | 
            labels = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        if (cst instanceof Integer) { | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
        } else if (cst instanceof Long) { | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
        } else if (cst instanceof Float) { | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
        } else if (cst instanceof Double) { | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
        } else if (cst instanceof String) { | 
 | 
            push("java/lang/String"); | 
 | 
        } else if (cst instanceof Type) { | 
 | 
            int sort = ((Type) cst).getSort();  | 
 | 
            if (sort == Type.OBJECT || sort == Type.ARRAY) { | 
 | 
                push("java/lang/Class"); | 
 | 
            } else if (sort == Type.METHOD) { | 
 | 
                push("java/lang/invoke/MethodType"); | 
 | 
            } else { | 
 | 
                throw new IllegalArgumentException();  | 
 | 
            }  | 
 | 
        } else if (cst instanceof Handle) { | 
 | 
            push("java/lang/invoke/MethodHandle"); | 
 | 
        } else { | 
 | 
            throw new IllegalArgumentException();  | 
 | 
        }  | 
 | 
        labels = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitIincInsn(final int var, final int increment) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitIincInsn(var, increment);  | 
 | 
        }  | 
 | 
        execute(Opcodes.IINC, var, null);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitTableSwitchInsn(final int min, final int max,  | 
 | 
            final Label dflt, final Label... labels) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitTableSwitchInsn(min, max, dflt, labels);  | 
 | 
        }  | 
 | 
        execute(Opcodes.TABLESWITCH, 0, null);  | 
 | 
        this.locals = null;  | 
 | 
        this.stack = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,  | 
 | 
            final Label[] labels) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitLookupSwitchInsn(dflt, keys, labels);  | 
 | 
        }  | 
 | 
        execute(Opcodes.LOOKUPSWITCH, 0, null);  | 
 | 
        this.locals = null;  | 
 | 
        this.stack = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitMultiANewArrayInsn(final String desc, final int dims) { | 
 | 
        if (mv != null) { | 
 | 
            mv.visitMultiANewArrayInsn(desc, dims);  | 
 | 
        }  | 
 | 
        execute(Opcodes.MULTIANEWARRAY, dims, desc);  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public void visitMaxs(final int maxStack, final int maxLocals) { | 
 | 
        if (mv != null) { | 
 | 
            this.maxStack = Math.max(this.maxStack, maxStack);  | 
 | 
            this.maxLocals = Math.max(this.maxLocals, maxLocals);  | 
 | 
            mv.visitMaxs(this.maxStack, this.maxLocals);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    // ------------------------------------------------------------------------  | 
 | 
 | 
 | 
    private Object get(final int local) { | 
 | 
        maxLocals = Math.max(maxLocals, local + 1);  | 
 | 
        return local < locals.size() ? locals.get(local) : Opcodes.TOP;  | 
 | 
    }  | 
 | 
 | 
 | 
    private void set(final int local, final Object type) { | 
 | 
        maxLocals = Math.max(maxLocals, local + 1);  | 
 | 
        while (local >= locals.size()) { | 
 | 
            locals.add(Opcodes.TOP);  | 
 | 
        }  | 
 | 
        locals.set(local, type);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void push(final Object type) { | 
 | 
        stack.add(type);  | 
 | 
        maxStack = Math.max(maxStack, stack.size());  | 
 | 
    }  | 
 | 
 | 
 | 
    private void pushDesc(final String desc) { | 
 | 
        int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; | 
 | 
        switch (desc.charAt(index)) { | 
 | 
        case 'V':  | 
 | 
            return;  | 
 | 
        case 'Z':  | 
 | 
        case 'C':  | 
 | 
        case 'B':  | 
 | 
        case 'S':  | 
 | 
        case 'I':  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            return;  | 
 | 
        case 'F':  | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
            return;  | 
 | 
        case 'J':  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            return;  | 
 | 
        case 'D':  | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            return;  | 
 | 
        case '[':  | 
 | 
            if (index == 0) { | 
 | 
                push(desc);  | 
 | 
            } else { | 
 | 
                push(desc.substring(index, desc.length()));  | 
 | 
            }  | 
 | 
            break;  | 
 | 
          | 
 | 
        default:  | 
 | 
            if (index == 0) { | 
 | 
                push(desc.substring(1, desc.length() - 1));  | 
 | 
            } else { | 
 | 
                push(desc.substring(index + 1, desc.length() - 1));  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private Object pop() { | 
 | 
        return stack.remove(stack.size() - 1);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void pop(final int n) { | 
 | 
        int size = stack.size();  | 
 | 
        int end = size - n;  | 
 | 
        for (int i = size - 1; i >= end; --i) { | 
 | 
            stack.remove(i);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private void pop(final String desc) { | 
 | 
        char c = desc.charAt(0);  | 
 | 
        if (c == '(') { | 
 | 
            int n = 0;  | 
 | 
            Type[] types = Type.getArgumentTypes(desc);  | 
 | 
            for (int i = 0; i < types.length; ++i) { | 
 | 
                n += types[i].getSize();  | 
 | 
            }  | 
 | 
            pop(n);  | 
 | 
        } else if (c == 'J' || c == 'D') { | 
 | 
            pop(2);  | 
 | 
        } else { | 
 | 
            pop(1);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private void execute(final int opcode, final int iarg, final String sarg) { | 
 | 
        if (this.locals == null) { | 
 | 
            labels = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
        Object t1, t2, t3, t4;  | 
 | 
        switch (opcode) { | 
 | 
        case Opcodes.NOP:  | 
 | 
        case Opcodes.INEG:  | 
 | 
        case Opcodes.LNEG:  | 
 | 
        case Opcodes.FNEG:  | 
 | 
        case Opcodes.DNEG:  | 
 | 
        case Opcodes.I2B:  | 
 | 
        case Opcodes.I2C:  | 
 | 
        case Opcodes.I2S:  | 
 | 
        case Opcodes.GOTO:  | 
 | 
        case Opcodes.RETURN:  | 
 | 
            break;  | 
 | 
        case Opcodes.ACONST_NULL:  | 
 | 
            push(Opcodes.NULL);  | 
 | 
            break;  | 
 | 
        case Opcodes.ICONST_M1:  | 
 | 
        case Opcodes.ICONST_0:  | 
 | 
        case Opcodes.ICONST_1:  | 
 | 
        case Opcodes.ICONST_2:  | 
 | 
        case Opcodes.ICONST_3:  | 
 | 
        case Opcodes.ICONST_4:  | 
 | 
        case Opcodes.ICONST_5:  | 
 | 
        case Opcodes.BIPUSH:  | 
 | 
        case Opcodes.SIPUSH:  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.LCONST_0:  | 
 | 
        case Opcodes.LCONST_1:  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.FCONST_0:  | 
 | 
        case Opcodes.FCONST_1:  | 
 | 
        case Opcodes.FCONST_2:  | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
            break;  | 
 | 
        case Opcodes.DCONST_0:  | 
 | 
        case Opcodes.DCONST_1:  | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.ILOAD:  | 
 | 
        case Opcodes.FLOAD:  | 
 | 
        case Opcodes.ALOAD:  | 
 | 
            push(get(iarg));  | 
 | 
            break;  | 
 | 
        case Opcodes.LLOAD:  | 
 | 
        case Opcodes.DLOAD:  | 
 | 
            push(get(iarg));  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.IALOAD:  | 
 | 
        case Opcodes.BALOAD:  | 
 | 
        case Opcodes.CALOAD:  | 
 | 
        case Opcodes.SALOAD:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.LALOAD:  | 
 | 
        case Opcodes.D2L:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.FALOAD:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
            break;  | 
 | 
        case Opcodes.DALOAD:  | 
 | 
        case Opcodes.L2D:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.AALOAD:  | 
 | 
            pop(1);  | 
 | 
            t1 = pop();  | 
 | 
            if (t1 instanceof String) { | 
 | 
                pushDesc(((String) t1).substring(1));  | 
 | 
            } else if (t1 == Opcodes.NULL) { | 
 | 
                push(t1);  | 
 | 
            } else { | 
 | 
                push("java/lang/Object"); | 
 | 
            }  | 
 | 
            break;  | 
 | 
        case Opcodes.ISTORE:  | 
 | 
        case Opcodes.FSTORE:  | 
 | 
        case Opcodes.ASTORE:  | 
 | 
            t1 = pop();  | 
 | 
            set(iarg, t1);  | 
 | 
            if (iarg > 0) { | 
 | 
                t2 = get(iarg - 1);  | 
 | 
                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { | 
 | 
                    set(iarg - 1, Opcodes.TOP);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            break;  | 
 | 
        case Opcodes.LSTORE:  | 
 | 
        case Opcodes.DSTORE:  | 
 | 
            pop(1);  | 
 | 
            t1 = pop();  | 
 | 
            set(iarg, t1);  | 
 | 
            set(iarg + 1, Opcodes.TOP);  | 
 | 
            if (iarg > 0) { | 
 | 
                t2 = get(iarg - 1);  | 
 | 
                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { | 
 | 
                    set(iarg - 1, Opcodes.TOP);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            break;  | 
 | 
        case Opcodes.IASTORE:  | 
 | 
        case Opcodes.BASTORE:  | 
 | 
        case Opcodes.CASTORE:  | 
 | 
        case Opcodes.SASTORE:  | 
 | 
        case Opcodes.FASTORE:  | 
 | 
        case Opcodes.AASTORE:  | 
 | 
            pop(3);  | 
 | 
            break;  | 
 | 
        case Opcodes.LASTORE:  | 
 | 
        case Opcodes.DASTORE:  | 
 | 
            pop(4);  | 
 | 
            break;  | 
 | 
        case Opcodes.POP:  | 
 | 
        case Opcodes.IFEQ:  | 
 | 
        case Opcodes.IFNE:  | 
 | 
        case Opcodes.IFLT:  | 
 | 
        case Opcodes.IFGE:  | 
 | 
        case Opcodes.IFGT:  | 
 | 
        case Opcodes.IFLE:  | 
 | 
        case Opcodes.IRETURN:  | 
 | 
        case Opcodes.FRETURN:  | 
 | 
        case Opcodes.ARETURN:  | 
 | 
        case Opcodes.TABLESWITCH:  | 
 | 
        case Opcodes.LOOKUPSWITCH:  | 
 | 
        case Opcodes.ATHROW:  | 
 | 
        case Opcodes.MONITORENTER:  | 
 | 
        case Opcodes.MONITOREXIT:  | 
 | 
        case Opcodes.IFNULL:  | 
 | 
        case Opcodes.IFNONNULL:  | 
 | 
            pop(1);  | 
 | 
            break;  | 
 | 
        case Opcodes.POP2:  | 
 | 
        case Opcodes.IF_ICMPEQ:  | 
 | 
        case Opcodes.IF_ICMPNE:  | 
 | 
        case Opcodes.IF_ICMPLT:  | 
 | 
        case Opcodes.IF_ICMPGE:  | 
 | 
        case Opcodes.IF_ICMPGT:  | 
 | 
        case Opcodes.IF_ICMPLE:  | 
 | 
        case Opcodes.IF_ACMPEQ:  | 
 | 
        case Opcodes.IF_ACMPNE:  | 
 | 
        case Opcodes.LRETURN:  | 
 | 
        case Opcodes.DRETURN:  | 
 | 
            pop(2);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP:  | 
 | 
            t1 = pop();  | 
 | 
            push(t1);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP_X1:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            push(t1);  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP_X2:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            t3 = pop();  | 
 | 
            push(t1);  | 
 | 
            push(t3);  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP2:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP2_X1:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            t3 = pop();  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            push(t3);  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.DUP2_X2:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            t3 = pop();  | 
 | 
            t4 = pop();  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            push(t4);  | 
 | 
            push(t3);  | 
 | 
            push(t2);  | 
 | 
            push(t1);  | 
 | 
            break;  | 
 | 
        case Opcodes.SWAP:  | 
 | 
            t1 = pop();  | 
 | 
            t2 = pop();  | 
 | 
            push(t1);  | 
 | 
            push(t2);  | 
 | 
            break;  | 
 | 
        case Opcodes.IADD:  | 
 | 
        case Opcodes.ISUB:  | 
 | 
        case Opcodes.IMUL:  | 
 | 
        case Opcodes.IDIV:  | 
 | 
        case Opcodes.IREM:  | 
 | 
        case Opcodes.IAND:  | 
 | 
        case Opcodes.IOR:  | 
 | 
        case Opcodes.IXOR:  | 
 | 
        case Opcodes.ISHL:  | 
 | 
        case Opcodes.ISHR:  | 
 | 
        case Opcodes.IUSHR:  | 
 | 
        case Opcodes.L2I:  | 
 | 
        case Opcodes.D2I:  | 
 | 
        case Opcodes.FCMPL:  | 
 | 
        case Opcodes.FCMPG:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.LADD:  | 
 | 
        case Opcodes.LSUB:  | 
 | 
        case Opcodes.LMUL:  | 
 | 
        case Opcodes.LDIV:  | 
 | 
        case Opcodes.LREM:  | 
 | 
        case Opcodes.LAND:  | 
 | 
        case Opcodes.LOR:  | 
 | 
        case Opcodes.LXOR:  | 
 | 
            pop(4);  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.FADD:  | 
 | 
        case Opcodes.FSUB:  | 
 | 
        case Opcodes.FMUL:  | 
 | 
        case Opcodes.FDIV:  | 
 | 
        case Opcodes.FREM:  | 
 | 
        case Opcodes.L2F:  | 
 | 
        case Opcodes.D2F:  | 
 | 
            pop(2);  | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
            break;  | 
 | 
        case Opcodes.DADD:  | 
 | 
        case Opcodes.DSUB:  | 
 | 
        case Opcodes.DMUL:  | 
 | 
        case Opcodes.DDIV:  | 
 | 
        case Opcodes.DREM:  | 
 | 
            pop(4);  | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.LSHL:  | 
 | 
        case Opcodes.LSHR:  | 
 | 
        case Opcodes.LUSHR:  | 
 | 
            pop(3);  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.IINC:  | 
 | 
            set(iarg, Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.I2L:  | 
 | 
        case Opcodes.F2L:  | 
 | 
            pop(1);  | 
 | 
            push(Opcodes.LONG);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.I2F:  | 
 | 
            pop(1);  | 
 | 
            push(Opcodes.FLOAT);  | 
 | 
            break;  | 
 | 
        case Opcodes.I2D:  | 
 | 
        case Opcodes.F2D:  | 
 | 
            pop(1);  | 
 | 
            push(Opcodes.DOUBLE);  | 
 | 
            push(Opcodes.TOP);  | 
 | 
            break;  | 
 | 
        case Opcodes.F2I:  | 
 | 
        case Opcodes.ARRAYLENGTH:  | 
 | 
        case Opcodes.INSTANCEOF:  | 
 | 
            pop(1);  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.LCMP:  | 
 | 
        case Opcodes.DCMPL:  | 
 | 
        case Opcodes.DCMPG:  | 
 | 
            pop(4);  | 
 | 
            push(Opcodes.INTEGER);  | 
 | 
            break;  | 
 | 
        case Opcodes.JSR:  | 
 | 
        case Opcodes.RET:  | 
 | 
            throw new RuntimeException("JSR/RET are not supported"); | 
 | 
        case Opcodes.GETSTATIC:  | 
 | 
            pushDesc(sarg);  | 
 | 
            break;  | 
 | 
        case Opcodes.PUTSTATIC:  | 
 | 
            pop(sarg);  | 
 | 
            break;  | 
 | 
        case Opcodes.GETFIELD:  | 
 | 
            pop(1);  | 
 | 
            pushDesc(sarg);  | 
 | 
            break;  | 
 | 
        case Opcodes.PUTFIELD:  | 
 | 
            pop(sarg);  | 
 | 
            pop();  | 
 | 
            break;  | 
 | 
        case Opcodes.NEW:  | 
 | 
            push(labels.get(0));  | 
 | 
            break;  | 
 | 
        case Opcodes.NEWARRAY:  | 
 | 
            pop();  | 
 | 
            switch (iarg) { | 
 | 
            case Opcodes.T_BOOLEAN:  | 
 | 
                pushDesc("[Z"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_CHAR:  | 
 | 
                pushDesc("[C"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_BYTE:  | 
 | 
                pushDesc("[B"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_SHORT:  | 
 | 
                pushDesc("[S"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_INT:  | 
 | 
                pushDesc("[I"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_FLOAT:  | 
 | 
                pushDesc("[F"); | 
 | 
                break;  | 
 | 
            case Opcodes.T_DOUBLE:  | 
 | 
                pushDesc("[D"); | 
 | 
                break;  | 
 | 
              | 
 | 
            default:  | 
 | 
                pushDesc("[J"); | 
 | 
                break;  | 
 | 
            }  | 
 | 
            break;  | 
 | 
        case Opcodes.ANEWARRAY:  | 
 | 
            pop();  | 
 | 
            pushDesc("[" + Type.getObjectType(sarg)); | 
 | 
            break;  | 
 | 
        case Opcodes.CHECKCAST:  | 
 | 
            pop();  | 
 | 
            pushDesc(Type.getObjectType(sarg).getDescriptor());  | 
 | 
            break;  | 
 | 
          | 
 | 
        default:  | 
 | 
            pop(iarg);  | 
 | 
            pushDesc(sarg);  | 
 | 
            break;  | 
 | 
        }  | 
 | 
        labels = null;  | 
 | 
    }  | 
 | 
}  |