Example usage for org.objectweb.asm MethodVisitor visitIincInsn

List of usage examples for org.objectweb.asm MethodVisitor visitIincInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitIincInsn.

Prototype

public void visitIincInsn(final int var, final int increment) 

Source Link

Document

Visits an IINC instruction.

Usage

From source file:autostack.Transformer.java

License:Open Source License

public byte[] transform(ClassLoader loader, final String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) {
    try {/*from  www .j  a va2  s  .  co m*/
        if (className == null || className.startsWith("java/") || className.startsWith("sun/")
                || className.startsWith("jdk/internal/") || className.startsWith("org/lwjgl/"))
            return null;
        for (String pack : packages)
            if (!className.startsWith(pack))
                return null;
        ClassReader cr = new ClassReader(classfileBuffer);
        final Map<String, Integer> stackMethods = new HashMap<String, Integer>();
        // Scan all methods that need auto-stack
        if (debugTransform)
            System.out.println("[autostack] scanning methods in class: " + className.replace('/', '.'));
        cr.accept(new ClassVisitor(ASM5) {
            public MethodVisitor visitMethod(final int access, final String methodName, final String methodDesc,
                    String signature, String[] exceptions) {
                if ((access & (ACC_NATIVE | ACC_ABSTRACT)) != 0) {
                    // Don't try to analyze native or abstract methods.
                    return null;
                }
                MethodVisitor mv = new MethodVisitor(ASM5) {
                    boolean mark, catches, notransform, nostackparam, forcestack;

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lautostack/NoTransform;".equals(desc))
                            notransform = true;
                        else if ("Lautostack/NoStackParam;".equals(desc))
                            nostackparam = true;
                        else if ("Lautostack/UseNewStack;".equals(desc))
                            forcestack = true;
                        return null;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        if (opcode == INVOKESTATIC && !itf && (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                || owner.equals(MEMORYSTACK) && (name.equals("stackGet")
                                        || name.equals("stackPop") || name.equals("stackPush")
                                        || name.startsWith("stackMalloc") || name.startsWith("stackCalloc")
                                        || name.equals("stackUTF8") || name.equals("stackASCII")
                                        || name.equals("stackUTF16") || name.equals("stackFloats")
                                        || name.equals("stackInts") || name.equals("stackBytes")
                                        || name.equals("stackShorts") || name.equals("stackPointers")
                                        || name.equals("stackLongs")))) {
                            mark = true;
                        }
                    }

                    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
                        catches = true;
                    }

                    public void visitEnd() {
                        int flag = (access & ACC_PRIVATE) != 0 ? 8 : 0;
                        flag |= nostackparam ? 16 : 0;
                        if (mark || notransform || forcestack || nostackparam) {
                            if (notransform) {
                                flag |= 2;
                                if (debugTransform)
                                    System.out.println("[autostack]   will not transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            } else {
                                if (checkStack)
                                    flag |= 4;
                                flag |= catches ? 1 : 0;
                                if (debugTransform)
                                    System.out.println("[autostack]   will transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            }
                            stackMethods.put(methodName + methodDesc, Integer.valueOf(flag));
                        }
                    }
                };
                return mv;
            }
        }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
        if (stackMethods.isEmpty())
            return null;

        // Now, transform all such methods
        if (debugTransform)
            System.out.println("[autostack] transforming methods in class: " + className.replace('/', '.'));
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        cr.accept(new ClassVisitor(ASM5, cw) {
            boolean classDefaultNewStack = defaultNewStack;
            boolean classNoTransform;

            @Override
            public void visit(int version, int access, String name, String signature, String superName,
                    String[] interfaces) {
                cv.visit(version, access, name, signature, superName, interfaces);
                if (!checkStack) {
                    return;
                }
                /* Generate simple synthetic "compare stack pointers and throw if not equal" method */
                MethodVisitor mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStack$",
                        "(II)V", null, new String[] { "java/lang/AssertionError" });
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitVarInsn(ILOAD, 1);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitInsn(ATHROW);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitInsn(RETURN);
                    mv.visitMaxs(5, 2);
                    mv.visitEnd();
                }

                mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStackWithThrowable$",
                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", null, null);
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitVarInsn(ILOAD, 2);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 2);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
                    mv.visitInsn(ARETURN);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitInsn(ARETURN);
                    mv.visitMaxs(5, 3);
                    mv.visitEnd();
                }
            }

            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                if ("Lautostack/UseCallerStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use caller stack for all methods, unless overridden by method");
                    classDefaultNewStack = false;
                    return null;
                } else if ("Lautostack/UseNewStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use new stack for all methods, unless overridden by method");
                    classDefaultNewStack = true;
                    return null;
                } else if ("Lautostack/NoTransform;".equals(desc)) {
                    if (debugTransform)
                        System.out.println("[autostack]   class declares to not transform any methods");
                    classNoTransform = true;
                    return null;
                }
                return cv.visitAnnotation(desc, visible);
            }

            public MethodVisitor visitMethod(final int access, final String name, final String desc,
                    String signature, String[] exceptions) {
                Integer info = stackMethods.get(name + desc);
                if (info == null)
                    return super.visitMethod(access, name, desc, signature, exceptions);
                boolean catches = (info.intValue() & 1) == 1;
                final boolean notransform = classNoTransform || (info.intValue() & 2) == 2;
                if (debugTransform && !notransform)
                    System.out.println(
                            "[autostack]   transform method: " + className.replace('/', '.') + "." + name);
                final boolean memoryStackParam = stackAsParameter && (access & ACC_PRIVATE) != 0
                        && (info.intValue() & 16) == 0;
                MethodVisitor mv;
                final Type[] paramTypes = Type.getArgumentTypes(desc);
                final boolean isStatic = (access & ACC_STATIC) != 0;
                final boolean isConstructor = "<init>".equals(name);
                if (memoryStackParam) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]     changing signature of method to add additional MemoryStack parameter");

                    // Add additional MemoryStack parameter to the method signature index of the local stays the same
                    int paramEndIndex = desc.indexOf(')');
                    String beforeDesc = desc.substring(0, paramEndIndex);
                    String afterDesc = desc.substring(paramEndIndex);
                    mv = super.visitMethod(access | ACC_SYNTHETIC, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, signature, exceptions);

                    // Re-introduce the original method which just delegates
                    if (debugTransform)
                        System.out.println("[autostack]     adding delegate method with original signature");
                    MethodVisitor omv = super.visitMethod(access, name, desc, signature, exceptions);
                    omv.visitCode();
                    int param = 0;
                    if (!isStatic) {
                        omv.visitVarInsn(ALOAD, 0);
                        param++;
                    }
                    for (int i = 0; i < paramTypes.length; i++) {
                        omv.visitVarInsn(paramTypes[i].getOpcode(ILOAD), param);
                        param += paramTypes[i].getSize();
                    }
                    omv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet", "()L" + MEMORYSTACK + ";",
                            false);
                    boolean isPrivate = (access & ACC_PRIVATE) != 0;
                    int opcode = isStatic ? INVOKESTATIC : isPrivate ? INVOKESPECIAL : INVOKEVIRTUAL;
                    omv.visitMethodInsn(opcode, className, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                    Type retType = Type.getReturnType(desc);
                    omv.visitInsn(retType.getOpcode(IRETURN));
                    omv.visitMaxs(-1, -1);
                    omv.visitEnd();
                } else {
                    mv = super.visitMethod(access, name, desc, signature, exceptions);
                }
                if (catches)
                    mv = new TryCatchBlockSorter(mv, access, name, desc, signature, exceptions);
                mv = new MethodVisitor(ASM5, mv) {
                    Label tryLabel = new Label();
                    Label finallyLabel = new Label();
                    int lastLine = 0;
                    boolean newStack = classDefaultNewStack;
                    int stackVarIndex;
                    int stackPointerVarIndex;
                    int firstAdditionalLocal;
                    int additionalLocals;
                    Object[] replacedLocals;

                    public void visitInsn(int opcode) {
                        if (notransform) {
                            mv.visitInsn(opcode);
                            return;
                        }
                        if (opcode >= IRETURN && opcode <= RETURN && (newStack || checkStack)) {
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of return at "
                                        + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            } else if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStack$", "(II)V", false);
                            }
                        }
                        mv.visitInsn(opcode);
                    }

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lautostack/UseCallerStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use caller stack");
                                newStack = false;
                            }
                            return null;
                        } else if ("Lautostack/UseNewStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use new stack");
                                newStack = true;
                            }
                            return null;
                        } else if ("Lautostack/NoTransform;".equals(desc)) {
                            return null;
                        } else if ("Lautostack/NoStackParam;".equals(desc)) {
                            return null;
                        }
                        return mv.visitAnnotation(desc, visible);
                    }

                    public void visitVarInsn(int opcode, int var) {
                        if (notransform) {
                            mv.visitVarInsn(opcode, var);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitVarInsn(opcode, var);
                    }

                    public void visitIincInsn(int var, int increment) {
                        if (notransform) {
                            mv.visitIincInsn(var, increment);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitIincInsn(var, increment);
                    }

                    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
                        if (notransform) {
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                            return;
                        }
                        if (type == F_FULL) {
                            int noThis = isStatic ? 0 : 1;
                            Object[] locals = new Object[local.length + additionalLocals];
                            if (!isStatic)
                                locals[0] = local[0];
                            int replacementLength = replacedLocals.length;
                            System.arraycopy(replacedLocals, noThis, locals, noThis,
                                    replacementLength - noThis);
                            int len = locals.length - replacementLength;
                            System.arraycopy(local, replacementLength - additionalLocals, locals,
                                    replacementLength, len);
                            mv.visitFrame(type, nLocal + additionalLocals, locals, nStack, stack);
                        } else
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                    }

                    public void visitLocalVariable(String name, String desc, String signature, Label start,
                            Label end, int index) {
                        if (notransform) {
                            mv.visitLocalVariable(className, desc, signature, start, end, index);
                            return;
                        }
                        if (index >= firstAdditionalLocal)
                            index += additionalLocals;
                        mv.visitLocalVariable(name, desc, signature, start, end, index);
                    }

                    private boolean doesNotTakeStackItself(String desc) {
                        return desc.lastIndexOf("L" + MEMORYSTACK + ";)") == -1;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        String completeName = name + desc;
                        Integer info = stackMethods.get(completeName);
                        if (opcode != INVOKESTATIC || notransform) {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                            return;
                        }
                        if (stackAsParameter && info != null && (info.intValue() & 8) != 0
                                && (info.intValue() & 16) == 0) {
                            /* Rewrite invocation to have additional MemoryStack parameter */
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> "
                                                + owner.replace('/', '.') + "." + name + "(..., MemoryStack)");
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, itf);
                            return;
                        }
                        if (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                && doesNotTakeStackItself(desc)) {
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> aload " + stackVarIndex
                                                + "; invokestatic " + owner.replace('/', '.') + "." + name);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackGet")) {
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackPush") || name.equals("stackPop"))) {
                            String newName = "p" + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.startsWith("stackMalloc") || name.startsWith("stackCalloc"))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitInsn(SWAP);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK) && (name.equals("stackASCII")
                                || name.equals("stackUTF8") || name.equals("stackUTF16"))) {
                            String newName = name.substring(5);
                            boolean withBoolean = desc.startsWith("(Ljava/lang/CharSequence;Z");
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            if (withBoolean) {
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                            } else {
                                mv.visitInsn(SWAP);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackFloats") || name.equals("stackInts")
                                        || name.equals("stackBytes") || name.equals("stackShorts")
                                        || name.equals("stackPointers")
                                                && (desc.startsWith("([Lorg/lwjgl/system/Pointer;")
                                                        || desc.startsWith("(Lorg/lwjgl/system/Pointer;")))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 2) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 3) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP2_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                                mv.visitInsn(SWAP);
                                mv.visitInsn(POP);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackLongs")) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                        }
                    }

                    public void visitLineNumber(int line, Label start) {
                        mv.visitLineNumber(line, start);
                        lastLine = line;
                    }

                    public void visitCode() {
                        if (notransform) {
                            mv.visitCode();
                            return;
                        }
                        additionalLocals = newStack || checkStack ? 2 : 1;
                        replacedLocals = new Object[paramTypes.length + additionalLocals + (isStatic ? 0 : 1)];
                        if (!newStack && !checkStack) {
                            replacedLocals[replacedLocals.length - 1] = MEMORYSTACK;
                        } else {
                            replacedLocals[replacedLocals.length - 2] = MEMORYSTACK;
                            replacedLocals[replacedLocals.length - 1] = INTEGER;
                        }
                        if (!isStatic)
                            replacedLocals[0] = isConstructor ? TOP : className;
                        int var = isStatic ? 0 : 1;
                        for (int t = 0, i = var; t < paramTypes.length; t++, i++) {
                            Type type = paramTypes[t];
                            var += type.getSize();
                            switch (type.getSort()) {
                            case Type.INT:
                            case Type.BYTE:
                            case Type.BOOLEAN:
                            case Type.SHORT:
                            case Type.CHAR:
                                replacedLocals[i] = INTEGER;
                                break;
                            case Type.LONG:
                                replacedLocals[i] = LONG;
                                break;
                            case Type.FLOAT:
                                replacedLocals[i] = FLOAT;
                                break;
                            case Type.DOUBLE:
                                replacedLocals[i] = DOUBLE;
                                break;
                            case Type.OBJECT:
                            case Type.ARRAY:
                                replacedLocals[i] = type.getInternalName();
                                break;
                            default:
                                throw new AssertionError("Unhandled parameter type: " + type);
                            }
                        }
                        firstAdditionalLocal = var;
                        stackVarIndex = var;
                        stackPointerVarIndex = var + 1;
                        mv.visitCode();
                        if (newStack && !checkStack || checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitInsn(DUP);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            } else {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                            mv.visitVarInsn(ISTORE, stackPointerVarIndex);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] save stack pointer [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 2, new Object[] { MEMORYSTACK, INTEGER }, 0, null);
                            else
                                mv.visitFrame(F_APPEND, 1, new Object[] { INTEGER }, 0, null);
                        } else if (!newStack && !checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            }
                            if (debugRuntime) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] current stack pointer is [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 1, new Object[] { MEMORYSTACK }, 0, null);
                        }
                    }

                    public void visitMaxs(int maxStack, int maxLocals) {
                        if (notransform) {
                            mv.visitMaxs(maxStack, maxLocals);
                            return;
                        }
                        if (newStack && !checkStack || checkStack) {
                            mv.visitLabel(finallyLabel);
                            mv.visitFrame(F_FULL, replacedLocals.length, replacedLocals, 1,
                                    new Object[] { "java/lang/Throwable" });
                            mv.visitTryCatchBlock(tryLabel, finallyLabel, finallyLabel, null);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of throw [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitInsn(DUP);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString",
                                        "()Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn(
                                        "] at " + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            }
                            if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStackWithThrowable$",
                                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", false);
                            }
                            mv.visitInsn(ATHROW);
                        }
                        mv.visitMaxs(-1, maxLocals + additionalLocals);
                    }
                };
                return mv;
            }
        }, 0);
        byte[] arr = cw.toByteArray();
        if (trace) {
            cr = new ClassReader(arr);
            cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
        }
        return arr;
    } catch (Throwable t) {
        t.printStackTrace();
        throw new RuntimeException(t);
    }
}

From source file:br.usp.each.saeg.badua.test.validation.MaxTest.java

License:Open Source License

@Override
@Before/*  w  w  w.j av a  2s  .c o  m*/
public void setUp() throws Exception {
    super.setUp();

    final int classVersion = Opcodes.V1_6;
    final int classAccessor = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER;
    final String className = "Max";
    final String superName = "java/lang/Object";

    final int methodAccessor = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
    final String methodName = "max";
    final String methodDesc = "([II)I";

    final ClassWriter cw = new ClassWriter(0);
    final MethodVisitor mw;

    cw.visit(classVersion, classAccessor, className, null, superName, null);
    mw = cw.visitMethod(methodAccessor, methodName, methodDesc, null, null);
    mw.visitCode();
    // block 0 (definitions {0, 1, 2, 3})
    mw.visitInsn(Opcodes.ICONST_0);
    mw.visitVarInsn(Opcodes.ISTORE, 2);
    mw.visitVarInsn(Opcodes.ALOAD, 0);
    mw.visitVarInsn(Opcodes.ILOAD, 2);
    mw.visitIincInsn(2, 1);
    mw.visitInsn(Opcodes.IALOAD);
    mw.visitVarInsn(Opcodes.ISTORE, 3);
    // block 1 (p-uses {1, 2})
    final Label backLoop = new Label();
    mw.visitLabel(backLoop);
    mw.visitVarInsn(Opcodes.ILOAD, 2);
    mw.visitVarInsn(Opcodes.ILOAD, 1);
    final Label breakLoop = new Label();
    mw.visitJumpInsn(Opcodes.IF_ICMPGE, breakLoop);
    // block 3 (p-uses {0, 2, 3})
    mw.visitVarInsn(Opcodes.ALOAD, 0);
    mw.visitVarInsn(Opcodes.ILOAD, 2);
    mw.visitInsn(Opcodes.IALOAD);
    mw.visitVarInsn(Opcodes.ILOAD, 3);
    final Label jump = new Label();
    mw.visitJumpInsn(Opcodes.IF_ICMPLE, jump);
    // block 5 (definitions {3}, uses {0, 2})
    mw.visitVarInsn(Opcodes.ALOAD, 0);
    mw.visitVarInsn(Opcodes.ILOAD, 2);
    mw.visitInsn(Opcodes.IALOAD);
    mw.visitVarInsn(Opcodes.ISTORE, 3);
    // block 4 (definitions {2}, uses {2})
    mw.visitLabel(jump);
    mw.visitIincInsn(2, 1);
    mw.visitJumpInsn(Opcodes.GOTO, backLoop);
    // block 2 ( uses {3})
    mw.visitLabel(breakLoop);
    mw.visitVarInsn(Opcodes.ILOAD, 3);
    mw.visitInsn(Opcodes.IRETURN);
    mw.visitMaxs(2, 4);
    mw.visitEnd();
    cw.visitEnd();

    final byte[] bytes = cw.toByteArray();
    klass = addClass(className, bytes);
    method = klass.getMethod(methodName, int[].class, int.class);
    classId = CRC64.checksum(bytes);

    RT.init(new RuntimeData());
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateEncodeSequenceValue(Class<?> javaClass, LocalVariable nextVar, MethodVisitor mv,
        boolean required, int outputStreamVar, Class<?> componentJavaClass, TypeDef type, Schema schema,
        String genClassInternalName, String fieldIdentifier, String debugValueLabel, boolean javaClassCodec)
        throws IllegalArgumentException {

    // PENDING: merge the two if-cases, and reuse common code blocks (see generateDecodeSquenceValue)
    if (javaClass.isArray()) {
        int sequenceVar = nextVar.next();
        mv.visitInsn(DUP);//from  www. ja  v a  2s . c  o m
        mv.visitVarInsn(ASTORE, sequenceVar);
        int lengthVar = nextVar.next();
        Label endLabel = new Label();
        if (required) {
            mv.visitInsn(ARRAYLENGTH);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        } else {
            Label nonNullLabel = new Label();
            mv.visitInsn(DUP);
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitInsn(POP);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeNull",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;)V", false);
            mv.visitJumpInsn(GOTO, endLabel);
            // not null
            mv.visitLabel(nonNullLabel);
            // PENDING: mv.visitFrame?
            mv.visitInsn(ARRAYLENGTH);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        }
        // for loop
        int loopVar = nextVar.next();
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, loopVar);
        Label loopLabel = new Label();
        mv.visitLabel(loopLabel);
        // PENDING: mv.visitFrame?
        mv.visitVarInsn(ILOAD, loopVar);
        mv.visitVarInsn(ILOAD, lengthVar);
        mv.visitJumpInsn(IF_ICMPGE, endLabel);
        mv.visitVarInsn(ALOAD, outputStreamVar);
        mv.visitVarInsn(ALOAD, sequenceVar);
        mv.visitVarInsn(ILOAD, loopVar);
        if (componentJavaClass == byte.class || componentJavaClass == boolean.class) {
            mv.visitInsn(BALOAD);
        } else if (componentJavaClass == short.class) {
            mv.visitInsn(SALOAD);
        } else if (componentJavaClass == int.class) {
            mv.visitInsn(IALOAD);
        } else if (componentJavaClass == long.class) {
            mv.visitInsn(LALOAD);
        } else if (componentJavaClass == float.class) {
            mv.visitInsn(FALOAD);
        } else if (componentJavaClass == double.class) {
            mv.visitInsn(DALOAD);
        } else if (componentJavaClass == char.class) {
            mv.visitInsn(CALOAD);
        } else {
            mv.visitInsn(AALOAD);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(componentJavaClass));
        }

        // encode the element
        TypeDef.Sequence seqType = (TypeDef.Sequence) type;
        generateEncodeValue(mv, outputStreamVar, nextVar, true, seqType.getComponentType(), componentJavaClass,
                null, schema, genClassInternalName, fieldIdentifier, debugValueLabel + ".component",
                javaClassCodec);

        mv.visitIincInsn(loopVar, 1);
        mv.visitJumpInsn(GOTO, loopLabel);
        mv.visitLabel(endLabel);
        // PENDING: mv.visitFrame?

    } else if (javaClass == List.class) {
        int sequenceVar = nextVar.next();
        mv.visitInsn(DUP);
        mv.visitVarInsn(ASTORE, sequenceVar);
        int lengthVar = nextVar.next();
        Label endLabel = new Label();
        if (required) {
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        } else {
            Label nonNullLabel = new Label();
            mv.visitInsn(DUP);
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitInsn(POP);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeNull",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;)V", false);
            mv.visitJumpInsn(GOTO, endLabel);
            // not null
            mv.visitLabel(nonNullLabel);
            // PENDING: mv.visitFrame?
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        }
        // for loop, using iterator
        int iteratorVar = nextVar.next();
        mv.visitVarInsn(ALOAD, sequenceVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
        mv.visitVarInsn(ASTORE, iteratorVar);
        Label loopLabel = new Label();
        mv.visitLabel(loopLabel);
        // PENDING: mv.visitFrame?
        mv.visitVarInsn(ALOAD, iteratorVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
        mv.visitJumpInsn(IFEQ, endLabel);
        mv.visitVarInsn(ALOAD, outputStreamVar);
        mv.visitVarInsn(ALOAD, iteratorVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
        if (componentJavaClass.isPrimitive()) {
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(box(componentJavaClass)));
            unbox(mv, componentJavaClass);
        } else {
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(componentJavaClass));
        }

        // encode the element
        TypeDef.Sequence seqType = (TypeDef.Sequence) type;
        generateEncodeValue(mv, outputStreamVar, nextVar, true, seqType.getComponentType(), componentJavaClass,
                null, schema, genClassInternalName, fieldIdentifier, debugValueLabel + ".component",
                javaClassCodec);

        mv.visitJumpInsn(GOTO, loopLabel);
        mv.visitLabel(endLabel);
        // PENDING: mv.visitFrame?
    } else {
        throw new IllegalArgumentException("Illegal sequence javaClass: " + javaClass);
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateDecodeSequenceValue(Class<?> javaClass, LocalVariable nextVar, boolean required,
        MethodVisitor mv, Class<?> componentJavaClass, int byteSourceVar, TypeDef type, Schema schema,
        String genClassInternalName, String fieldIdentifier, String debugValueLabel, boolean javaClassCodec)
        throws IllegalArgumentException {
    if (!javaClass.isArray() && javaClass != List.class) {
        throw new IllegalArgumentException("Illegal sequence javaClass: " + javaClass);
    }//w  w w .  j  a  v a  2  s  . c o  m

    int lengthVar = nextVar.next();
    int sequenceVar = nextVar.next();
    Label finalEndLabel = new Label();
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkInputIName, "readUInt32",
                "(Lcom/cinnober/msgcodec/io/ByteSource;)I", false);
        mv.visitVarInsn(ISTORE, lengthVar);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkInputIName, "readUInt32Null",
                "(Lcom/cinnober/msgcodec/io/ByteSource;)Ljava/lang/Integer;", false);
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNULL, finalEndLabel);
        unbox(mv, Integer.class);
        mv.visitVarInsn(ISTORE, lengthVar);
    }

    if (javaClass.isArray()) {
        mv.visitVarInsn(ILOAD, lengthVar);
        generateNewArray(mv, componentJavaClass);
    } else {
        mv.visitTypeInsn(NEW, "java/util/ArrayList");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ILOAD, lengthVar);
        mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false);
    }
    mv.visitVarInsn(ASTORE, sequenceVar);

    // for loop
    Label endLabel = new Label();
    int loopVar = nextVar.next();
    mv.visitInsn(ICONST_0);
    mv.visitVarInsn(ISTORE, loopVar);
    Label loopLabel = new Label();
    mv.visitLabel(loopLabel);
    // PENDING: mv.visitFrame?
    mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ILOAD, loopVar);
    mv.visitVarInsn(ILOAD, lengthVar);
    mv.visitJumpInsn(IF_ICMPGE, endLabel);

    mv.visitVarInsn(ALOAD, sequenceVar);
    mv.visitVarInsn(ILOAD, loopVar);
    mv.visitVarInsn(ALOAD, byteSourceVar);

    // decode the element
    TypeDef.Sequence seqType = (TypeDef.Sequence) type;
    generateDecodeValue(mv, byteSourceVar, nextVar, true, seqType.getComponentType(), componentJavaClass, null,
            schema, genClassInternalName, fieldIdentifier, debugValueLabel + ".component", javaClassCodec);

    // store the value
    if (javaClass.isArray()) {
        generateArrayStore(mv, componentJavaClass);
    } else {
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "add", "(ILjava/lang/Object;)V", false);
    }

    mv.visitIincInsn(loopVar, 1);
    mv.visitJumpInsn(GOTO, loopLabel);
    mv.visitLabel(endLabel);
    mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, sequenceVar);
    mv.visitLabel(finalEndLabel);
    mv.visitFrame(F_SAME, 0, null, 0, null);
    if (javaClass.isArray()) {
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass));
    }
}

From source file:com.google.devtools.build.lib.syntax.compiler.IntegerVariableIncrease.java

License:Open Source License

@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
    methodVisitor.visitIincInsn(variable.index, increment);
    return new Size(0, 0);
}

From source file:com.google.gwtorm.jdbc.AccessGen.java

License:Apache License

private void doFetchOne(final MethodVisitor mv, final CodeGenSupport cgs, final ColumnModel field,
        final int reportLiveInto) {
    if (field.isNested()) {
        int oldIdx = cgs.getColumnIndex();
        final Type vType = CodeGenSupport.toType(field);
        final int livecnt;

        if (field.isNotNull()) {
            livecnt = -1;//from ww w .j  a  va  2  s.c  o  m
        } else {
            livecnt = cgs.newLocal();
            cgs.push(0);
            mv.visitVarInsn(ISTORE, livecnt);
        }

        cgs.setFieldReference(field);
        cgs.fieldSetBegin();
        mv.visitTypeInsn(NEW, vType.getInternalName());
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, vType.getInternalName(), "<init>",
                Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
        cgs.fieldSetEnd();

        cgs.resetColumnIndex(oldIdx);
        for (final ColumnModel c : field.getNestedColumns()) {
            doFetchOne(mv, cgs, c, livecnt);
        }

        if (livecnt >= 0) {
            oldIdx = cgs.getColumnIndex();

            final Label islive = new Label();
            mv.visitVarInsn(ILOAD, livecnt);
            mv.visitJumpInsn(IFNE, islive);
            cgs.setFieldReference(field);
            cgs.fieldSetBegin();
            mv.visitInsn(ACONST_NULL);
            cgs.fieldSetEnd();

            if (reportLiveInto >= 0) {
                final Label end = new Label();
                mv.visitJumpInsn(GOTO, end);
                mv.visitLabel(islive);
                mv.visitIincInsn(reportLiveInto, 1);
                mv.visitLabel(end);
            } else {
                mv.visitLabel(islive);
            }

            cgs.resetColumnIndex(oldIdx);
            cgs.freeLocal(livecnt);
        }

    } else {
        final int dupTo;
        if (reportLiveInto >= 0 && CodeGenSupport.toType(field).getSort() == Type.OBJECT) {
            dupTo = cgs.newLocal();
        } else {
            dupTo = -1;
        }

        cgs.setFieldReference(field);
        cgs.setDupOnFieldSetEnd(dupTo);
        dialect.getSqlTypeInfo(field).generateResultSetGet(cgs);

        if (reportLiveInto >= 0) {
            final Label wasnull = new Label();
            if (dupTo >= 0) {
                mv.visitVarInsn(ALOAD, dupTo);
                mv.visitJumpInsn(IFNULL, wasnull);
                cgs.freeLocal(dupTo);
            } else {
                cgs.pushSqlHandle();
                mv.visitMethodInsn(INVOKEINTERFACE, Type.getType(ResultSet.class).getInternalName(), "wasNull",
                        Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
                mv.visitJumpInsn(IFNE, wasnull);
            }
            mv.visitIincInsn(reportLiveInto, 1);
            mv.visitLabel(wasnull);
        }
    }
}

From source file:com.google.gwtorm.jdbc.AccessGen.java

License:Apache License

private void overrideGetMany() {
    final KeyModel pk = model.getPrimaryKey();
    final StringBuilder query = new StringBuilder();
    query.append(model.getSelectSql(dialect, REL_ALIAS));
    query.append(" WHERE ");
    final ColumnModel pkcol = pk.getAllLeafColumns().iterator().next();
    query.append(REL_ALIAS);/* w  w  w  . java  2s  .  c o m*/
    query.append('.');
    query.append(pkcol.getColumnName());
    query.append(" IN");

    final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_FINAL, "getBySqlIn",
            Type.getMethodDescriptor(Type.getType(com.google.gwtorm.server.ResultSet.class),
                    new Type[] { Type.getType(Collection.class) }),
            null, new String[] { Type.getType(OrmException.class).getInternalName() });
    mv.visitCode();

    final int keyset = 1;
    final int psvar = 2;
    final int itrvar = 3;
    final int colvar = 4;
    final int keyvar = 5;

    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(query.toString());
    mv.visitVarInsn(ALOAD, keyset);
    mv.visitMethodInsn(INVOKEVIRTUAL, superTypeName, "prepareBySqlIn",
            Type.getMethodDescriptor(Type.getType(PreparedStatement.class),
                    new Type[] { Type.getType(String.class), Type.getType(Collection.class) }));
    mv.visitVarInsn(ASTORE, psvar);

    mv.visitVarInsn(ALOAD, keyset);
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Collection.class), "iterator",
            Type.getMethodDescriptor(Type.getType(Iterator.class), new Type[] {}));
    mv.visitVarInsn(ASTORE, itrvar);

    mv.visitInsn(ICONST_1);
    mv.visitVarInsn(ISTORE, colvar);

    final Label endbind = new Label();
    final Label again = new Label();
    mv.visitLabel(again);
    mv.visitVarInsn(ALOAD, itrvar);
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Iterator.class), "hasNext",
            Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
    mv.visitJumpInsn(IFEQ, endbind);

    mv.visitVarInsn(ALOAD, itrvar);
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Iterator.class), "next",
            Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {}));
    mv.visitTypeInsn(CHECKCAST, CodeGenSupport.toType(pk.getField()).getInternalName());
    mv.visitVarInsn(ASTORE, keyvar);

    final CodeGenSupport cgs = new CodeGenSupport(mv) {
        @Override
        public void pushSqlHandle() {
            mv.visitVarInsn(ALOAD, psvar);
        }

        @Override
        public void pushFieldValue() {
            appendGetField(getFieldReference());
        }

        @Override
        public void pushColumnIndex() {
            mv.visitVarInsn(ILOAD, colvar);
        }

        @Override
        protected void appendGetField(final ColumnModel c) {
            if (c.getParent() == null) {
                mv.visitVarInsn(ALOAD, keyvar);
            } else {
                super.appendGetField(c);
            }
        }
    };

    cgs.setFieldReference(pkcol);
    dialect.getSqlTypeInfo(pkcol).generatePreparedStatementSet(cgs);
    mv.visitIincInsn(colvar, 1);
    mv.visitJumpInsn(GOTO, again);

    mv.visitLabel(endbind);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, psvar);
    mv.visitMethodInsn(INVOKEVIRTUAL, superTypeName, "queryList",
            Type.getMethodDescriptor(Type.getType(com.google.gwtorm.server.ResultSet.class),
                    new Type[] { Type.getType(PreparedStatement.class) }));
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
}

From source file:com.googlecode.d2j.converter.IR2JConverter.java

License:Apache License

private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
    asm = new LdcOptimizeAdapter(asm);
    int maxLocalIndex = 0;
    for (Local local : ir.locals) {
        maxLocalIndex = Math.max(maxLocalIndex, local._ls_index);
    }/*from w w  w  .  j  a v a2s  .c  om*/
    Map<String, Integer> lockMap = new HashMap<String, Integer>();
    for (Stmt st : ir.stmts) {
        switch (st.st) {
        case LABEL:
            LabelStmt labelStmt = (LabelStmt) st;
            Label label = (Label) labelStmt.tag;
            asm.visitLabel(label);
            if (labelStmt.lineNumber >= 0) {
                asm.visitLineNumber(labelStmt.lineNumber, label);
            }
            break;
        case ASSIGN: {
            E2Stmt e2 = (E2Stmt) st;
            Value v1 = e2.op1;
            Value v2 = e2.op2;
            switch (v1.vt) {
            case LOCAL:

                Local local = ((Local) v1);
                int i = local._ls_index;

                if (v2.vt == VT.LOCAL && (i == ((Local) v2)._ls_index)) {//
                    continue;
                }

                boolean skipOrg = false;
                if (v1.valueType.charAt(0) == 'I') {// check for IINC
                    if (v2.vt == VT.ADD) {
                        E2Expr e = (E2Expr) v2;
                        if ((e.op1 == local && e.op2.vt == VT.CONSTANT)
                                || (e.op2 == local && e.op1.vt == VT.CONSTANT)) {
                            int increment = (Integer) ((Constant) (e.op1 == local ? e.op2 : e.op1)).value;
                            if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                asm.visitIincInsn(i, increment);
                                skipOrg = true;
                            }
                        }
                    } else if (v2.vt == VT.SUB) {
                        E2Expr e = (E2Expr) v2;
                        if (e.op1 == local && e.op2.vt == VT.CONSTANT) {
                            int increment = -(Integer) ((Constant) e.op2).value;
                            if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                asm.visitIincInsn(i, increment);
                                skipOrg = true;
                            }
                        }
                    }
                }
                if (!skipOrg) {
                    accept(v2, asm);
                    if (i >= 0) {
                        asm.visitVarInsn(getOpcode(v1, ISTORE), i);
                    } else if (!v1.valueType.equals("V")) { // skip void type locals
                        switch (v1.valueType.charAt(0)) {
                        case 'J':
                        case 'D':
                            asm.visitInsn(POP2);
                            break;
                        default:
                            asm.visitInsn(POP);
                            break;
                        }
                    }
                }
                break;
            case STATIC_FIELD: {
                StaticFieldExpr fe = (StaticFieldExpr) v1;
                accept(v2, asm);
                insertI2x(v2.valueType, fe.type, asm);
                asm.visitFieldInsn(PUTSTATIC, toInternal(fe.owner), fe.name, fe.type);
                break;
            }
            case FIELD: {
                FieldExpr fe = (FieldExpr) v1;
                accept(fe.op, asm);
                accept(v2, asm);
                insertI2x(v2.valueType, fe.type, asm);
                asm.visitFieldInsn(PUTFIELD, toInternal(fe.owner), fe.name, fe.type);
                break;
            }
            case ARRAY:
                ArrayExpr ae = (ArrayExpr) v1;
                accept(ae.op1, asm);
                accept(ae.op2, asm);
                accept(v2, asm);
                String tp1 = ae.op1.valueType;
                String tp2 = ae.valueType;
                if (tp1.charAt(0) == '[') {
                    String arrayElementType = tp1.substring(1);
                    insertI2x(v2.valueType, arrayElementType, asm);
                    asm.visitInsn(getOpcode(arrayElementType, IASTORE));
                } else {
                    asm.visitInsn(getOpcode(tp2, IASTORE));
                }
                break;
            }
        }
            break;
        case IDENTITY: {
            E2Stmt e2 = (E2Stmt) st;
            if (e2.op2.vt == VT.EXCEPTION_REF) {
                int index = ((Local) e2.op1)._ls_index;
                if (index >= 0) {
                    asm.visitVarInsn(ASTORE, index);
                } else {
                    asm.visitInsn(POP);
                }
            }
        }
            break;

        case FILL_ARRAY_DATA: {
            E2Stmt e2 = (E2Stmt) st;
            Object arrayData = ((Constant) e2.getOp2()).value;
            int arraySize = Array.getLength(arrayData);
            String arrayValueType = e2.getOp1().valueType;
            String elementType;
            if (arrayValueType.charAt(0) == '[') {
                elementType = arrayValueType.substring(1);
            } else {
                elementType = "I";
            }
            int iastoreOP = getOpcode(elementType, IASTORE);
            accept(e2.getOp1(), asm);
            for (int i = 0; i < arraySize; i++) {
                asm.visitInsn(DUP);
                asm.visitLdcInsn(i);
                asm.visitLdcInsn(Array.get(arrayData, i));
                asm.visitInsn(iastoreOP);
            }
            asm.visitInsn(POP);
        }
            break;
        case GOTO:
            asm.visitJumpInsn(GOTO, (Label) ((GotoStmt) st).target.tag);
            break;
        case IF:
            reBuildJumpInstructions((IfStmt) st, asm);
            break;
        case LOCK: {
            Value v = ((UnopStmt) st).op;
            accept(v, asm);
            if (optimizeSynchronized) {
                switch (v.vt) {
                case LOCAL:
                    // FIXME do we have to disable local due to OptSyncTest ?
                    // break;
                case CONSTANT: {
                    String key;
                    if (v.vt == VT.LOCAL) {
                        key = "L" + ((Local) v)._ls_index;
                    } else {
                        key = "C" + ((Constant) v).value;
                    }
                    Integer integer = lockMap.get(key);
                    int nIndex = integer != null ? integer : ++maxLocalIndex;
                    asm.visitInsn(DUP);
                    asm.visitVarInsn(getOpcode(v, ISTORE), nIndex);
                    lockMap.put(key, nIndex);
                }
                    break;
                default:
                    throw new RuntimeException();
                }
            }
            asm.visitInsn(MONITORENTER);
        }
            break;
        case UNLOCK: {
            Value v = ((UnopStmt) st).op;
            if (optimizeSynchronized) {
                switch (v.vt) {
                case LOCAL:
                case CONSTANT: {
                    String key;
                    if (v.vt == VT.LOCAL) {
                        key = "L" + ((Local) v)._ls_index;
                    } else {
                        key = "C" + ((Constant) v).value;
                    }
                    Integer integer = lockMap.get(key);
                    if (integer != null) {
                        asm.visitVarInsn(getOpcode(v, ILOAD), integer);
                    } else {
                        accept(v, asm);
                    }
                }
                    break;
                // TODO other
                default: {
                    accept(v, asm);
                    break;
                }
                }
            } else {
                accept(v, asm);
            }
            asm.visitInsn(MONITOREXIT);
        }
            break;
        case NOP:
            break;
        case RETURN: {
            Value v = ((UnopStmt) st).op;
            accept(v, asm);
            insertI2x(v.valueType, ir.ret, asm);
            asm.visitInsn(getOpcode(v, IRETURN));
        }
            break;
        case RETURN_VOID:
            asm.visitInsn(RETURN);
            break;
        case LOOKUP_SWITCH: {
            LookupSwitchStmt lss = (LookupSwitchStmt) st;
            accept(lss.op, asm);
            Label targets[] = new Label[lss.targets.length];
            for (int i = 0; i < targets.length; i++) {
                targets[i] = (Label) lss.targets[i].tag;
            }
            asm.visitLookupSwitchInsn((Label) lss.defaultTarget.tag, lss.lookupValues, targets);
        }
            break;
        case TABLE_SWITCH: {
            TableSwitchStmt tss = (TableSwitchStmt) st;
            accept(tss.op, asm);
            Label targets[] = new Label[tss.targets.length];
            for (int i = 0; i < targets.length; i++) {
                targets[i] = (Label) tss.targets[i].tag;
            }
            asm.visitTableSwitchInsn(tss.lowIndex, tss.lowIndex + targets.length - 1,
                    (Label) tss.defaultTarget.tag, targets);
        }
            break;
        case THROW:
            accept(((UnopStmt) st).op, asm);
            asm.visitInsn(ATHROW);
            break;
        case VOID_INVOKE:
            InvokeExpr invokeExpr = (InvokeExpr) st.getOp();
            accept(invokeExpr, asm);
            String ret = invokeExpr.ret;
            if (invokeExpr.vt == VT.INVOKE_NEW) {
                asm.visitInsn(POP);
            } else if (!"V".equals(ret)) {
                switch (ret.charAt(0)) {
                case 'J':
                case 'D':
                    asm.visitInsn(POP2);
                    break;
                default:
                    asm.visitInsn(POP);
                    break;
                }
            }
            break;
        default:
            throw new RuntimeException("not support st: " + st.st);
        }

    }
}

From source file:com.googlecode.ddom.weaver.asm.MethodVisitorTee.java

License:Apache License

public void visitIincInsn(int var, int increment) {
    for (MethodVisitor visitor : visitors) {
        visitor.visitIincInsn(var, increment);
    }/*from w ww .  j av  a2  s  .  co m*/
}

From source file:com.nginious.http.xsp.ForEachTagPart.java

License:Apache License

/**
 * Creates bytecode in a separate method for evaluating this for each tag part.
 * /*from   www .  j  a  v  a2 s .  co  m*/
 * @param intClassName the binary class name of the class being created
 * @param writer the class writer
 * @throws XspException if unable to create bytecode
 */
void compileMethod(String intClassName, ClassWriter writer) throws XspException {
    String[] exceptions = { "com/nginious/http/xsp/XspException" };
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PRIVATE, this.methodName,
            "(Lcom/nginious/http/HttpRequest;Lcom/nginious/http/HttpResponse;Ljava/lang/StringBuffer;)V", null,
            exceptions);
    visitor.visitCode();

    Label tryLabel = new Label();
    Label startCatchLabel = new Label();

    // Start try block
    visitor.visitTryCatchBlock(tryLabel, startCatchLabel, startCatchLabel, "java/lang/Exception");
    visitor.visitLabel(tryLabel);

    try {
        String expression = setValue.getExpressionContent();
        ExpressionParser parser = new ExpressionParser();
        TreeExpression expr = parser.parse(expression);

        if (expr.getType() != Type.ANY) {
            throw new XspException("Expression in attribute set in tag " + getName()
                    + " is not an attribute or bean property " + " at line " + getLocationDescriptor());
        }

        expr.compile(visitor, Type.ANY);
        visitor.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Collection");
        visitor.visitVarInsn(Opcodes.ASTORE, 4);
    } catch (ExpressionException e) {
        throw new XspException("Invalid expression in attribute set in tag " + getName() + " at line "
                + getLocationDescriptor(), e);
    }

    Label labelOut = new Label();
    visitor.visitVarInsn(Opcodes.ALOAD, 4);
    visitor.visitJumpInsn(Opcodes.IFNULL, labelOut);

    // Start
    if (this.start != null) {
        start.compile(visitor, Type.INT);
    } else {
        visitor.visitLdcInsn((int) 0);
    }

    visitor.visitVarInsn(Opcodes.ISTORE, 5);

    // End
    if (this.end != null) {
        end.compile(visitor, Type.INT);
    } else {
        visitor.visitVarInsn(Opcodes.ALOAD, 4);
        visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Collection", "size", "()I");
    }

    visitor.visitVarInsn(Opcodes.ISTORE, 6);

    // Step
    if (this.step != null) {
        step.compile(visitor, Type.INT);
    } else {
        visitor.visitLdcInsn((int) 1);
    }

    visitor.visitVarInsn(Opcodes.ISTORE, 7);

    // Current pos
    visitor.visitLdcInsn(0);
    visitor.visitVarInsn(Opcodes.ISTORE, 8);

    visitor.visitVarInsn(Opcodes.ALOAD, 4);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Collection", "iterator",
            "()Ljava/util/Iterator;");
    visitor.visitVarInsn(Opcodes.ASTORE, 9);

    Label labelStart = new Label();

    // Start of loop
    visitor.visitLabel(labelStart);

    // iterator.hasNext();
    visitor.visitVarInsn(Opcodes.ALOAD, 9);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z");
    visitor.visitJumpInsn(Opcodes.IFEQ, labelOut);

    // iterator.next();
    visitor.visitVarInsn(Opcodes.ALOAD, 9);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;");
    visitor.visitVarInsn(Opcodes.ASTORE, 10);

    // pos >= start && pos <= end && (pos - start) % step == 0
    Label labelIncr = new Label();

    visitor.visitVarInsn(Opcodes.ILOAD, 8);
    visitor.visitVarInsn(Opcodes.ILOAD, 5);
    visitor.visitJumpInsn(Opcodes.IF_ICMPLT, labelIncr);

    visitor.visitVarInsn(Opcodes.ILOAD, 8);
    visitor.visitVarInsn(Opcodes.ILOAD, 6);
    visitor.visitJumpInsn(Opcodes.IF_ICMPGT, labelIncr);

    visitor.visitVarInsn(Opcodes.ILOAD, 8);
    visitor.visitVarInsn(Opcodes.ILOAD, 5);
    visitor.visitInsn(Opcodes.ISUB);
    visitor.visitVarInsn(Opcodes.ILOAD, 7);
    visitor.visitInsn(Opcodes.IREM);
    visitor.visitJumpInsn(Opcodes.IFNE, labelIncr);

    visitor.visitVarInsn(Opcodes.ALOAD, 1);
    varName.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ALOAD, 10);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/nginious/http/HttpRequest", "setAttribute",
            "(Ljava/lang/String;Ljava/lang/Object;)V");

    // Call sub parts
    for (XspPart part : this.contentParts) {
        part.compile(intClassName, writer, visitor);
    }

    // pos++
    visitor.visitLabel(labelIncr);
    visitor.visitIincInsn(8, 1);
    visitor.visitJumpInsn(Opcodes.GOTO, labelStart);

    visitor.visitLabel(labelOut);
    visitor.visitInsn(Opcodes.RETURN);

    visitor.visitLabel(startCatchLabel);

    visitor.visitVarInsn(Opcodes.ASTORE, 3);
    visitor.visitTypeInsn(Opcodes.NEW, "com/nginious/http/xsp/XspException");
    visitor.visitInsn(Opcodes.DUP);
    visitor.visitLdcInsn("Attribute set contains an invalid collection for tag " + getName() + " at "
            + getLocationDescriptor());
    visitor.visitVarInsn(Opcodes.ALOAD, 3);
    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/nginious/http/xsp/XspException", "<init>",
            "(Ljava/lang/String;Ljava/lang/Throwable;)V");
    visitor.visitInsn(Opcodes.ATHROW);

    visitor.visitMaxs(11, 11);
    visitor.visitEnd();
}