List of usage examples for org.objectweb.asm MethodVisitor visitTryCatchBlock
public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type)
From source file:org.jboss.byteman.agent.JigsawAccessEnablerGenerator.java
License:Open Source License
private static byte[] getJigsawAccessibleFieldSetterClassBytes() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); FieldVisitor fv;//w ww .j a v a 2 s.co m MethodVisitor mv; cw.visit(V9, ACC_PUBLIC + ACC_SUPER, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", null, "java/lang/Object", new String[] { "org/jboss/byteman/agent/AccessibleFieldSetter" }); cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC + ACC_FINAL + ACC_STATIC); { fv = cw.visitField(ACC_PRIVATE, "handle", "Ljava/lang/invoke/MethodHandle;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "isStatic", "Z", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE, "field", "Ljava/lang/reflect/Field;", null, null); fv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/reflect/Field;)V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getModifiers", "()I", false); mv.visitMethodInsn(INVOKESTATIC, "java/lang/reflect/Modifier", "isStatic", "(I)Z", false); mv.visitFieldInsn(PUTFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "isStatic", "Z"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "isStatic", "Z"); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getDeclaringClass", "()Ljava/lang/Class;", false); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getType", "()Ljava/lang/Class;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStaticSetter", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", false); mv.visitFieldInsn(PUTFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "handle", "Ljava/lang/invoke/MethodHandle;"); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getDeclaringClass", "()Ljava/lang/Class;", false); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Field", "getType", "()Ljava/lang/Class;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findSetter", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", false); mv.visitFieldInsn(PUTFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "handle", "Ljava/lang/invoke/MethodHandle;"); mv.visitLabel(l1); Label l4 = new Label(); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l2); mv.visitVarInsn(ASTORE, 3); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitLdcInsn("JigsawAccessibleFieldSetter : exception creating etter method handle for field "); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l4); mv.visitInsn(RETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "isStatic", "Z"); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitVarInsn(ALOAD, 1); Label l4 = new Label(); mv.visitJumpInsn(IFNULL, l4); mv.visitTypeInsn(NEW, "org/jboss/byteman/rule/exception/ExecuteException"); mv.visitInsn(DUP); mv.visitLdcInsn("JigsawAccessibleFieldSetter.set : expecting null owner for static set!"); mv.visitMethodInsn(INVOKESPECIAL, "org/jboss/byteman/rule/exception/ExecuteException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "handle", "Ljava/lang/invoke/MethodHandle;"); mv.visitInsn(ICONST_1); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;", false); mv.visitInsn(POP); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/jboss/byteman/jigsaw/JigsawAccessibleFieldSetter", "handle", "Ljava/lang/invoke/MethodHandle;"); mv.visitInsn(ICONST_2); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;", false); mv.visitInsn(POP); mv.visitLabel(l1); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l2); mv.visitVarInsn(ASTORE, 3); mv.visitTypeInsn(NEW, "org/jboss/byteman/rule/exception/ExecuteException"); mv.visitInsn(DUP); mv.visitLdcInsn("JigsawAccessibleFieldSetter.set : exception invoking setter methodhandle "); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "org/jboss/byteman/rule/exception/ExecuteException", "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l5); mv.visitInsn(RETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:org.lwjglx.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 v a 2s. c o 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(ASM7) { 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(ASM7) { boolean mark, catches, notransform, nostackparam, forcestack; public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) notransform = true; else if ("Lorg/lwjglx/autostack/NoStackParam;".equals(desc)) nostackparam = true; else if ("Lorg/lwjglx/autostack/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.startsWith("nstackMalloc") || name.startsWith("nstackCalloc") || 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(ASM7, 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 ("Lorg/lwjglx/autostack/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 ("Lorg/lwjglx/autostack/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 ("Lorg/lwjglx/autostack/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(ASM7, 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 ("Lorg/lwjglx/autostack/UseCallerStack;".equals(desc)) { if (!notransform) { if (debugTransform) System.out.println("[autostack] method declares to use caller stack"); newStack = false; } return null; } else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc)) { if (!notransform) { if (debugTransform) System.out.println("[autostack] method declares to use new stack"); newStack = true; } return null; } else if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) { return null; } else if ("Lorg/lwjglx/autostack/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(name, 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.startsWith("nstackMalloc") || name.startsWith("nstackCalloc"))) { String newName = "n" + name.substring(6, 7).toLowerCase() + name.substring(7); 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 ("(I)J".equals(desc)) { mv.visitInsn(SWAP); } else { // (II)J mv.visitInsn(DUP_X2); mv.visitInsn(POP); } 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:org.mbte.groovypp.compiler.asm.VisitTryCatchBlock.java
License:Apache License
public void visit(MethodVisitor mv) { mv.visitTryCatchBlock(start, end, handler, type); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Generate the exception table entry(/entries) for a try/catch block. * This can be done in any order, any time after all labels passed as arguments have been visited. * //from w ww . j a v a 2 s.c om * Jump and return instructions are excluded from any exception handling blocks if they cause the next executed instruction * to escape the bounds of the try statement. * * eg. if there is a return statement in a try block in a try-catch statement, the corresponding return instruction will * be excluded from the exception table entry. * if there is a jump (eg. goto) statement in a try block of a try-catch statement, the jump instruction will be * excluded from the exception table entry if the jump destination lies outside the try statement. * * Exclusion of the instruction will cause the exception table entry to be split or reduced: * one entry will include the part before the excluded instruction, * the other will include the part after it, if it is not the instruction at the end of the block. * * * An interesting case to consider is a try/catch nested with respect to a while(true) statement, with a continue statement in the body: * * try { * while (true) { * (statements) * continue; * (more statements) * } * } catch (Exception e) { * } * * versus * * while (true) { * try { * (statements) * continue; * (more statements) * } catch (Exception e) { * } * } * * In both cases, the continue is encoded as a goto instruction whose destination is the first instruction in (statements). * In the first case, the target "while" statement is nested within the try block, therefore the goto is not excluded. * In the second case, the target "while" statement is outside of the try block, therefore the goto is excluded. * ie. even though the instructions for the try body are the same, and the instructions for (statements) lies both within * the while block and the try block, a jump to the first statement may or may not be viewed as escaping the try block, * depending on which case was compiled. * * * @param tryStartLabel * @param tryEndLabel * @param catchLabel * @param exceptionType * @param tryBlockContext */ private static void encodeTryCatchBlock(Label tryStartLabel, Label tryEndLabel, Label catchLabel, JavaTypeName exceptionType, GenerationContext tryBlockContext) { MethodVisitor mv = tryBlockContext.getMethodVisitor(); // The start label for the next table entry to be visited. Label exceptionEntryStartLabel = tryStartLabel; for (final JumpReturnLabelInfo jumpReturnLabelInfo : tryBlockContext.getJumpReturnLabelInfoList()) { // Only exclude the jump/return instruction (ie. split the exception block) // if the destination label is outside the scope of the try block Label destinationLabel = jumpReturnLabelInfo.getDestinationLabel(); if (destinationLabel != null && tryBlockContext.containsStatementJumpLabel(destinationLabel)) { continue; } // The next entry goes from the start label (inclusive) to the return or continue label (exclusive). Label returnContinueLabel = jumpReturnLabelInfo.getInstructionLabel(); if (exceptionEntryStartLabel.getOffset() != returnContinueLabel.getOffset()) { // When there are consecutive instructions which jump/return outside the scope of the try block, // after the first iteration of the loop we will have the exception entry start label and the // return continue label both pointing to the same offset (ie. the offset of the nth consecutive // jump/return instruction on iteration n). mv.visitTryCatchBlock(exceptionEntryStartLabel, returnContinueLabel, catchLabel, exceptionType.getJVMInternalName()); } // Set the start label for the next table entry to be visited. exceptionEntryStartLabel = jumpReturnLabelInfo.getAfterInstructionLabel(); // afterReturnLabel } // Check for the case where the last return instruction comes at the end of the try block. if (exceptionEntryStartLabel.getOffset() != tryEndLabel.getOffset()) { // Add the final entry, which ends at the tryEndLabel. mv.visitTryCatchBlock(exceptionEntryStartLabel, tryEndLabel, catchLabel, exceptionType.getJVMInternalName()); } }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Encode a method invocation that is wrapped in a synchronized block. * See Sun bug id #4414101 for a discussion of this generated code. * /*from w w w .ja v a2s. com*/ * @param smi - the SynchronizedMethodInvocation object. * @param context - the context of the code generation. * @return - true if the SynchronizedMethodInvocation is terminating. * @throws JavaGenerationException */ private static boolean encodeSynchronizedMethodInvocation(JavaStatement.SynchronizedMethodInvocation smi, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); // Get the JavaExpression for the object to synchronize on and generate the bytecode. JavaExpression objectToSynchOn = smi.getSynchronizingObject(); encodeExpr(objectToSynchOn, context); // The object to synchronize on is now on the stack. Duplicate it, // move one to storage as a local variable, and to MONITORENTER on the other. mv.visitInsn(Opcodes.DUP); int mutexIndex = context.addLocalVar("$mutex", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, mutexIndex); mv.visitInsn(Opcodes.MONITORENTER); // We need to wrap the method invocation in a try/catch block so // the monitor can be exited properly if the method invocation throws // an exception. Label tryCatchStart = new Label(); mv.visitLabel(tryCatchStart); // Note: if this is generalized to handle any synchronized statement (for example, a synchronized block), // then the scope of entries in the exception table here will have to be modified to exclude return instructions. // See encodeTryCatchStatement() for how to do this. // Here, the only statement in the try block is a single expressionStatement, which has no return instructions, // so we don't have to worry about handling this case. // Get the method invocation and generate the corresponding bytecode. MethodInvocation methodInvocation = smi.getMethodInvocation(); encodeExpr(methodInvocation, context); // Load the mutex object back onto the stack and do MonitorExit. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the try block around the method invocation. Label tryEnd = new Label(); mv.visitLabel(tryEnd); // At this point we want to code an instruction to jump past the exception handling // code. Label tryCatchEnd = new Label(); mv.visitJumpInsn(Opcodes.GOTO, tryCatchEnd); // Label the start of the exception handling code. Label catchStart = new Label(); mv.visitLabel(catchStart); // The exception is on the stack. Store it as a local. int exceptionIndex = context.addLocalVar("exception", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex); // Retrieve the mutex object and do MONITOREXIT. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the exception handling code that deals with the monitor. Label exceptionMonitorExitEnd = new Label(); mv.visitLabel(exceptionMonitorExitEnd); // Retrieve the exception and throw it. mv.visitVarInsn(Opcodes.ALOAD, exceptionIndex); mv.visitInsn(Opcodes.ATHROW); // Vist the label to mark the end of the try/catch. mv.visitLabel(tryCatchEnd); // Set up the try/catch block to catch exceptions thrown by the method invocation // and handle exiting the monitor. mv.visitTryCatchBlock(tryCatchStart, tryEnd, catchStart, null); // Set up a try catch block so that if an exception is thrown by trying to exit // the monitor in the case of an exception from the method invocation we will keep trying to // exit the monitor. mv.visitTryCatchBlock(catchStart, exceptionMonitorExitEnd, catchStart, null); return false; }
From source file:org.qi4j.runtime.composite.FragmentClassLoader.java
License:Open Source License
public static byte[] generateClass(String name, Class baseClass) throws ClassNotFoundException { String classSlash = name.replace('.', '/'); String baseClassSlash = getInternalName(baseClass); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); // Class definition start cw.visit(jdkVersion, ACC_PUBLIC + ACC_SUPER, classSlash, null, baseClassSlash, null); // Composite reference {/*from w ww. j a va 2 s. co m*/ cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;", null, null) .visitEnd(); } // Static Method references boolean hasProxyMethods = false; { int idx = 1; for (Method method : baseClass.getMethods()) { if (isOverridden(method, baseClass)) { cw.visitField(ACC_PRIVATE + ACC_STATIC, "m" + idx++, "Ljava/lang/reflect/Method;", null, null) .visitEnd(); hasProxyMethods = true; } } } // Constructors for (Constructor constructor : baseClass.getDeclaredConstructors()) { if (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor.getModifiers())) { String desc = org.objectweb.asm.commons.Method.getMethod(constructor).getDescriptor(); MethodVisitor cmv = cw.visitMethod(ACC_PUBLIC, "<init>", desc, null, null); cmv.visitCode(); cmv.visitVarInsn(ALOAD, 0); int idx = 1; for (Class aClass : constructor.getParameterTypes()) { final int opcode; if (aClass.equals(Integer.TYPE)) { opcode = ILOAD; } else if (aClass.equals(Long.TYPE)) { opcode = LLOAD; } else if (aClass.equals(Float.TYPE)) { opcode = FLOAD; } else if (aClass.equals(Double.TYPE)) { opcode = DLOAD; } else { opcode = ALOAD; } cmv.visitVarInsn(opcode, idx++); } cmv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, "<init>", desc); cmv.visitInsn(RETURN); cmv.visitMaxs(idx, idx); cmv.visitEnd(); } } // Overloaded and unimplemented methods if (hasProxyMethods) { Method[] methods = baseClass.getMethods(); int idx = 0; List<Label> exceptionLabels = new ArrayList<Label>(); for (Method method : methods) { if (isOverridden(method, baseClass)) { idx++; String methodName = method.getName(); String desc = org.objectweb.asm.commons.Method.getMethod(method).getDescriptor(); String[] exceptions = null; { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, desc, null, exceptions); if (isInternalQi4jMethod(method, baseClass)) { // generate a NoOp method... mv.visitInsn(RETURN); } else { Label endLabel = null; // Use this if return type is void if (method.getExceptionTypes().length > 0) { exceptions = new String[method.getExceptionTypes().length]; for (int i = 0; i < method.getExceptionTypes().length; i++) { Class<?> aClass = method.getExceptionTypes()[i]; exceptions[i] = getInternalName(aClass); } } mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); exceptionLabels.clear(); for (Class<?> declaredException : method.getExceptionTypes()) { Label ld = new Label(); mv.visitTryCatchBlock(l0, l1, ld, getInternalName(declaredException)); exceptionLabels.add(ld); // Reuse this further down for the catch } Label lruntime = new Label(); mv.visitTryCatchBlock(l0, l1, lruntime, "java/lang/RuntimeException"); Label lerror = new Label(); mv.visitTryCatchBlock(l0, l1, lerror, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classSlash, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, classSlash, "m" + idx, "Ljava/lang/reflect/Method;"); int paramCount = method.getParameterTypes().length; int stackIdx = 0; if (paramCount == 0) { // Send in null as parameter mv.visitInsn(ACONST_NULL); } else { insn(mv, paramCount); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int pidx = 0; for (Class<?> aClass : method.getParameterTypes()) { mv.visitInsn(DUP); insn(mv, pidx++); stackIdx = wrapParameter(mv, aClass, stackIdx + 1); mv.visitInsn(AASTORE); } } // Call method mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/api/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); // Return value if (!method.getReturnType().equals(Void.TYPE)) { unwrapResult(mv, method.getReturnType(), l1); } else { mv.visitInsn(POP); mv.visitLabel(l1); endLabel = new Label(); mv.visitJumpInsn(GOTO, endLabel); } // Increase stack to beyond method args stackIdx++; // Declared exceptions int exceptionIdx = 0; for (Class<?> aClass : method.getExceptionTypes()) { mv.visitLabel(exceptionLabels.get(exceptionIdx++)); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { getInternalName(aClass) }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitInsn(ATHROW); } // RuntimeException and Error catch-all mv.visitLabel(lruntime); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/RuntimeException" }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitInsn(ATHROW); mv.visitLabel(lerror); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitTypeInsn(CHECKCAST, "java/lang/Error"); mv.visitInsn(ATHROW); // Return type = void if (endLabel != null) { mv.visitLabel(endLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); } mv.visitMaxs(0, 0); mv.visitEnd(); } } if (!Modifier.isAbstract(method.getModifiers())) { // Add method with _ as prefix MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "_" + method.getName(), desc, null, exceptions); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // Parameters int stackIdx = 1; for (Class<?> aClass : method.getParameterTypes()) { stackIdx = loadParameter(mv, aClass, stackIdx) + 1; } // Call method mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, method.getName(), desc); // Return value if (!method.getReturnType().equals(Void.TYPE)) { returnResult(mv, method.getReturnType()); } else { mv.visitInsn(RETURN); } mv.visitMaxs(1, 1); mv.visitEnd(); } } } // Class initializer { MethodVisitor mv; mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException"); mv.visitLabel(l0); // Lookup methods and store in static variables int midx = 0; for (Method method : methods) { if (isOverridden(method, baseClass)) { method.setAccessible(true); Class methodClass; if (Modifier.isAbstract(method.getModifiers())) { methodClass = method.getDeclaringClass(); } else { try { methodClass = getInterfaceMethodDeclaration(method, baseClass); // Overridden method lookup } catch (NoSuchMethodException e) { throw new ClassNotFoundException(name, e); } } midx++; mv.visitLdcInsn(Type.getType(methodClass)); mv.visitLdcInsn(method.getName()); insn(mv, method.getParameterTypes().length); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); int pidx = 0; for (Class<?> aClass : method.getParameterTypes()) { mv.visitInsn(DUP); insn(mv, pidx++); type(mv, aClass); mv.visitInsn(AASTORE); } mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, classSlash, "m" + midx, "Ljava/lang/reflect/Method;"); } } mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/NoSuchMethodException" }); mv.visitVarInsn(ASTORE, 0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V"); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); mv.visitMaxs(6, 1); mv.visitEnd(); } } cw.visitEnd(); return cw.toByteArray(); }
From source file:org.qi4j.runtime.composite.TransientClassLoader.java
License:Open Source License
public static byte[] generateClass(String name, Class baseClass) throws ClassNotFoundException { String classSlash = name.replace('.', '/'); String baseClassSlash = getInternalName(baseClass); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv;/*from w ww . j a va 2s. c o m*/ MethodVisitor mv; AnnotationVisitor av0; // Class definition start cw.visit(jdkVersion, ACC_PUBLIC + ACC_SUPER, classSlash, null, baseClassSlash, null); // Composite reference { fv = cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;", null, null); fv.visitEnd(); } // Static Method references { int idx = 1; for (Method method : baseClass.getMethods()) { if (isOverloaded(method, baseClass)) { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m" + idx++, "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } } } // Constructors for (Constructor constructor : baseClass.getDeclaredConstructors()) { if (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor.getModifiers())) { String desc = org.objectweb.asm.commons.Method.getMethod(constructor).getDescriptor(); mv = cw.visitMethod(ACC_PUBLIC, "<init>", desc, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); int idx = 1; for (Class aClass : constructor.getParameterTypes()) { // TODO Handle other types than objects (?) mv.visitVarInsn(ALOAD, idx++); } mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, "<init>", desc); mv.visitInsn(RETURN); mv.visitMaxs(idx, idx); mv.visitEnd(); } } // Overloaded and unimplemented methods Method[] methods = baseClass.getMethods(); int idx = 0; List<Label> exceptionLabels = new ArrayList<Label>(); for (Method method : methods) { if (isOverloaded(method, baseClass)) { idx++; String methodName = method.getName(); String desc = org.objectweb.asm.commons.Method.getMethod(method).getDescriptor(); String[] exceptions = null; { mv = cw.visitMethod(ACC_PUBLIC, methodName, desc, null, exceptions); if (isInternalQi4jMethod(method, baseClass)) { // generate a NoOp method... mv.visitInsn(RETURN); } else { Label endLabel = null; // Use this if return type is void if (method.getExceptionTypes().length > 0) { exceptions = new String[method.getExceptionTypes().length]; for (int i = 0; i < method.getExceptionTypes().length; i++) { Class<?> aClass = method.getExceptionTypes()[i]; exceptions[i] = getInternalName(aClass); } } mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); exceptionLabels.clear(); for (Class<?> declaredException : method.getExceptionTypes()) { Label ld = new Label(); mv.visitTryCatchBlock(l0, l1, ld, getInternalName(declaredException)); exceptionLabels.add(ld); // Reuse this further down for the catch } Label lruntime = new Label(); mv.visitTryCatchBlock(l0, l1, lruntime, "java/lang/RuntimeException"); Label lerror = new Label(); mv.visitTryCatchBlock(l0, l1, lerror, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classSlash, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, classSlash, "m" + idx, "Ljava/lang/reflect/Method;"); int paramCount = method.getParameterTypes().length; int stackIdx = 0; if (paramCount == 0) { // Send in null as parameter mv.visitInsn(ACONST_NULL); } else { insn(mv, paramCount); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int pidx = 0; for (Class<?> aClass : method.getParameterTypes()) { mv.visitInsn(DUP); insn(mv, pidx++); stackIdx = wrapParameter(mv, aClass, stackIdx + 1); mv.visitInsn(AASTORE); } } // Call method mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/api/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); // Return value if (!method.getReturnType().equals(Void.TYPE)) { unwrapResult(mv, method.getReturnType(), l1); } else { mv.visitInsn(POP); mv.visitLabel(l1); endLabel = new Label(); mv.visitJumpInsn(GOTO, endLabel); } // Increase stack to beyond method args stackIdx++; // Declared exceptions int exceptionIdx = 0; for (Class<?> aClass : method.getExceptionTypes()) { mv.visitLabel(exceptionLabels.get(exceptionIdx++)); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { getInternalName(aClass) }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitInsn(ATHROW); } // RuntimeException and Error catch-all mv.visitLabel(lruntime); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/RuntimeException" }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitInsn(ATHROW); mv.visitLabel(lerror); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, stackIdx); mv.visitVarInsn(ALOAD, stackIdx); mv.visitTypeInsn(CHECKCAST, "java/lang/Error"); mv.visitInsn(ATHROW); // Return type = void if (endLabel != null) { mv.visitLabel(endLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); } mv.visitMaxs(0, 0); mv.visitEnd(); } } if (!Modifier.isAbstract(method.getModifiers())) { // Add method with _ as prefix mv = cw.visitMethod(ACC_PUBLIC, "_" + method.getName(), desc, null, exceptions); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); // Parameters int stackIdx = 1; for (Class<?> aClass : method.getParameterTypes()) { stackIdx = loadParameter(mv, aClass, stackIdx) + 1; } // Call method mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, method.getName(), desc); // Return value if (!method.getReturnType().equals(Void.TYPE)) { returnResult(mv, method.getReturnType()); } else { mv.visitInsn(RETURN); } mv.visitMaxs(1, 1); mv.visitEnd(); } } } // Class initializer { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException"); mv.visitLabel(l0); // Lookup methods and store in static variables int midx = 0; for (Method method : methods) { if (isOverloaded(method, baseClass)) { method.setAccessible(true); Class methodClass; methodClass = method.getDeclaringClass(); midx++; mv.visitLdcInsn(Type.getType(methodClass)); mv.visitLdcInsn(method.getName()); insn(mv, method.getParameterTypes().length); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); int pidx = 0; for (Class<?> aClass : method.getParameterTypes()) { mv.visitInsn(DUP); insn(mv, pidx++); type(mv, aClass); mv.visitInsn(AASTORE); } mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, classSlash, "m" + midx, "Ljava/lang/reflect/Method;"); } } mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/NoSuchMethodException" }); mv.visitVarInsn(ASTORE, 0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V"); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); mv.visitMaxs(6, 1); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:org.qi4j.test.ASMTest.java
License:Open Source License
public static byte[] generateClass() { ClassWriter cw = new ClassWriter(0); FieldVisitor fv;//from w w w .ja v a2 s . c o m MethodVisitor mv; AnnotationVisitor av0; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "org/qi4j/satisfiedBy/SomeMixin_Stub", null, "org/qi4j/satisfiedBy/SomeMixin", null); { fv = cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m1", "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m2", "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m3", "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m4", "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m5", "Ljava/lang/reflect/Method;", null, null); fv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "org/qi4j/satisfiedBy/SomeMixin", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "org/qi4j/satisfiedBy/SomeMixin", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "other", "()Ljava/lang/String;", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m1", "Ljava/lang/reflect/Method;"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitLabel(l1); mv.visitInsn(ARETURN); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "foo", "(Ljava/lang/String;I)Ljava/lang/String;", null, new String[] { "java/lang/IllegalArgumentException" }); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IllegalArgumentException"); Label l3 = new Label(); mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m2", "Ljava/lang/reflect/Method;"); mv.visitInsn(ICONST_2); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitLabel(l1); mv.visitInsn(ARETURN); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/IllegalArgumentException" }); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ATHROW); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 3); mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(6, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "bar", "(DZFCIJSBLjava/lang/Double;[Ljava/lang/Object;[I)V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m3", "Ljava/lang/reflect/Method;"); mv.visitIntInsn(BIPUSH, 11); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(DLOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_2); mv.visitVarInsn(FLOAD, 4); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_3); mv.visitVarInsn(ILOAD, 5); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_4); mv.visitVarInsn(ILOAD, 6); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_5); mv.visitVarInsn(LLOAD, 7); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 6); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 7); mv.visitVarInsn(ILOAD, 10); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 8); mv.visitVarInsn(ALOAD, 11); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 9); mv.visitVarInsn(ALOAD, 12); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 10); mv.visitVarInsn(ALOAD, 13); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 14); mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 14); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); mv.visitMaxs(7, 15); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "multiEx", "(Ljava/lang/String;)V", null, new String[] { "org/qi4j/satisfiedBy/Exception1", "org/qi4j/satisfiedBy/Exception2" }); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "org/qi4j/satisfiedBy/Exception1"); Label l3 = new Label(); mv.visitTryCatchBlock(l0, l1, l3, "org/qi4j/satisfiedBy/Exception2"); Label l4 = new Label(); mv.visitTryCatchBlock(l0, l1, l4, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m4", "Ljava/lang/reflect/Method;"); mv.visitInsn(ICONST_1); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitLabel(l1); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "org/qi4j/satisfiedBy/Exception1" }); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ATHROW); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "org/qi4j/satisfiedBy/Exception2" }); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ATHROW); mv.visitLabel(l4); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 2); mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l5); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); mv.visitMaxs(6, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "unwrapResult", "()I", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;"); mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m5", "Ljava/lang/reflect/Method;"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); mv.visitLabel(l1); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException"); mv.visitLabel(l0); mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;")); mv.visitLdcInsn("other"); mv.visitInsn(ICONST_0); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m1", "Ljava/lang/reflect/Method;"); mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;")); mv.visitLdcInsn("foo"); mv.visitInsn(ICONST_2); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitLdcInsn(Type.getType("Ljava/lang/String;")); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m2", "Ljava/lang/reflect/Method;"); mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;")); mv.visitLdcInsn("bar"); mv.visitIntInsn(BIPUSH, 11); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_2); mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_3); mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_4); mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_5); mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 6); mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 7); mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 8); mv.visitLdcInsn(Type.getType("Ljava/lang/Double;")); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 9); mv.visitLdcInsn(Type.getType("[Ljava/lang/Object;")); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, 10); mv.visitLdcInsn(Type.getType("[I")); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m3", "Ljava/lang/reflect/Method;"); mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;")); mv.visitLdcInsn("multiEx"); mv.visitInsn(ICONST_1); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitLdcInsn(Type.getType("Ljava/lang/String;")); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m4", "Ljava/lang/reflect/Method;"); mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;")); mv.visitLdcInsn("unwrapResult"); mv.visitInsn(ICONST_0); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m5", "Ljava/lang/reflect/Method;"); mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/NoSuchMethodException" }); mv.visitVarInsn(ASTORE, 0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V"); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); mv.visitMaxs(6, 1); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:org.simantics.databoard.tests.testASM.java
License:Open Source License
void createImpl(String className, Class<?> interfaze, ClassWriter cw) { FieldVisitor fv;//from w ww.j av a2 s . c om MethodVisitor mv; AnnotationVisitor av0; java.lang.reflect.Method[] methods = interfaze.getMethods(); Arrays.sort(methods, MethodInterfaceUtil.methodComparator); String classResourceName = className.replaceAll("\\.", "/"); String classTypeDescriptor = "L" + classResourceName + ";"; String interfaceResourceName = classResourceName.substring(0, classResourceName.length() - 5); String interfaceTypeDescriptor = "L" + interfaceResourceName + ";"; cw.visit(V1_6, ACC_SUPER | ACC_PUBLIC, classResourceName, null, "java/lang/Object", new String[] { interfaceResourceName }); // Imports Set<Class<?>> imports = new HashSet<Class<?>>(); imports.add(AsyncResult.class); imports.add(ExecutionError.class); imports.add(Method.class); imports.add(interfaze); for (java.lang.reflect.Method m : methods) { for (Class<?> clazz : m.getExceptionTypes()) { imports.add(clazz); } for (Class<?> clazz : m.getParameterTypes()) { imports.add(clazz); } imports.add(m.getReturnType()); } for (Class<?> clazz : imports) { if (clazz.isPrimitive()) continue; String name = clazz.getName(); if (name.startsWith("java.lang")) continue; String resourceName = name.replaceAll("\\.", "/"); String outerName = resourceName.contains("$") ? resourceName.substring(0, resourceName.indexOf('$')) : null; String className_ = clazz.isArray() ? clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 2) : clazz.getSimpleName(); int access = ACC_PUBLIC + ACC_STATIC + (clazz.isInterface() ? ACC_INTERFACE + ACC_ABSTRACT : 0); // System.out.printf("name=%s, outerName=%s, innerName=%s\n", resourceName, outerName, className_); cw.visitInnerClass(resourceName, outerName, className_, access); } // Fields { fv = cw.visitField(ACC_FINAL + ACC_STATIC, "interfaze", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", null); fv.visitEnd(); } { fv = cw.visitField(ACC_FINAL + ACC_STATIC, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "mi", "Lorg/simantics/data/session/MethodInterface;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;", null, null); fv.visitEnd(); } // Init class - static {} { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLdcInsn(Type.getType(interfaceTypeDescriptor)); mv.visitFieldInsn(PUTSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitFieldInsn(GETSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;"); mv.visitVarInsn(ASTORE, 0); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETSTATIC, "org/simantics/data/network/MethodInterfaceUtil", "methodComparator", "Ljava/util/Comparator;"); mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "sort", "([Ljava/lang/Object;Ljava/util/Comparator;)V"); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARRAYLENGTH); mv.visitTypeInsn(ANEWARRAY, "org/simantics/databoard/method/MethodBinding"); mv.visitFieldInsn(PUTSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); Label l4 = new Label(); mv.visitLabel(l4); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 1); Label l5 = new Label(); mv.visitLabel(l5); Label l6 = new Label(); mv.visitJumpInsn(GOTO, l6); Label l7 = new Label(); mv.visitLabel(l7); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/reflect/Method;", Opcodes.INTEGER }, 0, null); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(AALOAD); mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/DataTypes", "getMethodBinding", "(Ljava/lang/reflect/Method;)Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(AASTORE); Label l8 = new Label(); mv.visitLabel(l8); mv.visitIincInsn(1, 1); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 1); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l7); Label l9 = new Label(); mv.visitLabel(l9); mv.visitInsn(RETURN); Label l10 = new Label(); mv.visitLabel(l10); mv.visitLocalVariable("methods", "[Ljava/lang/reflect/Method;", null, l2, l10, 0); mv.visitLocalVariable("i", "I", null, l5, l9, 1); mv.visitMaxs(4, 2); mv.visitEnd(); } // Constructor { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/data/session/MethodInterface;)V", null, new String[] { "org/simantics/data/error/MethodNotSupportedException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, classResourceName, "mi", "Lorg/simantics/data/session/MethodInterface;"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitTypeInsn(ANEWARRAY, "org/simantics/data/session/MethodInterface$Method"); mv.visitFieldInsn(PUTFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); Label l3 = new Label(); mv.visitLabel(l3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l4 = new Label(); mv.visitLabel(l4); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); Label l6 = new Label(); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_FULL, 3, new Object[] { classResourceName, "org/simantics/data/session/MethodInterface", Opcodes.INTEGER }, 0, new Object[] {}); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface", "getMethod", "(Lorg/simantics/databoard/method/MethodBinding;)Lorg/simantics/data/session/MethodInterface$Method;"); mv.visitInsn(AASTORE); Label l7 = new Label(); mv.visitLabel(l7); mv.visitIincInsn(2, 1); mv.visitLabel(l5); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 2); mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings", "[Lorg/simantics/databoard/method/MethodBinding;"); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l6); Label l8 = new Label(); mv.visitLabel(l8); mv.visitInsn(RETURN); Label l9 = new Label(); mv.visitLabel(l9); mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l9, 0); mv.visitLocalVariable("mi", "Lorg/simantics/data/session/MethodInterface;", null, l0, l9, 1); mv.visitLocalVariable("i", "I", null, l4, l8, 2); mv.visitMaxs(5, 3); mv.visitEnd(); } // Method int methodNumber = 0; for (java.lang.reflect.Method m : methods) { String typeDescription = ""; Class<?>[] params = m.getParameterTypes(); for (int i = 0; i < params.length; i++) { if (i > 0) typeDescription += ";"; typeDescription += classToTypeDescriptor(params[i]); } typeDescription = "(" + typeDescription + ")" + classToTypeDescriptor(m.getReturnType()); System.out.println(typeDescription + " " + m.getName()); Class<?>[] exceptions = m.getExceptionTypes(); String[] exceptionResourceNames = new String[exceptions.length]; for (int i = 0; i < exceptionResourceNames.length; i++) { exceptionResourceNames[i] = exceptions[i].getName().replaceAll("\\.", "/"); } // Registers // 0 - this // 1..argRegs args // argRegs+1 - method // argRegs+2 - args (the array) // argRegs+3 - AsyncResult // argRegs+4 - e // argRegs+5 - ExecutionError.cause // argRegs+6 - e int argRegs = 0; for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; argRegs++; if (clazz == long.class || clazz == float.class || clazz == Double.class) argRegs++; } mv = cw.visitMethod(ACC_PUBLIC, m.getName(), typeDescription, null, exceptionResourceNames); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "org/simantics/data/session/MethodInterface$ExecutionError"); Label l3 = new Label(); mv.visitTryCatchBlock(l0, l1, l3, "java/lang/InterruptedException"); Label l4 = new Label(); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classResourceName, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;"); // Method m and puts into register mv.visitLdcInsn(Integer.valueOf(methodNumber)); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, argRegs + 1); Label l5 = new Label(); mv.visitLabel(l5); mv.visitLdcInsn(Integer.valueOf(params.length)); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int register = 1; // argument register for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; mv.visitInsn(DUP); mv.visitLdcInsn(Integer.valueOf(i)); if (clazz == byte.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); } else if (clazz == char.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); } else if (clazz == boolean.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); } else if (clazz == byte.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); } else if (clazz == int.class) { mv.visitVarInsn(ILOAD, register++); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (clazz == long.class) { mv.visitVarInsn(LLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(F)Ljava/lang/Long;"); } else if (clazz == float.class) { mv.visitVarInsn(FLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); } else if (clazz == Double.class) { mv.visitVarInsn(DLOAD, register); register += 2; mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); } else { // Push argument to stack mv.visitVarInsn(ALOAD, register++); } mv.visitInsn(AASTORE); } // Store args to argRegs+2 mv.visitVarInsn(ASTORE, argRegs + 2); Label l6 = new Label(); mv.visitLabel(l6); mv.visitVarInsn(ALOAD, argRegs + 1 /* m */); mv.visitVarInsn(ALOAD, argRegs + 2 /*args*/); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$Method", "invoke", "(Ljava/lang/Object;)Lorg/simantics/data/session/MethodInterface$AsyncResult;"); mv.visitVarInsn(ASTORE, argRegs + 3); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, argRegs + 3); mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$AsyncResult", "waitForResponse", "()Ljava/lang/Object;"); // TODO Return typecase result Class<?> returnType = m.getReturnType(); if (returnType == void.class) { mv.visitInsn(POP); mv.visitInsn(RETURN); } else if (returnType == int.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == byte.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "B()"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == char.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == boolean.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == short.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); mv.visitLabel(l1); mv.visitInsn(IRETURN); } else if (returnType == long.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); mv.visitLabel(l1); mv.visitInsn(LRETURN); } else if (returnType == double.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); mv.visitLabel(l1); mv.visitInsn(DRETURN); } else if (returnType == float.class) { mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); mv.visitLabel(l1); mv.visitInsn(FRETURN); } else { // Object mv.visitTypeInsn(CHECKCAST, returnType.getName().replaceAll("\\.", "/")); mv.visitLabel(l1); mv.visitInsn(ARETURN); } // Handle exceptions mv.visitLabel(l2); mv.visitFrame(Opcodes.F_FULL, argRegs + 4, new Object[] { classResourceName, "java/lang/Integer", "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;", "org/simantics/data/session/MethodInterface$AsyncResult" }, 1, new Object[] { "org/simantics/data/session/MethodInterface$ExecutionError" }); mv.visitVarInsn(ASTORE, argRegs + 4); Label l7 = new Label(); mv.visitLabel(l7); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/data/session/MethodInterface$ExecutionError", "getError", "()Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, argRegs + 5); // argRegs+5 <- ExecutionError.cause Class<?>[] exceptionClasses = m.getExceptionTypes(); Label nextException[] = new Label[exceptionClasses.length]; for (int i = 0; i < exceptionClasses.length; i++) { Class<?> exceptionClass = exceptionClasses[i]; String exceptionClassResourceName = exceptionClass.getName().replaceAll("\\.", "/"); nextException[i] = new Label(); // If instanceof MyException Label l8 = new Label(); mv.visitLabel(l8); mv.visitVarInsn(ALOAD, argRegs + 5); // Cause mv.visitTypeInsn(INSTANCEOF, exceptionClassResourceName); mv.visitJumpInsn(IFEQ, nextException[i]); // If not, go to ExecutionError // If so, throw it mv.visitVarInsn(ALOAD, argRegs + 5); // e mv.visitTypeInsn(CHECKCAST, exceptionClassResourceName); mv.visitInsn(ATHROW); mv.visitLabel(nextException[i]); } // ExecutionError mv.visitFrame( Opcodes.F_APPEND, argRegs + 1, new Object[] { "org/simantics/data/session/MethodInterface$ExecutionError", "java/lang/Object" }, 0, null); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); // InteruptedException mv.visitLabel(l3); mv.visitFrame(Opcodes.F_FULL, argRegs + 4, new Object[] { classResourceName, "java/lang/Integer", "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;", "org/simantics/data/session/MethodInterface$AsyncResult" }, 1, new Object[] { "java/lang/InterruptedException" }); mv.visitVarInsn(ASTORE, argRegs + 4); Label l10 = new Label(); mv.visitLabel(l10); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, argRegs + 4); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); Label l11 = new Label(); mv.visitLabel(l11); mv.visitLocalVariable("this", classTypeDescriptor, null, l4, l11, 0); // mv.visitLocalVariable("arg1", "Ljava/lang/Integer;", null, l4, l11, 1); register = 1; for (int i = 0; i < params.length; i++) { Class<?> clazz = params[i]; mv.visitLocalVariable("arg" + (i + 1), classToTypeDescriptor(clazz), null, l4, l11, register); register++; if (clazz == long.class || clazz == float.class || clazz == Double.class) argRegs++; } mv.visitLocalVariable("m", "Lorg/simantics/data/session/MethodInterface$Method;", null, l5, l11, argRegs + 1); mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l6, l11, argRegs + 2); mv.visitLocalVariable("result", "Lorg/simantics/data/session/MethodInterface$AsyncResult;", null, l0, l11, argRegs + 3); mv.visitLocalVariable("e", "Lorg/simantics/data/session/MethodInterface$ExecutionError;", null, l7, l3, argRegs + 4); mv.visitLocalVariable("cause", "Ljava/lang/Object;", null, l7, l3, argRegs + 5); mv.visitLocalVariable("e", "Ljava/lang/InterruptedException;", null, l10, l11, argRegs + 4); mv.visitMaxs(argRegs + 3, argRegs + 6); mv.visitEnd(); methodNumber++; } cw.visitEnd(); }
From source file:org.sonatype.restsimple.jaxrs.impl.JAXRSServiceDefinitionGenerator.java
License:Open Source License
/** * Generate a JAX RS Resource on the fly, based on the information contained with a {@link ServiceDefinition} * @param serviceDefinition a {@link ServiceDefinition} */// w w w . j a v a2s.c o m @Override public void generate(final ServiceDefinition serviceDefinition, ServiceHandlerMapper mapper) { for (ServiceHandler sh : serviceDefinition.serviceHandlers()) { mapper.addServiceHandler(serviceDefinition.path(), sh); } ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 4); String className = "org/sonatype/restsimple/model/ServiceDescriptionResource" + uuid; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", null); { String path = serviceDefinition.path().contains("/:") ? convert(serviceDefinition.path()) : serviceDefinition.path(); logger.info("Generating jaxrs resource for {} with path {}", serviceDefinition, path); if (path == "") { path = "/"; } av0 = cw.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", path); av0.visitEnd(); } if (serviceDefinition.mediaToProduce().size() > 0) { { av0 = cw.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceDefinition.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } if (serviceDefinition.mediaToConsume().size() > 0) { { av0 = cw.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceDefinition.mediaToConsume()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } cw.visitInnerClass("javax/ws/rs/core/Response$ResponseBuilder", "javax/ws/rs/core/Response", "ResponseBuilder", ACC_PUBLIC + ACC_STATIC + ACC_ABSTRACT); cw.visitInnerClass("javax/ws/rs/core/Response$Status", "javax/ws/rs/core/Response", "Status", ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM); cw.visitInnerClass("org/sonatype/restsimple/api/ServiceDefinition$HttpMethod", "org/sonatype/restsimple/api/ServiceDefinition", "HttpMethod", ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM); { fv = cw.visitField(ACC_PRIVATE, "logger", "Lorg/slf4j/Logger;", null, null); fv.visitEnd(); } { fv = cw.visitField(0, "request", "Ljavax/servlet/http/HttpServletRequest;", null, null); { av0 = fv.visitAnnotation("Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } fv.visitEnd(); } { fv = cw.visitField(0, "mapper", "Lorg/sonatype/restsimple/spi/ServiceHandlerMapper;", null, null); { av0 = fv.visitAnnotation("Lcom/google/inject/Inject;", true); av0.visitEnd(); } fv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(Type.getType("L" + className + ";")); mv.visitMethodInsn(INVOKESTATIC, "org/slf4j/LoggerFactory", "getLogger", "(Ljava/lang/Class;)Lorg/slf4j/Logger;"); mv.visitFieldInsn(PUTFIELD, className, "logger", "Lorg/slf4j/Logger;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } int duplicateCounter = -1; for (ServiceHandler serviceHandler : serviceDefinition.serviceHandlers()) { { String methodName = serviceHandler.getHttpMethod().name().toLowerCase(); if (duplicateCounter++ >= 0) { methodName = methodName + duplicateCounter; } if (serviceHandler.getHttpMethod().name().equalsIgnoreCase("get")) { mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;)Ljava/lang/Object;", null, null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/GET;", true); av0.visitEnd(); } if (serviceHandler.consumeMediaType() != null) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, serviceHandler.consumeMediaType().toMediaType()); av1.visitEnd(); } av0.visitEnd(); } } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("get"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); mv.visitMaxs(6, 3); mv.visitEnd(); continue; } } { if (serviceHandler.getHttpMethod().name().equalsIgnoreCase("head")) { { String methodName = serviceHandler.getHttpMethod().name().toLowerCase(); if (duplicateCounter++ >= 0) { methodName = methodName + "_" + duplicateCounter; } mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;)Ljavax/ws/rs/core/Response;", null, null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/HEAD;", true); av0.visitEnd(); } if (serviceHandler.consumeMediaType() != null) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, serviceHandler.consumeMediaType().toMediaType()); av1.visitEnd(); } av0.visitEnd(); } } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("head"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 2); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "ok", "()Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 3); mv.visitEnd(); continue; } } } { if (serviceHandler.getHttpMethod().name().equalsIgnoreCase("put")) { { String methodName = serviceHandler.getHttpMethod().name().toLowerCase(); if (duplicateCounter++ >= 0) { methodName = methodName + "_" + duplicateCounter; } String methodType = serviceHandler.consumeClass() != null ? serviceHandler.consumeClass().getName().replace(".", "/") : "java/lang/String"; mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;L" + methodType + ";)Ljavax/ws/rs/core/Response;", null, null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/PUT;", true); av0.visitEnd(); } if (serviceHandler.consumeMediaType() != null) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, serviceHandler.consumeMediaType().toMediaType()); av1.visitEnd(); } av0.visitEnd(); } } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/UriBuilder", "fromResource", "(Ljava/lang/Class;)Ljavax/ws/rs/core/UriBuilder;"); mv.visitInsn(ICONST_3); mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitLdcInsn(""); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_1); mv.visitLdcInsn(""); mv.visitInsn(AASTORE); mv.visitInsn(DUP); mv.visitInsn(ICONST_2); mv.visitLdcInsn(""); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/UriBuilder", "build", "([Ljava/lang/Object;)Ljava/net/URI;"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("put"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/UriInfo", "getQueryParameters", "()Ljavax/ws/rs/core/MultivaluedMap;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "created", "(Ljava/net/URI;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "entity", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 5); mv.visitEnd(); continue; } } { if (serviceHandler.getHttpMethod().name().equalsIgnoreCase("post")) { String methodName = serviceHandler.getHttpMethod().name().toLowerCase(); if (duplicateCounter++ >= 0) { methodName = methodName + "_" + duplicateCounter; } List<String> formsParam = PostServiceHandler.class.cast(serviceHandler).formParams(); if (formsParam.size() > 0) { { mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;)Ljavax/ws/rs/core/Response;", "(Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap<Ljava/lang/String;Ljava/lang/String;>;)Ljavax/ws/rs/core/Response;", null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/POST;", true); av0.visitEnd(); } { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, "application/x-www-form-urlencoded"); av1.visitEnd(); } av0.visitEnd(); } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("post"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitFieldInsn(GETSTATIC, "javax/ws/rs/core/Response$Status", "NO_CONTENT", "Ljavax/ws/rs/core/Response$Status;"); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "status", "(Ljavax/ws/rs/core/Response$Status;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "ok", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 4); mv.visitEnd(); continue; } } else { String methodType = serviceHandler.consumeClass() != null ? serviceHandler.consumeClass().getName().replace(".", "/") : "java/lang/String"; mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;L" + methodType + ";)Ljavax/ws/rs/core/Response;", null, null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/POST;", true); av0.visitEnd(); } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } if (serviceHandler.consumeMediaType() != null) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, serviceHandler.consumeMediaType().toMediaType()); av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("post"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/UriInfo", "getQueryParameters", "()Ljavax/ws/rs/core/MultivaluedMap;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitFieldInsn(GETSTATIC, "javax/ws/rs/core/Response$Status", "NO_CONTENT", "Ljavax/ws/rs/core/Response$Status;"); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "status", "(Ljavax/ws/rs/core/Response$Status;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "ok", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 4); mv.visitEnd(); continue; } } } { if (serviceHandler.getHttpMethod().name().equalsIgnoreCase("delete")) { { String methodName = serviceHandler.getHttpMethod().name().toLowerCase(); if (duplicateCounter++ >= 0) { methodName = methodName + "_" + duplicateCounter; } String methodType = serviceHandler.consumeClass() != null ? serviceHandler.consumeClass().getName().replace(".", "/") : "java/lang/String"; mv = cw.visitMethod(ACC_PUBLIC, methodName, "(Ljavax/ws/rs/core/UriInfo;L" + methodType + ";)Ljavax/ws/rs/core/Response;", null, null); { String p = convert(serviceHandler.path()); if (!p.equals("/") && !p.isEmpty()) { av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true); av0.visit("value", p); av0.visitEnd(); } } { av0 = mv.visitAnnotation("Ljavax/ws/rs/DELETE;", true); av0.visitEnd(); } if (serviceHandler.mediaToProduce().size() > 0) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true); { AnnotationVisitor av1 = av0.visitArray("value"); for (MediaType m : serviceHandler.mediaToProduce()) { av1.visit(null, m.toMediaType()); } av1.visitEnd(); } av0.visitEnd(); } } if (serviceHandler.consumeMediaType() != null) { { av0 = mv.visitAnnotation("Ljavax/ws/rs/Consumes;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, serviceHandler.consumeMediaType().toMediaType()); av1.visitEnd(); } av0.visitEnd(); } } { av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/core/Context;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("delete"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, className, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "ok", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 4); mv.visitEnd(); continue; } } } } } { mv = cw.visitMethod(ACC_PRIVATE, "invokeAction", "(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap;Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;", "<T:Ljava/lang/Object;>(Ljava/lang/String;Ljavax/ws/rs/core/UriInfo;Ljavax/ws/rs/core/MultivaluedMap<Ljava/lang/String;Ljava/lang/String;>;Ljava/util/Map<Ljava/lang/String;Ljava/util/Collection<Ljava/lang/String;>;>;TT;)Ljava/lang/Object;", null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "org/sonatype/restsimple/api/ActionException"); Label l3 = new Label(); mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "mapper", "Lorg/sonatype/restsimple/spi/ServiceHandlerMapper;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/UriInfo", "getPath", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/sonatype/restsimple/spi/ServiceHandlerMapper", "map", "(Ljava/lang/String;Ljava/lang/String;)Lorg/sonatype/restsimple/api/ServiceHandler;"); mv.visitVarInsn(ASTORE, 6); mv.visitVarInsn(ALOAD, 6); Label l4 = new Label(); mv.visitJumpInsn(IFNONNULL, l4); mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException"); mv.visitInsn(DUP); mv.visitIntInsn(SIPUSH, 405); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "status", "(I)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitLdcInsn("Method not allowed"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "entity", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljavax/ws/rs/core/Response;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l4); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "org/sonatype/restsimple/api/ServiceHandler" }, 0, null); mv.visitVarInsn(ALOAD, 6); mv.visitMethodInsn(INVOKEVIRTUAL, "org/sonatype/restsimple/api/ServiceHandler", "getHttpMethod", "()Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "name", "()Ljava/lang/String;"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l5 = new Label(); mv.visitJumpInsn(IFNE, l5); mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException"); mv.visitInsn(DUP); mv.visitIntInsn(SIPUSH, 405); mv.visitMethodInsn(INVOKESTATIC, "javax/ws/rs/core/Response", "status", "(I)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitLdcInsn("Method not allowed"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "entity", "(Ljava/lang/Object;)Ljavax/ws/rs/core/Response$ResponseBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "javax/ws/rs/core/Response$ResponseBuilder", "build", "()Ljavax/ws/rs/core/Response;"); mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljavax/ws/rs/core/Response;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l5); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 6); mv.visitMethodInsn(INVOKEVIRTUAL, "org/sonatype/restsimple/api/ServiceHandler", "getAction", "()Lorg/sonatype/restsimple/api/Action;"); mv.visitVarInsn(ASTORE, 8); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitVarInsn(ASTORE, 9); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/UriInfo", "getPathParameters", "()Ljavax/ws/rs/core/MultivaluedMap;"); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "entrySet", "()Ljava/util/Set;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "iterator", "()Ljava/util/Iterator;"); mv.visitVarInsn(ASTORE, 10); Label l6 = new Label(); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_FULL, 11, new Object[] { className, "java/lang/String", "javax/ws/rs/core/UriInfo", "javax/ws/rs/core/MultivaluedMap", "java/util/Map", "java/lang/Object", "org/sonatype/restsimple/api/ServiceHandler", "java/lang/Object", "org/sonatype/restsimple/api/Action", "java/util/Map", "java/util/Iterator" }, 0, new Object[] {}); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); mv.visitJumpInsn(IFEQ, l0); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/Map$Entry"); mv.visitVarInsn(ASTORE, 11); mv.visitVarInsn(ALOAD, 9); mv.visitVarInsn(ALOAD, 11); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map$Entry", "getKey", "()Ljava/lang/Object;"); mv.visitVarInsn(ALOAD, 11); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map$Entry", "getValue", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/List"); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitJumpInsn(GOTO, l6); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitTypeInsn(NEW, "org/sonatype/restsimple/api/ActionContext"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "request", "Ljavax/servlet/http/HttpServletRequest;"); mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletRequest", "getMethod", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKESPECIAL, className, "mapMethod", "(Ljava/lang/String;)Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, className, "mapHeaders", "()Ljava/util/Map;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, className, "mapFormParams", "(Ljavax/ws/rs/core/MultivaluedMap;)Ljava/util/Map;"); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "request", "Ljavax/servlet/http/HttpServletRequest;"); mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletRequest", "getInputStream", "()Ljavax/servlet/ServletInputStream;"); mv.visitVarInsn(ALOAD, 9); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKESPECIAL, "org/sonatype/restsimple/api/ActionContext", "<init>", "(Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/io/InputStream;Ljava/util/Map;Ljava/lang/Object;)V"); mv.visitVarInsn(ASTORE, 10); mv.visitVarInsn(ALOAD, 8); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKEINTERFACE, "org/sonatype/restsimple/api/Action", "action", "(Lorg/sonatype/restsimple/api/ActionContext;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, 7); mv.visitLabel(l1); Label l7 = new Label(); mv.visitJumpInsn(GOTO, l7); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "org/sonatype/restsimple/api/ActionException" }); mv.visitVarInsn(ASTORE, 10); mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 10); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKEVIRTUAL, "org/sonatype/restsimple/api/ActionException", "getStatusCode", "()I"); mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljava/lang/Throwable;I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(ASTORE, 10); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "logger", "Lorg/slf4j/Logger;"); mv.visitLdcInsn("invokeAction"); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKEINTERFACE, "org/slf4j/Logger", "error", "(Ljava/lang/String;Ljava/lang/Throwable;)V"); mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljava/lang/Throwable;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l7); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(ARETURN); mv.visitMaxs(9, 12); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE, "mapFormParams", "(Ljavax/ws/rs/core/MultivaluedMap;)Ljava/util/Map;", "(Ljavax/ws/rs/core/MultivaluedMap<Ljava/lang/String;Ljava/lang/String;>;)Ljava/util/Map<Ljava/lang/String;Ljava/util/Collection<Ljava/lang/String;>;>;", null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNULL, l0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "keySet", "()Ljava/util/Set;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "iterator", "()Ljava/util/Iterator;"); mv.visitVarInsn(ASTORE, 3); Label l1 = new Label(); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "java/util/Map", "java/util/Iterator" }, 0, null); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); mv.visitJumpInsn(IFEQ, l0); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); Label l2 = new Label(); mv.visitJumpInsn(IFNULL, l2); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/Collection"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/Collection"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "addAll", "(Ljava/util/Collection;)Z"); mv.visitInsn(POP); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/String" }, 0, null); mv.visitTypeInsn(NEW, "java/util/ArrayList"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/Collection"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "addAll", "(Ljava/util/Collection;)Z"); mv.visitInsn(POP); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); mv.visitMaxs(3, 6); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE, "mapMethod", "(Ljava/lang/String;)Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("GET"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); mv.visitFieldInsn(GETSTATIC, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "GET", "Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("PUT"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitFieldInsn(GETSTATIC, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "PUT", "Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitInsn(ARETURN); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("POST"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l2 = new Label(); mv.visitJumpInsn(IFEQ, l2); mv.visitFieldInsn(GETSTATIC, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "POST", "Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitInsn(ARETURN); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("DELETE"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitFieldInsn(GETSTATIC, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "DELETE", "Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitInsn(ARETURN); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn("HEAD"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equalsIgnoreCase", "(Ljava/lang/String;)Z"); Label l4 = new Label(); mv.visitJumpInsn(IFEQ, l4); mv.visitFieldInsn(GETSTATIC, "org/sonatype/restsimple/api/ServiceDefinition$METHOD", "HEAD", "Lorg/sonatype/restsimple/api/ServiceDefinition$METHOD;"); mv.visitInsn(ARETURN); mv.visitLabel(l4); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); mv.visitInsn(DUP); mv.visitLdcInsn("Invalid Method"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE, "mapHeaders", "()Ljava/util/Map;", "()Ljava/util/Map<Ljava/lang/String;Ljava/util/Collection<Ljava/lang/String;>;>;", null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitVarInsn(ASTORE, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "request", "Ljavax/servlet/http/HttpServletRequest;"); mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletRequest", "getHeaderNames", "()Ljava/util/Enumeration;"); mv.visitVarInsn(ASTORE, 2); Label l0 = new Label(); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "java/util/Map", "java/util/Enumeration" }, 0, null); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Enumeration", "hasMoreElements", "()Z"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Enumeration", "nextElement", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); Label l2 = new Label(); mv.visitJumpInsn(IFNULL, l2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/util/Collection"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "request", "Ljavax/servlet/http/HttpServletRequest;"); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletRequest", "getHeader", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "add", "(Ljava/lang/Object;)Z"); mv.visitInsn(POP); mv.visitJumpInsn(GOTO, l0); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/String" }, 0, null); mv.visitTypeInsn(NEW, "java/util/ArrayList"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "request", "Ljavax/servlet/http/HttpServletRequest;"); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletRequest", "getHeader", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z"); mv.visitInsn(POP); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitJumpInsn(GOTO, l0); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 5); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE, "mapMatrixParam", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map;", "(Ljavax/ws/rs/core/UriInfo;)Ljava/util/Map<Ljava/lang/String;Ljava/util/Collection<Ljava/lang/String;>;>;", null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/UriInfo", "getPathSegments", "()Ljava/util/List;"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;"); mv.visitVarInsn(ASTORE, 4); Label l0 = new Label(); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_APPEND, 3, new Object[] { "java/util/Map", "java/util/List", "java/util/Iterator" }, 0, null); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "javax/ws/rs/core/PathSegment"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/PathSegment", "getMatrixParameters", "()Ljavax/ws/rs/core/MultivaluedMap;"); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "keySet", "()Ljava/util/Set;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "iterator", "()Ljava/util/Iterator;"); mv.visitVarInsn(ASTORE, 6); Label l2 = new Label(); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "javax/ws/rs/core/PathSegment", "java/util/Iterator" }, 0, null); mv.visitVarInsn(ALOAD, 6); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitVarInsn(ALOAD, 6); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/PathSegment", "getMatrixParameters", "()Ljavax/ws/rs/core/MultivaluedMap;"); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(INVOKEINTERFACE, "javax/ws/rs/core/MultivaluedMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_CHOP, 2, null, 0, null); mv.visitJumpInsn(GOTO, l0); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;"); mv.visitInsn(ARETURN); mv.visitMaxs(4, 8); mv.visitEnd(); } cw.visitEnd(); byte[] bytes = cw.toByteArray(); try { String classToLoad = className.replace("/", "."); ClassLoader cl = new ByteClassloader(bytes, this.getClass().getClassLoader(), classToLoad); Class<?> clazz = cl.loadClass(classToLoad); moduleConfig.bind(clazz); moduleConfig.bind(GenericMessageBodyWriter.class); bindExtension(serviceDefinition); } catch (Throwable e) { logger.error("generate", e); } }