Example usage for org.objectweb.asm Opcodes LLOAD

List of usage examples for org.objectweb.asm Opcodes LLOAD

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes LLOAD.

Prototype

int LLOAD

To view the source code for org.objectweb.asm Opcodes LLOAD.

Click Source Link

Usage

From source file:asmlib.Type.java

License:Open Source License

public static Type fromLoadOpcode(int opcode) {
    char type;//from   w ww.  j a  v  a 2s  . c  om

    switch (opcode) {
    case Opcodes.ILOAD:
        type = 'I';
        break;
    case Opcodes.LLOAD:
        type = 'J';
        break;
    case Opcodes.FLOAD:
        type = 'F';
        break;
    case Opcodes.DLOAD:
        type = 'D';
        break;
    case Opcodes.ALOAD:
        return Type.OBJECT;
    default:
        throw new InstrumentationException("Unknown or invalid bytecode type");
    }

    return Type.fromBytecode(type);
}

From source file:asmlib.Type.java

License:Open Source License

/** Mtodo que retorna o opcode certo para o tipo de varivel que se quer fazer load.
  * Opcodes disponveis:/*from   ww w.  j a  va2s. com*/
  * - ILOAD para boolean, byte, char, short, int
  * - LLOAD para long
  * - FLOAD para float
  * - DLOAD para double
  * - ALOAD para referncia (objecto ou array)
  **/
public int getLoadInsn() {
    char c = bytecodeName().charAt(0);
    switch (c) {
    case 'Z': // boolean
    case 'B': // byte
    case 'C': // char
    case 'S': // short
    case 'I': // int
        return Opcodes.ILOAD;
    case 'J': // long
        return Opcodes.LLOAD;
    case 'F': // float
        return Opcodes.FLOAD;
    case 'D': // double
        return Opcodes.DLOAD;
    case '[': // Algum tipo de array
    case 'L': // objecto
    case 'T': // objecto (generics)
        return Opcodes.ALOAD;
    }
    throw new InstrumentationException("Unknown fieldType in getLoadInsn");
}

From source file:br.usp.each.saeg.badua.core.internal.instr.LongProbe.java

License:Open Source License

@Override
public void accept(final MethodVisitor mv) {

    // update covered
    if (potcov != 0) {
        mv.visitVarInsn(Opcodes.LLOAD, vAlive);

        if (!singlePredecessor && potcovpuse != 0) {
            mv.visitVarInsn(Opcodes.LLOAD, vSleepy);
            mv.visitInsn(Opcodes.LAND);/* www .  j a v  a 2  s  .  com*/
        }

        mv.visitLdcInsn(potcov);
        mv.visitInsn(Opcodes.LAND);
        mv.visitVarInsn(Opcodes.LLOAD, vCovered);
        mv.visitInsn(Opcodes.LOR);
        mv.visitVarInsn(Opcodes.LSTORE, vCovered);
    }

    // update alive
    if (disabled != 0) {
        mv.visitLdcInsn(~disabled);
        mv.visitVarInsn(Opcodes.LLOAD, vAlive);
        mv.visitInsn(Opcodes.LAND);
    }
    if (born != 0) {
        if (disabled == 0) {
            mv.visitVarInsn(Opcodes.LLOAD, vAlive);
        }
        mv.visitLdcInsn(born);
        mv.visitInsn(Opcodes.LOR);
    }
    if (disabled != 0 || born != 0) {
        mv.visitVarInsn(Opcodes.LSTORE, vAlive);
    }

    // update sleepy
    if (sleepy != 0) {
        mv.visitLdcInsn(~sleepy);
    } else {
        mv.visitLdcInsn(-1L);
    }
    mv.visitVarInsn(Opcodes.LSTORE, vSleepy);
}

From source file:br.usp.each.saeg.badua.core.internal.instr.LongUpdateProbe.java

License:Open Source License

@Override
public void accept(final MethodVisitor mv) {
    mv.visitVarInsn(Opcodes.LLOAD, vCovered);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, InstrSupport.DATAMETHOD_NAME, InstrSupport.DATAMETHOD_DESC,
            false);//from www . j  a v a  2  s .  c  om
    InstrSupport.push(mv, index);
    mv.visitInsn(Opcodes.DUP2_X2);
    mv.visitInsn(Opcodes.LALOAD);
    mv.visitInsn(Opcodes.LOR);
    mv.visitInsn(Opcodes.LASTORE);
}

From source file:bytecode.InstructionExporter.java

License:Apache License

/**
 * Outputs a read operation, choosing both the correct opcode family (variable
 * read, array load, field get, etc.) and type.
 *
 * @param instruction Read instruction./* ww  w .ja  v  a  2  s  .  c  o  m*/
 * @return            <code>null</code>
 */
@Override
public Void visit(Read instruction) {
    // Variable Reads
    if (instruction.getState() instanceof Variable) {
        Variable v = (Variable) instruction.getState();

        switch (v.getType().getSort()) {
        case LONG:
            mv.visitVarInsn(Opcodes.LLOAD, v.getIndex());
            break;
        case FLOAT:
            mv.visitVarInsn(Opcodes.FLOAD, v.getIndex());
            break;
        case DOUBLE:
            mv.visitVarInsn(Opcodes.DLOAD, v.getIndex());
            break;
        case REF:
            mv.visitVarInsn(Opcodes.ALOAD, v.getIndex());
            break;
        default:
            mv.visitVarInsn(Opcodes.ILOAD, v.getIndex());
            break;
        }
        // Array Loads
    } else if (instruction.getState() instanceof ArrayElement) {
        switch (instruction.getState().getType().getSort()) {
        case INT:
            mv.visitInsn(Opcodes.IALOAD);
            break;
        case LONG:
            mv.visitInsn(Opcodes.LALOAD);
            break;
        case FLOAT:
            mv.visitInsn(Opcodes.FALOAD);
            break;
        case DOUBLE:
            mv.visitInsn(Opcodes.DALOAD);
            break;
        case REF:
            mv.visitInsn(Opcodes.AALOAD);
            break;
        case BYTE:
            mv.visitInsn(Opcodes.BALOAD);
            break;
        case BOOL:
            mv.visitInsn(Opcodes.BALOAD);
            break;
        case CHAR:
            mv.visitInsn(Opcodes.CALOAD);
            break;
        case SHORT:
            mv.visitInsn(Opcodes.SALOAD);
            break;
        }
        // Static Reads
    } else if (instruction.getState() instanceof Field) {
        Field f = (Field) instruction.getState();

        mv.visitFieldInsn(Opcodes.GETSTATIC, f.getOwner().getName(), f.getName(), f.getType().getDescriptor());
        // Field Reads
    } else if (instruction.getState() instanceof InstanceField) {
        Field f = (Field) ((InstanceField) instruction.getState()).getField();

        mv.visitFieldInsn(Opcodes.GETFIELD, f.getOwner().getName(), f.getName(), f.getType().getDescriptor());
    }

    return null;
}

From source file:bytecode.MethodImporter.java

License:Apache License

/**
 * Imports variable load and store operations, as well as RET?!?
 *
 * @param opcode Opcode.//from  www.  j a v  a 2s  .  c o m
 * @param var    Variable index.
 */
@Override
public void visitVarInsn(final int opcode, final int var) {
    switch (opcode) {
    case Opcodes.ILOAD:
        createVarRead(var, Type.INT);
        break;
    case Opcodes.LLOAD:
        createVarRead(var, Type.LONG);
        break;
    case Opcodes.FLOAD:
        createVarRead(var, Type.FLOAT);
        break;
    case Opcodes.DLOAD:
        createVarRead(var, Type.DOUBLE);
        break;
    case Opcodes.ALOAD:
        createVarRead(var, Type.getFreshRef());
        break;
    case Opcodes.ISTORE:
        createVarWrite(var, Type.INT);
        break;
    case Opcodes.LSTORE:
        createVarWrite(var, Type.LONG);
        break;
    case Opcodes.FSTORE:
        createVarWrite(var, Type.FLOAT);
        break;
    case Opcodes.DSTORE:
        createVarWrite(var, Type.DOUBLE);
        break;
    case Opcodes.ASTORE:
        createVarWrite(var, Type.getFreshRef());
        break;

    // TODO: RET (paired with JSR)
    case Opcodes.RET:
        throw new RuntimeException("visitVarInsn: RET");
    }
}

From source file:com.asakusafw.dag.compiler.codegen.AsmUtil.java

License:Apache License

/**
 * Returns the T_LOAD opcode./*from w  ww . ja  v  a  2  s. c  om*/
 * @param type the target type
 * @return the opcode
 */
public static int loadOpcodeOf(TypeDescription type) {
    Arguments.requireNonNull(type);
    if (type.getTypeKind() == TypeKind.BASIC) {
        switch (((BasicTypeDescription) type).getBasicTypeKind()) {
        case BOOLEAN:
        case BYTE:
        case CHAR:
        case SHORT:
        case INT:
            return Opcodes.ILOAD;
        case LONG:
            return Opcodes.LLOAD;
        case FLOAT:
            return Opcodes.FLOAD;
        case DOUBLE:
            return Opcodes.DLOAD;
        default:
            throw new AssertionError(type);
        }
    }
    return Opcodes.ALOAD;
}

From source file:com.asakusafw.dag.compiler.codegen.AsmUtil.java

License:Apache License

/**
 * Performs {@code T_STORE} instruction.
 * @param method the target method// w  w w  .j a va  2 s .  c o m
 * @param sort the target type sort
 * @param index the target local variable index
 * @return the target local variable ref
 */
public static LocalVarRef putLocalVar(MethodVisitor method, int sort, int index) {
    int load;
    int store;
    switch (sort) {
    case Type.BOOLEAN:
    case Type.BYTE:
    case Type.SHORT:
    case Type.CHAR:
    case Type.INT:
        load = Opcodes.ILOAD;
        store = Opcodes.ISTORE;
        break;
    case Type.LONG:
        load = Opcodes.LLOAD;
        store = Opcodes.LSTORE;
        break;
    case Type.FLOAT:
        load = Opcodes.FLOAD;
        store = Opcodes.FSTORE;
        break;
    case Type.DOUBLE:
        load = Opcodes.DLOAD;
        store = Opcodes.DSTORE;
        break;
    case Type.ARRAY:
    case Type.OBJECT:
        load = Opcodes.ALOAD;
        store = Opcodes.ASTORE;
        break;
    default:
        throw new AssertionError(sort);
    }
    method.visitVarInsn(store, index);
    return new LocalVarRef(load, index);
}

From source file:com.codename1.tools.ikvm.Parser.java

/**
 * Parses an InputStream containing a class.
 * @param input The input stream with a class.
 * @return If a transformation occurred, the bytes for the changed class will be returned.  Otherwise null will be returned.
 * @throws Exception /*from  w ww.  ja  va2  s.  c o  m*/
 */
public static byte[] parse(InputStream input, ClassLoader classLoader) throws Exception {
    ClassReader r = new ClassReader(input);
    Parser p = new Parser();
    //ClassWriter w = new ClassWriter(r, 0);
    ClassNode classNode = new ClassNode();
    //p.classNode = classNode;

    r.accept(classNode, 0);
    //r.accept(p, ClassReader.EXPAND_FRAMES)

    List<MethodNode> methodsToAdd = new ArrayList<MethodNode>();
    int methodNum = 0;
    for (Object o : classNode.methods) {
        methodNum++;
        MethodNode methodNode = (MethodNode) o;
        boolean synchronizedMethod = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) == Opcodes.ACC_SYNCHRONIZED;
        if (synchronizedMethod) {
            // Check for a try statement
            final boolean[] tryCatchFound = new boolean[1];
            //System.out.println("Found sync method "+methodNode.name+". Checking for try blocks");
            methodNode.accept(new MethodVisitor(Opcodes.ASM5) {

                @Override
                public void visitTryCatchBlock(Label label, Label label1, Label label2, String string) {
                    tryCatchFound[0] = true;
                }

            });
            if (!tryCatchFound[0]) {
                continue;
            }

            //System.out.println("Instructions: "+Arrays.toString(methodNode.instructions.toArray()));

            System.out.println("Transforming method " + methodNode.name + " of class " + classNode.name);
            MethodDescriptor md = new MethodDescriptor(methodNode.access, methodNode.name, methodNode.desc);
            //methodNode.access = methodNode.access & ~Opcodes.ACC_SYNCHRONIZED;
            String privateMethodName = (md.constructor ? "___cn1init__" : methodNode.name) + "___cn1sync"
                    + (methodNum);
            MethodNode syncMethod = new MethodNode(methodNode.access, methodNode.name, methodNode.desc,
                    methodNode.signature,
                    (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()]));

            methodNode.name = privateMethodName;
            methodNode.access = (methodNode.access | Opcodes.ACC_PRIVATE) & ~Opcodes.ACC_PUBLIC
                    & ~Opcodes.ACC_PROTECTED & ~Opcodes.ACC_SYNCHRONIZED;
            LabelNode startLabel = new LabelNode();
            syncMethod.instructions.add(startLabel);
            LabelNode endLabel = new LabelNode();

            int argIndex = 0;
            if (!md.staticMethod) {
                //System.out.println(methodNode.name + " is not static");
                syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex),
                        "L" + classNode.name + ";", null, startLabel, endLabel, argIndex));
                syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++));

            }

            for (ByteCodeMethodArg arg : md.arguments) {
                char typeChar = arg.type;
                if (arg.dim > 0) {
                    typeChar = 'L';
                }
                if (arg.desc == null || arg.desc.isEmpty()) {
                    throw new RuntimeException(
                            "Invalid arg description for arg " + argIndex + " of method " + methodNode.name);
                }
                syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), arg.desc, arg.desc,
                        startLabel, endLabel, argIndex));

                switch (typeChar) {
                case 'L':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++));
                    //syncMethod.localVariables.add(new LocalVariableNode("arg"+(argIndex-1), arg.desc, null, startLabel, endLabel, argIndex-1));
                    break;
                case 'S':
                case 'I':
                case 'B':
                case 'Z':
                case 'C':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.ILOAD, argIndex++));
                    break;
                case 'J':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.LLOAD, argIndex++));
                    argIndex++; // arg index increments 2 for double size args
                    break;
                case 'F':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.FLOAD, argIndex++));
                    break;
                case 'D':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.DLOAD, argIndex++));
                    argIndex++;// arg index increments 2 for double size args
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported argument type " + arg.type);
                }
            }

            if (md.staticMethod) {
                syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name,
                        privateMethodName, methodNode.desc));
            } else {
                syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name,
                        privateMethodName, methodNode.desc));
            }

            if (md.returnType != null) {
                char typeChar = md.returnType.type;
                if (md.returnType.dim > 0) {
                    typeChar = 'L';
                }
                switch (typeChar) {
                case 'L':
                    syncMethod.instructions.add(new InsnNode(Opcodes.ARETURN));
                    break;
                case 'S':
                case 'I':
                case 'B':
                case 'Z':
                case 'C':
                    syncMethod.instructions.add(new InsnNode(Opcodes.IRETURN));
                    break;
                case 'J':
                    syncMethod.instructions.add(new InsnNode(Opcodes.LRETURN));
                    break;
                case 'F':
                    syncMethod.instructions.add(new InsnNode(Opcodes.FRETURN));
                    break;
                case 'D':
                    syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN));
                    break;
                case 'V':
                    syncMethod.instructions.add(new InsnNode(Opcodes.RETURN));
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported argument type " + md.returnType.type);
                }
            } else {
                syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN));
            }

            syncMethod.instructions.add(endLabel);

            methodsToAdd.add(syncMethod);

        }
    }
    if (!methodsToAdd.isEmpty()) {
        changed = true;
        System.out
                .println("Transforming " + methodsToAdd.size() + " synchronized methods in " + classNode.name);
        classNode.methods.addAll(methodsToAdd);
        ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(w);
        byte[] out = w.toByteArray();
        if (verify) {
            verify(out, classLoader);
        }
        return out;
    } else {
        ClassWriter w = new ClassWriter(0);
        classNode.accept(w);
        byte[] out = w.toByteArray();
        return out;
    }

}

From source file:com.codename1.tools.translator.BytecodeMethod.java

License:Open Source License

boolean optimize() {
    int instructionCount = instructions.size();

    // optimize away a method that only contains the void return instruction e.g. blank constructors etc.
    if (instructionCount < 6) {
        int realCount = instructionCount;
        Instruction actual = null;/*from ww w  .  j a v a2s  .c o m*/
        for (int iter = 0; iter < instructionCount; iter++) {
            Instruction current = instructions.get(iter);
            if (current instanceof LabelInstruction) {
                realCount--;
                continue;
            }
            if (current instanceof LineNumber) {
                realCount--;
                continue;
            }
            actual = current;
        }

        if (realCount == 1 && actual != null && actual.getOpcode() == Opcodes.RETURN) {
            return false;
        }
    }

    boolean astoreCalls = false;
    boolean hasInstructions = false;

    boolean hasTryCatch = false;
    for (int iter = 0; iter < instructionCount - 1; iter++) {
        Instruction current = instructions.get(iter);
        if (current instanceof TryCatch) {
            hasTryCatch = true;
        }
        current.setMethod(this);
        if (current.isOptimized()) {
            continue;
        }
        int currentOpcode = current.getOpcode();
        switch (currentOpcode) {
        case Opcodes.CHECKCAST: {
            // Remove the check cast for now as it gets in the way of other optimizations
            instructions.remove(iter);
            iter--;
            instructionCount--;
            break;
        }
        }
    }

    for (int iter = 0; iter < instructionCount - 1; iter++) {
        Instruction current = instructions.get(iter);
        if (current.isOptimized()) {
            // This instruction has already been optimized
            // we should skip it and proceed to the next one
            continue;
        }
        Instruction next = instructions.get(iter + 1);

        int currentOpcode = current.getOpcode();
        int nextOpcode = next.getOpcode();

        if (ArithmeticExpression.isArithmeticOp(current)) {
            int addedIndex = ArithmeticExpression.tryReduce(instructions, iter);
            if (addedIndex >= 0) {
                iter = addedIndex;
                instructionCount = instructions.size();
                continue;
            }
        }

        if (current instanceof Field) {
            int newIter = Field.tryReduce(instructions, iter);
            if (newIter >= 0) {
                iter = newIter;
                instructionCount = instructions.size();
                continue;
            }
        }

        switch (currentOpcode) {

        case Opcodes.ARRAYLENGTH: {
            if (!dependentClasses.contains("java_lang_NullPointerException")) {
                dependentClasses.add("java_lang_NullPointerException");
            }
            int newIter = ArrayLengthExpression.tryReduce(instructions, iter);
            if (newIter >= 0) {
                instructionCount = instructions.size();
                iter = newIter;
                continue;
            }
            break;
        }

        case Opcodes.DUP: {
            int newIter = DupExpression.tryReduce(instructions, iter);
            if (newIter >= 0) {
                iter = newIter;
                instructionCount = instructions.size();
                continue;
            }
            break;
        }

        case Opcodes.POP: {
            if (iter > 0) {
                Instruction prev = instructions.get(iter - 1);
                if (prev instanceof CustomInvoke) {
                    CustomInvoke inv = (CustomInvoke) prev;
                    if (inv.methodHasReturnValue()) {
                        inv.setNoReturn(true);
                        instructions.remove(iter);
                        iter--;
                        instructionCount--;
                        continue;
                    }
                }
            }
            break;
        }

        case Opcodes.ASTORE:
        case Opcodes.ISTORE:
        case Opcodes.DSTORE:
        case Opcodes.LSTORE:
        case Opcodes.FSTORE: {
            if (iter > 0 && current instanceof VarOp) {
                VarOp currentVarOp = (VarOp) current;
                Instruction prev = instructions.get(iter - 1);
                if (prev instanceof AssignableExpression) {
                    AssignableExpression expr = (AssignableExpression) prev;
                    StringBuilder sb = new StringBuilder();
                    if (currentVarOp.assignFrom(expr, sb)) {
                        instructions.remove(iter - 1);
                        instructions.remove(iter - 1);
                        instructions.add(iter - 1,
                                new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                        iter = iter - 1;
                        instructionCount = instructions.size();
                        continue;
                    }

                } else if (prev instanceof CustomInvoke) {
                    CustomInvoke inv = (CustomInvoke) prev;
                    StringBuilder sb = new StringBuilder();
                    if (currentVarOp.assignFrom(inv, sb)) {
                        instructions.remove(iter - 1);
                        instructions.remove(iter - 1);
                        instructions.add(iter - 1,
                                new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                        iter = iter - 1;
                        instructionCount = instructions.size();
                        continue;
                    }
                }
            }

            break;
        }

        case Opcodes.IRETURN:
        case Opcodes.FRETURN:
        case Opcodes.ARETURN:
        case Opcodes.LRETURN:
        case Opcodes.DRETURN: {
            if (iter > 0 && current instanceof BasicInstruction) {
                Instruction prev = instructions.get(iter - 1);
                if (prev instanceof AssignableExpression) {
                    AssignableExpression expr = (AssignableExpression) prev;
                    StringBuilder sb = new StringBuilder();
                    if (expr.assignTo(null, sb)) {
                        instructions.remove(iter - 1);
                        instructions.remove(iter - 1);
                        String exprString = sb.toString().trim();
                        String retVal = exprString;
                        sb.setLength(0);
                        if (!prev.isConstant()) {
                            sb.append("\n{\n    ");
                            switch (currentOpcode) {
                            case Opcodes.IRETURN:
                                sb.append("JAVA_INT");
                                break;
                            case Opcodes.FRETURN:
                                sb.append("JAVA_FLOAT");
                                break;
                            case Opcodes.ARETURN:
                                sb.append("JAVA_OBJECT");
                                break;
                            case Opcodes.LRETURN:
                                sb.append("JAVA_LONG");
                                break;
                            case Opcodes.DRETURN:
                                sb.append("JAVA_DOUBLE");
                                break;
                            }
                            sb.append(" ___returnValue=").append(exprString).append(";\n");
                            retVal = "___returnValue";
                        }
                        if (synchronizedMethod) {
                            if (staticMethod) {
                                sb.append("    monitorExit(threadStateData, (JAVA_OBJECT)&class__");
                                sb.append(getClsName());
                                sb.append(");\n");
                            } else {
                                sb.append("    monitorExit(threadStateData, __cn1ThisObject);\n");
                            }
                        }
                        if (hasTryCatch) {
                            sb.append(
                                    "    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ")
                                    .append(retVal).append(";\n");
                        } else {
                            sb.append("    releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ")
                                    .append(retVal).append(";\n");
                        }
                        if (!prev.isConstant()) {
                            sb.append("}\n");
                        }

                        instructions.add(iter - 1,
                                new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                        iter--;
                        instructionCount = instructions.size();
                        continue;

                    }
                } else if (prev instanceof CustomInvoke) {

                    CustomInvoke expr = (CustomInvoke) prev;
                    String returnType = expr.getReturnValue();
                    if (returnType != null && !"JAVA_OBJECT".equals(returnType)) {
                        // We can't safely return a JAVA_OBJECT directly because it needs to be added 
                        // to the stack for the GC
                        StringBuilder sb = new StringBuilder();
                        if (expr.appendExpression(sb)) {
                            instructions.remove(iter - 1);
                            instructions.remove(iter - 1);
                            String exprString = sb.toString().trim();
                            String retVal = exprString;
                            sb.setLength(0);
                            if (!expr.isConstant()) {

                                sb.append("\n{\n    ");
                                switch (currentOpcode) {
                                case Opcodes.IRETURN:
                                    sb.append("JAVA_INT");
                                    break;
                                case Opcodes.FRETURN:
                                    sb.append("JAVA_FLOAT");
                                    break;
                                case Opcodes.ARETURN:
                                    sb.append("JAVA_OBJECT");
                                    break;
                                case Opcodes.LRETURN:
                                    sb.append("JAVA_LONG");
                                    break;
                                case Opcodes.DRETURN:
                                    sb.append("JAVA_DOUBLE");
                                    break;
                                }

                                sb.append(" ___returnValue=").append(exprString).append(";\n");
                                retVal = "___returnValue";
                            }
                            if (synchronizedMethod) {
                                if (staticMethod) {
                                    sb.append("    monitorExit(threadStateData, (JAVA_OBJECT)&class__");
                                    sb.append(getClsName());
                                    sb.append(");\n");
                                } else {
                                    sb.append("    monitorExit(threadStateData, __cn1ThisObject);\n");
                                }
                            }
                            if (hasTryCatch) {
                                sb.append(
                                        "    releaseForReturnInException(threadStateData, cn1LocalsBeginInThread, methodBlockOffset); return ")
                                        .append(retVal).append(";\n");
                            } else {
                                sb.append(
                                        "    releaseForReturn(threadStateData, cn1LocalsBeginInThread); return ")
                                        .append(retVal).append(";\n");
                            }
                            if (!expr.isConstant()) {
                                sb.append("}\n");
                            }

                            instructions.add(iter - 1,
                                    new CustomIntruction(sb.toString(), sb.toString(), dependentClasses));
                            iter--;
                            instructionCount = instructions.size();
                            continue;

                        }
                    }
                }
            }
            break;
        }

        case Opcodes.BASTORE:
        case Opcodes.SASTORE:
        case Opcodes.CASTORE:
        case Opcodes.AASTORE:
        case Opcodes.IASTORE:
        case Opcodes.DASTORE:
        case Opcodes.LASTORE:
        case Opcodes.FASTORE: {
            if (iter > 2 && current instanceof BasicInstruction) {
                StringBuilder devNull = new StringBuilder();
                String arrayLiteral = null;
                String indexLiteral = null;
                String valueLiteral = null;
                Instruction prev3 = instructions.get(iter - 3);
                if (prev3 instanceof AssignableExpression) {
                    if (((AssignableExpression) prev3).assignTo(null, devNull)) {
                        arrayLiteral = devNull.toString().trim();

                    }
                }
                devNull.setLength(0);
                Instruction prev2 = instructions.get(iter - 2);
                if (prev2 instanceof AssignableExpression) {
                    if (((AssignableExpression) prev2).assignTo(null, devNull)) {
                        indexLiteral = devNull.toString().trim();
                    }
                }
                devNull.setLength(0);
                Instruction prev1 = instructions.get(iter - 1);

                if (prev1 instanceof AssignableExpression) {
                    if (((AssignableExpression) prev1).assignTo(null, devNull)) {
                        valueLiteral = devNull.toString().trim();
                    }
                } else if (prev1 instanceof CustomInvoke) {
                    devNull.setLength(0);
                    if (((CustomInvoke) prev1).appendExpression(devNull)) {
                        valueLiteral = devNull.toString().trim();
                    }
                }

                if (arrayLiteral != null && indexLiteral != null && valueLiteral != null) {
                    String elementType = null;
                    switch (current.getOpcode()) {
                    case Opcodes.AASTORE:
                        elementType = "OBJECT";
                        break;
                    case Opcodes.IASTORE:
                        elementType = "INT";
                        break;
                    case Opcodes.DASTORE:
                        elementType = "DOUBLE";
                        break;

                    case Opcodes.LASTORE:
                        elementType = "LONG";
                        break;
                    case Opcodes.FASTORE:
                        elementType = "FLOAT";
                        break;
                    case Opcodes.CASTORE:
                        elementType = "CHAR";
                        break;
                    case Opcodes.BASTORE:
                        elementType = "BYTE";
                        break;
                    case Opcodes.SASTORE:
                        elementType = "SHORT";
                        break;

                    }
                    if (elementType == null) {
                        break;
                    }

                    instructions.remove(iter - 3);
                    instructions.remove(iter - 3);
                    instructions.remove(iter - 3);
                    instructions.remove(iter - 3);
                    String code = "    CN1_SET_ARRAY_ELEMENT_" + elementType + "(" + arrayLiteral + ", "
                            + indexLiteral + ", " + valueLiteral + ");\n";
                    instructions.add(iter - 3, new CustomIntruction(code, code, dependentClasses));
                    iter = iter - 3;
                    instructionCount = instructions.size();
                    continue;
                }
            }

            break;
        }

        case Opcodes.FALOAD:
        case Opcodes.BALOAD:
        case Opcodes.IALOAD:
        case Opcodes.LALOAD:
        case Opcodes.DALOAD:
        case Opcodes.AALOAD:
        case Opcodes.SALOAD:
        case Opcodes.CALOAD: {
            int newIter = ArrayLoadExpression.tryReduce(instructions, iter);
            if (newIter >= 0) {
                iter = newIter;
                instructionCount = instructions.size();
                continue;
            }
            break;
        }

        /* Try to optimize if statements that just use constants
           and local variables so that they don't need the intermediate
           push and pop from the stack.
        */
        case Opcodes.IF_ACMPEQ:
        case Opcodes.IF_ACMPNE:
        case Opcodes.IF_ICMPLE:
        case Opcodes.IF_ICMPLT:
        case Opcodes.IF_ICMPNE:
        case Opcodes.IF_ICMPGT:
        case Opcodes.IF_ICMPEQ:
        case Opcodes.IF_ICMPGE: {

            if (iter > 1) {
                Instruction leftArg = instructions.get(iter - 2);
                Instruction rightArg = instructions.get(iter - 1);

                String leftLiteral = null;
                String rightLiteral = null;

                if (leftArg instanceof AssignableExpression) {
                    StringBuilder sb = new StringBuilder();
                    if (((AssignableExpression) leftArg).assignTo(null, sb)) {
                        leftLiteral = sb.toString().trim();
                    }
                } else if (leftArg instanceof CustomInvoke) {
                    CustomInvoke inv = (CustomInvoke) leftArg;
                    StringBuilder sb = new StringBuilder();
                    if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
                        leftLiteral = sb.toString().trim();
                    }
                }
                if (rightArg instanceof AssignableExpression) {
                    StringBuilder sb = new StringBuilder();
                    if (((AssignableExpression) rightArg).assignTo(null, sb)) {
                        rightLiteral = sb.toString().trim();
                    }
                } else if (rightArg instanceof CustomInvoke) {
                    CustomInvoke inv = (CustomInvoke) rightArg;
                    StringBuilder sb = new StringBuilder();
                    if (!"JAVA_OBJECT".equals(inv.getReturnValue()) && inv.appendExpression(sb)) {
                        rightLiteral = sb.toString().trim();
                    }
                }

                if (rightLiteral != null && leftLiteral != null) {
                    Jump jmp = (Jump) current;
                    instructions.remove(iter - 2);
                    instructions.remove(iter - 2);
                    instructions.remove(iter - 2);
                    //instructions.remove(iter-2);
                    iter -= 2;
                    //instructionCount -= 2;
                    StringBuilder sb = new StringBuilder();
                    String operator = null;
                    String opName = null;
                    switch (currentOpcode) {
                    case Opcodes.IF_ICMPLE:
                        operator = "<=";
                        opName = "IF_ICMPLE";
                        break;
                    case Opcodes.IF_ICMPLT:
                        operator = "<";
                        opName = "IF_IMPLT";
                        break;
                    case Opcodes.IF_ICMPNE:
                        operator = "!=";
                        opName = "IF_ICMPNE";
                        break;
                    case Opcodes.IF_ICMPGT:
                        operator = ">";
                        opName = "IF_ICMPGT";
                        break;
                    case Opcodes.IF_ICMPGE:
                        operator = ">=";
                        opName = "IF_ICMPGE";
                        break;
                    case Opcodes.IF_ICMPEQ:
                        operator = "==";
                        opName = "IF_ICMPEQ";
                        break;
                    case Opcodes.IF_ACMPEQ:
                        operator = "==";
                        opName = "IF_ACMPEQ";
                        break;
                    case Opcodes.IF_ACMPNE:
                        operator = "!=";
                        opName = "IF_ACMPNE";
                        break;
                    default:
                        throw new RuntimeException(
                                "Invalid operator during optimization of integer comparison");
                    }

                    sb.append("if (").append(leftLiteral).append(operator).append(rightLiteral).append(") /* ")
                            .append(opName).append(" CustomJump */ ");
                    CustomJump newJump = CustomJump.create(jmp, sb.toString());
                    //jmp.setCustomCompareCode(sb.toString());
                    newJump.setOptimized(true);
                    instructions.add(iter, newJump);
                    instructionCount = instructions.size();

                }

            }
            break;
        }
        case Opcodes.IFNONNULL:
        case Opcodes.IFNULL:

        case Opcodes.IFLE:
        case Opcodes.IFLT:
        case Opcodes.IFNE:
        case Opcodes.IFGT:
        case Opcodes.IFEQ:
        case Opcodes.IFGE: {
            String rightArg = "0";
            if (currentOpcode == Opcodes.IFNONNULL || currentOpcode == Opcodes.IFNULL) {
                rightArg = "JAVA_NULL";
            }
            if (iter > 0) {
                Instruction leftArg = instructions.get(iter - 1);

                String leftLiteral = null;

                if (leftArg instanceof AssignableExpression) {
                    StringBuilder sb = new StringBuilder();
                    if (((AssignableExpression) leftArg).assignTo(null, sb)) {
                        leftLiteral = sb.toString().trim();
                    }
                } else if (leftArg instanceof CustomInvoke) {
                    CustomInvoke inv = (CustomInvoke) leftArg;
                    StringBuilder sb = new StringBuilder();
                    if (inv.appendExpression(sb)) {
                        leftLiteral = sb.toString().trim();
                    }
                }

                if (leftLiteral != null) {
                    Jump jmp = (Jump) current;
                    instructions.remove(iter - 1);
                    instructions.remove(iter - 1);
                    //instructions.remove(iter-2);
                    iter -= 1;
                    //instructionCount -= 2;
                    StringBuilder sb = new StringBuilder();
                    String operator = null;
                    String opName = null;
                    switch (currentOpcode) {
                    case Opcodes.IFLE:
                        operator = "<=";
                        opName = "IFLE";
                        break;
                    case Opcodes.IFLT:
                        operator = "<";
                        opName = "IFLT";
                        break;
                    case Opcodes.IFNE:
                        operator = "!=";
                        opName = "IFNE";
                        break;
                    case Opcodes.IFGT:
                        operator = ">";
                        opName = "IFGT";
                        break;
                    case Opcodes.IFGE:
                        operator = ">=";
                        opName = "IFGE";
                        break;
                    case Opcodes.IFEQ:
                        operator = "==";
                        opName = "IFEQ";
                        break;
                    case Opcodes.IFNULL:
                        operator = "==";
                        opName = "IFNULL";
                        break;
                    case Opcodes.IFNONNULL:
                        operator = "!=";
                        opName = "IFNONNULL";
                        break;
                    default:
                        throw new RuntimeException(
                                "Invalid operator during optimization of integer comparison");
                    }

                    sb.append("if (").append(leftLiteral).append(operator).append(rightArg).append(") /* ")
                            .append(opName).append(" CustomJump */ ");
                    CustomJump newJump = CustomJump.create(jmp, sb.toString());
                    //jmp.setCustomCompareCode(sb.toString());
                    newJump.setOptimized(true);
                    instructions.add(iter, newJump);
                    instructionCount = instructions.size();

                }

            }
            break;
        }

        case Opcodes.INVOKEVIRTUAL:
        case Opcodes.INVOKESTATIC:
        case Opcodes.INVOKESPECIAL:
        case Opcodes.INVOKEINTERFACE: {
            if (current instanceof Invoke) {
                Invoke inv = (Invoke) current;
                List<ByteCodeMethodArg> invocationArgs = inv.getArgs();
                int numArgs = invocationArgs.size();

                //if (current.getOpcode() != Opcodes.INVOKESTATIC) {
                //    numArgs++;
                //}
                if (iter >= numArgs) {
                    String[] argLiterals = new String[numArgs];
                    StringBuilder devNull = new StringBuilder();
                    for (int i = 0; i < numArgs; i++) {
                        devNull.setLength(0);
                        Instruction instr = instructions.get(iter - numArgs + i);
                        if (instr instanceof AssignableExpression
                                && ((AssignableExpression) instr).assignTo(null, devNull)) {
                            argLiterals[i] = devNull.toString().trim();
                        } else if (instr instanceof CustomInvoke) {
                            CustomInvoke cinv = (CustomInvoke) instr;
                            devNull.setLength(0);
                            if (!"JAVA_OBJECT".equals(cinv.getReturnValue())
                                    && cinv.appendExpression(devNull)) {
                                // We can't add invocations that return objects directly
                                // because they need to be added to the stack for GC
                                argLiterals[i] = devNull.toString().trim();
                            }
                        } else if (instr instanceof ArithmeticExpression) {
                            argLiterals[i] = ((ArithmeticExpression) instr).getExpressionAsString().trim();
                        } else if (instr instanceof VarOp) {
                            VarOp var = (VarOp) instr;
                            switch (instr.getOpcode()) {
                            case Opcodes.ALOAD: {
                                if (!isStatic() && var.getIndex() == 0) {
                                    argLiterals[i] = "__cn1ThisObject";
                                } else {
                                    argLiterals[i] = "locals[" + var.getIndex() + "].data.o";
                                }
                                break;
                            }
                            case Opcodes.ILOAD: {
                                argLiterals[i] = "ilocals_" + var.getIndex() + "_";
                                break;
                            }
                            case Opcodes.ACONST_NULL: {
                                argLiterals[i] = "JAVA_NULL";
                                break;
                            }
                            case Opcodes.DLOAD: {
                                argLiterals[i] = "dlocals_" + var.getIndex() + "_";
                                break;
                            }
                            case Opcodes.FLOAD: {
                                argLiterals[i] = "flocals_" + var.getIndex() + "_";
                                break;
                            }
                            case Opcodes.LLOAD: {
                                argLiterals[i] = "llocals_" + var.getIndex() + "_";
                                break;
                            }
                            case Opcodes.ICONST_0: {
                                argLiterals[i] = "0";
                                break;
                            }
                            case Opcodes.ICONST_1: {
                                argLiterals[i] = "1";
                                break;
                            }
                            case Opcodes.ICONST_2: {
                                argLiterals[i] = "2";
                                break;
                            }
                            case Opcodes.ICONST_3: {
                                argLiterals[i] = "3";
                                break;
                            }
                            case Opcodes.ICONST_4: {
                                argLiterals[i] = "4";
                                break;
                            }
                            case Opcodes.ICONST_5: {
                                argLiterals[i] = "5";
                                break;
                            }
                            case Opcodes.ICONST_M1: {
                                argLiterals[i] = "-1";
                                break;
                            }
                            case Opcodes.LCONST_0: {
                                argLiterals[i] = "(JAVA_LONG)0";
                                break;
                            }
                            case Opcodes.LCONST_1: {
                                argLiterals[i] = "(JAVA_LONG)1";
                                break;
                            }
                            case Opcodes.BIPUSH:
                            case Opcodes.SIPUSH: {
                                argLiterals[i] = String.valueOf(var.getIndex());

                                break;
                            }
                            }
                        } else {
                            switch (instr.getOpcode()) {

                            case Opcodes.ACONST_NULL: {
                                argLiterals[i] = "JAVA_NULL";
                                break;
                            }

                            case Opcodes.ICONST_0: {
                                argLiterals[i] = "0";
                                break;
                            }
                            case Opcodes.ICONST_1: {
                                argLiterals[i] = "1";
                                break;
                            }
                            case Opcodes.ICONST_2: {
                                argLiterals[i] = "2";
                                break;
                            }
                            case Opcodes.ICONST_3: {
                                argLiterals[i] = "3";
                                break;
                            }
                            case Opcodes.ICONST_4: {
                                argLiterals[i] = "4";
                                break;
                            }
                            case Opcodes.ICONST_5: {
                                argLiterals[i] = "5";
                                break;
                            }
                            case Opcodes.ICONST_M1: {
                                argLiterals[i] = "-1";
                                break;
                            }
                            case Opcodes.LCONST_0: {
                                argLiterals[i] = "(JAVA_LONG)0";
                                break;
                            }
                            case Opcodes.LCONST_1: {
                                argLiterals[i] = "(JAVA_LONG)1";
                                break;
                            }
                            case Opcodes.BIPUSH: {
                                if (instr instanceof BasicInstruction) {
                                    argLiterals[i] = String.valueOf(((BasicInstruction) instr).getValue());
                                }
                                break;
                            }
                            case Opcodes.LDC: {
                                if (instr instanceof Ldc) {
                                    Ldc ldc = (Ldc) instr;
                                    argLiterals[i] = ldc.getValueAsString();

                                }
                                break;
                            }

                            }

                        }
                    }

                    // Check to make sure that we have all the args as literals.
                    boolean missingLiteral = false;
                    for (String lit : argLiterals) {
                        if (lit == null) {
                            missingLiteral = true;
                            break;
                        }
                    }

                    // We have all of the arguments as literals.  Let's
                    // add them to our invoke instruction.
                    if (!missingLiteral) {
                        CustomInvoke newInvoke = CustomInvoke.create(inv);
                        instructions.remove(iter);
                        instructions.add(iter, newInvoke);
                        int newIter = iter;
                        for (int i = 0; i < numArgs; i++) {
                            instructions.remove(iter - numArgs);
                            newIter--;
                            newInvoke.setLiteralArg(i, argLiterals[i]);
                        }
                        if (inv.getOpcode() != Opcodes.INVOKESTATIC) {
                            Instruction ldTarget = instructions.get(iter - numArgs - 1);
                            if (ldTarget instanceof AssignableExpression) {
                                StringBuilder targetExprStr = new StringBuilder();
                                if (((AssignableExpression) ldTarget).assignTo(null, targetExprStr)) {
                                    newInvoke.setTargetObjectLiteral(targetExprStr.toString().trim());
                                    instructions.remove(iter - numArgs - 1);
                                    newIter--;

                                }

                            } else if (ldTarget instanceof CustomInvoke) {
                                // WE Can't pass a custom invoke as the target directly
                                // because it the return value needs to be added to the 
                                // stack for the GC
                            } else {
                                switch (ldTarget.getOpcode()) {
                                case Opcodes.ALOAD: {
                                    VarOp v = (VarOp) ldTarget;
                                    if (isStatic() && v.getIndex() == 0) {
                                        newInvoke.setTargetObjectLiteral("__cn1ThisObject");
                                    } else {
                                        newInvoke.setTargetObjectLiteral("locals[" + v.getIndex() + "].data.o");
                                    }
                                    instructions.remove(iter - numArgs - 1);
                                    newIter--;
                                    break;
                                }
                                }
                            }
                        }

                        newInvoke.setOptimized(true);
                        //iter = 0;
                        instructionCount = instructions.size();
                        iter = newIter;

                    }
                }
            }
            break;
        }

        }
        astoreCalls = astoreCalls || currentOpcode == Opcodes.ASTORE || currentOpcode == Opcodes.ISTORE
                || currentOpcode == Opcodes.LSTORE || currentOpcode == Opcodes.DSTORE
                || currentOpcode == Opcodes.FSTORE;

        hasInstructions = hasInstructions | current.getOpcode() != -1;
    }
    return hasInstructions;
}