List of usage examples for org.objectweb.asm Opcodes F_SAME
int F_SAME
To view the source code for org.objectweb.asm Opcodes F_SAME.
Click Source Link
From source file:org.jacoco.core.internal.instr.ProbeVariableInserterTest.java
License:Open Source License
@Test(expected = IllegalStateException.class) public void testVisitFrameNegative() { ProbeVariableInserter i = new ProbeVariableInserter(0, "(J)V", delegate); i.visitFrame(Opcodes.F_SAME, 0, null, 0, null); }
From source file:org.jupiter.common.util.FastMethodAccessor.java
License:Apache License
private static FastMethodAccessor create(Class<?> type) { ArrayList<Method> methods = Lists.newArrayList(); boolean isInterface = type.isInterface(); if (!isInterface) { Class nextClass = type;/*from ww w. j av a2 s . c om*/ while (nextClass != Object.class) { addDeclaredMethodsToList(nextClass, methods); nextClass = nextClass.getSuperclass(); } } else { recursiveAddInterfaceMethodsToList(type, methods); } int n = methods.size(); String[] methodNames = new String[n]; Class<?>[][] parameterTypes_s = new Class[n][]; Class<?>[] returnTypes = new Class[n]; for (int i = 0; i < n; i++) { Method method = methods.get(i); methodNames[i] = method.getName(); parameterTypes_s[i] = method.getParameterTypes(); returnTypes[i] = method.getReturnType(); } String className = type.getName(); String accessorClassName = className + "_FastMethodAccessor"; String accessorClassNameInternal = accessorClassName.replace('.', '/'); String classNameInternal = className.replace('.', '/'); String superClassNameInternal = FastMethodAccessor.class.getName().replace('.', '/'); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessorClassNameInternal, null, superClassNameInternal, null); // ? { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, superClassNameInternal, "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } // : public Object invoke(Object obj, int methodIndex, Object... args); { mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke", "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); if (n > 0) { // ?? obj (Class<?> type) mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); mv.visitVarInsn(ASTORE, 4); // ? switch ? mv.visitVarInsn(ILOAD, 2); Label[] labels = new Label[n]; for (int i = 0; i < n; i++) { labels[i] = new Label(); } Label defaultLabel = new Label(); // the default handler block mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); StringBuilder buf = new StringBuilder(128); for (int i = 0; i < n; i++) { mv.visitLabel(labels[i]); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { classNameInternal }, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitVarInsn(ALOAD, 4); buf.setLength(0); buf.append('('); Class<?>[] parameterTypes = parameterTypes_s[i]; Class<?> returnType = returnTypes[i]; for (int p_index = 0; p_index < parameterTypes.length; p_index++) { mv.visitVarInsn(ALOAD, 3); mv.visitIntInsn(BIPUSH, p_index); mv.visitInsn(AALOAD); // ?, (?) Type p_type = Type.getType(parameterTypes[p_index]); switch (p_type.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, p_type.getDescriptor()); break; case Type.OBJECT: mv.visitTypeInsn(CHECKCAST, p_type.getInternalName()); break; } buf.append(p_type.getDescriptor()); } buf.append(')').append(Type.getDescriptor(returnType)); // ??, ??? if (isInterface) { mv.visitMethodInsn(INVOKEINTERFACE, classNameInternal, methodNames[i], buf.toString(), true); } else if (Modifier.isStatic(methods.get(i).getModifiers())) { mv.visitMethodInsn(INVOKESTATIC, classNameInternal, methodNames[i], buf.toString(), false); } else { mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, methodNames[i], buf.toString(), false); } Type r_type = Type.getType(returnType); switch (r_type.getSort()) { case Type.VOID: mv.visitInsn(ACONST_NULL); break; case Type.BOOLEAN: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); break; case Type.BYTE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); break; case Type.CHAR: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); break; case Type.SHORT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); break; case Type.INT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); break; case Type.FLOAT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); break; case Type.LONG: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); break; case Type.DOUBLE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); break; } mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); // default ?? mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } // throw exception (method not found) mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("method not found: "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", 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.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); byte[] bytes = cw.toByteArray(); AccessorClassLoader loader = AccessorClassLoader.get(type); Class<?> accessorClass = loader.defineClass(accessorClassName, bytes); try { FastMethodAccessor accessor = (FastMethodAccessor) accessorClass.newInstance(); accessor.methodNames = methodNames; accessor.parameterTypes_s = parameterTypes_s; return accessor; } catch (Throwable t) { throw new RuntimeException("Error constructing method access class: " + accessorClass, t); } }
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 w w w . ja v a2 s .co m if (className == null || className.startsWith("java/") || className.startsWith("sun/") || className.startsWith("jdk/internal/") || className.startsWith("org/lwjgl/")) return null; for (String pack : packages) if (!className.startsWith(pack)) return null; ClassReader cr = new ClassReader(classfileBuffer); final Map<String, Integer> stackMethods = new HashMap<String, Integer>(); // Scan all methods that need auto-stack if (debugTransform) System.out.println("[autostack] scanning methods in class: " + className.replace('/', '.')); cr.accept(new ClassVisitor(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.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 www. ja va 2s . c o 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 w w . ja v a 2 s.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 www. j av a 2 s . com 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.qkit.core.asm.adapters.AddCustomGraphicsAdapter.java
License:Open Source License
@Override public void visitEnd() { ClassNode cn = (ClassNode) cv;/*from www . j a va 2s . com*/ String imgVar = null; for (FieldNode f : cn.fields) { if (f.desc.contains(Image.class.getName().replace('.', '/'))) imgVar = f.name; } MethodNode mm = null, mv = null; for (MethodNode m : cn.methods) { if (m.name.equals("drawGraphics")) { mm = m; mv = new MethodNode(ACC_PUBLIC, "drawGraphics", "(ILjava/awt/Graphics;I)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "RSImageProducer", "method239", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "RSImageProducer", "anImage320", "Ljava/awt/Image;"); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "RSImageProducer", "render", "(Ljava/awt/Image;II)Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); mv.visitInsn(RETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "RSImageProducer", "anImage320", "Ljava/awt/Image;"); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/awt/Graphics", "drawImage", "(Ljava/awt/Image;IILjava/awt/image/ImageObserver;)Z"); mv.visitInsn(POP); mv.visitInsn(RETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } } cn.methods.remove(mm); cn.methods.add(mv); System.out.println(" [+M] Added gfx method"); try { cn.accept(next); } catch (Exception ez) { ez.printStackTrace(); } }
From source file:org.simantics.databoard.binding.classfactory.AsmTypeClassFactory.java
License:Open Source License
public Class<?> createRecordClass(RecordType type) throws BindingConstructionException { ClassWriter cw = new ClassWriter(0); AnnotationVisitor av0;//from www.ja va 2s.com // Create class name SignatureVisitor sv = new SignatureVisitor(); type.accept(sv, null); String sig = sv.sb.toString() + "_" + Integer.toHexString(sv.hashcode); String hash = Integer.toHexString(type.hashCode()); String className = "org.simantics.databoard.RecordType_" + sig; String classSig = "org/simantics/databoard/RecordType_" + sig; Class<?> superClass = makeBean ? Bean.class : Object.class; String superType = AsmBindingClassLoader.toClassCanonicalName(superClass); cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, classSig, null, superType, null); if (type.isReferable()) { av0 = cw.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Referable.class), true); av0.visitEnd(); } for (int i = 0; i < type.getComponentCount(); i++) { Component c = type.getComponent(i); Datatype fieldType = c.type; boolean isOptional = fieldType instanceof OptionalType; boolean isIdentifier = type.isIdentifier(i); if (isOptional) { fieldType = ((OptionalType) fieldType).componentType; } // boolean isArray = fieldType instanceof ArrayType; // if ( isArray ) { // fieldType = ((ArrayType) fieldType).componentType; // } String fieldName = toJavaFieldName(c.name); BindingRequest br = classFactory.getClass(fieldType); FieldVisitor fv = cw.visitField(ACC_PUBLIC, fieldName, br.signature, br.descriptor.equals(br.signature) ? null : br.descriptor, null); // Visit annotations if (br.annotations != null && br.annotations.length > 0) { for (Annotation a : br.annotations) { if (a instanceof Arguments) { Arguments arg = (Arguments) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Arguments.class), true); AnnotationVisitor av1 = av0.visitArray("value"); for (Class<?> clzz : arg.value()) { av1.visit(null, Type.getType(AsmBindingClassLoader.toTypeDescriptor(clzz))); } av1.visitEnd(); av0.visitEnd(); } isIdentifier |= a instanceof Identifier; if (a instanceof Length) { Length arg = (Length) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Length.class), true); AnnotationVisitor av1 = av0.visitArray("value"); for (String s : arg.value()) av1.visit(null, s); av1.visitEnd(); av0.visitEnd(); } if (a instanceof MIMEType) { MIMEType arg = (MIMEType) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(MIMEType.class), true); av0.visit("value", arg.value()); av0.visitEnd(); } if (a instanceof Name) { Name arg = (Name) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Name.class), true); av0.visit("value", arg.value()); av0.visitEnd(); } isOptional |= a instanceof Optional; if (a instanceof org.simantics.databoard.annotations.Pattern) { org.simantics.databoard.annotations.Pattern arg = (org.simantics.databoard.annotations.Pattern) a; av0 = fv.visitAnnotation(AsmBindingClassLoader .toTypeDescriptor(org.simantics.databoard.annotations.Pattern.class), true); av0.visit("value", arg.value()); av0.visitEnd(); } if (a instanceof Range) { Range arg = (Range) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Range.class), true); av0.visit("value", arg.value()); av0.visitEnd(); } if (a instanceof Unit) { Unit arg = (Unit) a; av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Unit.class), true); av0.visit("value", arg.value()); av0.visitEnd(); } } } if (isIdentifier) { av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Identifier.class), true); av0.visitEnd(); } if (isOptional) { av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Optional.class), true); av0.visitEnd(); } fv.visitEnd(); } // Constructor { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); // super() if (!makeBean) { mv.visitLabel(l0); mv.visitLineNumber(20, l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, superType, "<init>", "()V"); } else { // super( getStaticBinding() ) mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, classSig, "getStaticBinding", "()Lorg/simantics/databoard/binding/Binding;"); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/util/Bean", "<init>", "(Lorg/simantics/databoard/binding/Binding;)V"); } mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + classSig + ";", null, l0, l1, 0); if (!makeBean) { mv.visitMaxs(1, 1); } else { mv.visitMaxs(2, 1); } mv.visitEnd(); } // BINDING { FieldVisitor fv = cw.visitField(ACC_STATIC, "BINDING", "Lorg/simantics/databoard/binding/Binding;", null, null); fv.visitEnd(); MethodVisitor mv = cw.visitMethod(ACC_STATIC, "getStaticBinding", "()Lorg/simantics/databoard/binding/Binding;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitFieldInsn(GETSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;"); Label l1 = new Label(); mv.visitJumpInsn(IFNONNULL, l1); mv.visitLdcInsn(Type.getType("L" + classSig + ";")); mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/Bindings", "getBindingUnchecked", "(Ljava/lang/Class;)Lorg/simantics/databoard/binding/Binding;"); mv.visitFieldInsn(PUTSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;"); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitFieldInsn(GETSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 0); mv.visitEnd(); } cw.visitEnd(); byte[] data = cw.toByteArray(); Class<?> clazz = defineClass(className, data, 0, data.length); BindingRequest br = new BindingRequest(clazz); return clazz; }
From source file:org.simantics.databoard.binding.reflection.AsmBindingClassLoader.java
License:Open Source License
public byte[] createBindingClass(ClassInfo ci, String bindingClassName) { //System.out.println("BindingFactory: "+bindingClassName+" (for "+ci.clazz.getClassLoader()+")"); int count = ci.fields.length; ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = cw;//new CheckClassAdapter(cw); FieldVisitor fv;//from w ww . ja va 2 s. c om MethodVisitor mv; AnnotationVisitor av0; String className = ci.clazz.getName().replaceAll("\\.", "/"); bindingClassName = bindingClassName.replaceAll("\\.", "/"); Object[] classNameX = new Object[] { className }; String signature = "L" + bindingClassName + ";"; // Constructor String superClass = "org/simantics/databoard/binding/reflection/ClassBinding"; cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, bindingClassName, null, superClass, null); // Constructor { mv = cv.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/databoard/type/RecordType;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingConstructionException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(Type.getType("L" + className + ";")); mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "(Ljava/lang/Class;)V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, bindingClassName, "type", "Lorg/simantics/databoard/type/Datatype;"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitInsn(RETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", signature, null, l0, l3, 0); mv.visitLocalVariable("type", "Lorg/simantics/databoard/type/RecordType;", null, l0, l3, 1); mv.visitMaxs(2, 2); mv.visitEnd(); } // getComponent { mv = cv.visitMethod(ACC_PUBLIC, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 3); Label l1 = new Label(); mv.visitLabel(l1); Label caseLabels[] = createFieldLabels(ci); Label elseLabel = new Label(); if (count > 0) { // Switch mv.visitVarInsn(ILOAD, 2); mv.visitTableSwitchInsn(0, count - 1, elseLabel, caseLabels); // case i: x.field = value[i] for (int i = 0; i < count; i++) { Label label = caseLabels[i]; Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); String typeDescriptor = toTypeDescriptor(fieldClass); Method getter = ci.getters[i]; boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null; mv.visitLabel(label); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } // Read instance argument mv.visitVarInsn(ALOAD, 3); if (useGetter) { // call getField mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor); } else { // Read field mv.visitFieldInsn(GETFIELD, className, fieldName, typeDescriptor); } // Box box(mv, fieldClass); mv.visitInsn(ARETURN); } } mv.visitLabel(elseLabel); if (count > 0) { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Illegal field index"); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); // End Label l19 = new Label(); mv.visitLabel(l19); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l19, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l19, 1); mv.visitLocalVariable("index", "I", null, l0, l19, 2); //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, l1, l19, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // Create { mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); if (ci.beanConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V"); mv.visitVarInsn(ASTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1); //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2); mv.visitMaxs(3, 3); mv.visitEnd(); } else if (ci.argsConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); String constArgsDescriptor = "("; Class<?>[] args = ci.argsConstructor.getParameterTypes(); for (int i = 0; i < count; i++) { Label label = new Label(); Class<?> field = args[i]; String fieldName = field.getName(); Method getter = ci.getters[i]; Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); constArgsDescriptor += typeDescriptor; mv.visitLabel(label); mv.visitVarInsn(ALOAD, 1); if (i < 6) { mv.visitInsn(ICONST_0 + i); } else { mv.visitIntInsn(BIPUSH, i); } mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); unbox(mv, fieldClass); } Label l17 = new Label(); mv.visitLabel(l17); constArgsDescriptor += ")V"; mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", constArgsDescriptor); mv.visitInsn(ARETURN); Label l18 = new Label(); mv.visitLabel(l18); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l18, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l18, 1); mv.visitMaxs(21, 2); mv.visitEnd(); } else { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V"); mv.visitVarInsn(ASTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V"); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); Label l3 = new Label(); mv.visitLabel(l3); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1); //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2); mv.visitMaxs(3, 3); mv.visitEnd(); } } // CreatePartial mv = cv.visitMethod(ACC_PUBLIC, "createPartial", "()Ljava/lang/Object;", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); if (ci.beanConstructor != null) { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V"); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0); mv.visitMaxs(3, 1); mv.visitEnd(); } else if (ci.noArgsConstructor != null) { // return new MyClass(); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V"); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0); mv.visitMaxs(2, 1); mv.visitEnd(); } else { mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitIntInsn(BIPUSH, count); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitVarInsn(ASTORE, 1); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l2 = new Label(); mv.visitLabel(l2); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); Label l4 = new Label(); mv.visitLabel(l4); mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/Object;", Opcodes.INTEGER }, 0, null); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings", "[Lorg/simantics/databoard/binding/Binding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, 3); Label l5 = new Label(); mv.visitLabel(l5); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/Binding", "createDefault", "()Ljava/lang/Object;"); mv.visitInsn(AASTORE); Label l6 = new Label(); mv.visitLabel(l6); mv.visitIincInsn(2, 1); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l4); Label l7 = new Label(); mv.visitLabel(l7); mv.visitLineNumber(109, l7); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "create", "([Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(ARETURN); Label l8 = new Label(); mv.visitLabel(l8); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l8, 0); mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l1, l8, 1); mv.visitLocalVariable("i", "I", null, l2, l7, 2); mv.visitLocalVariable("fb", "Lorg/simantics/databoard/binding/Binding;", null, l5, l6, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // setComponent { mv = cv.visitMethod(ACC_PUBLIC, "setComponent", "(Ljava/lang/Object;ILjava/lang/Object;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 4); Label endLabel = new Label(); Label l1 = new Label(); mv.visitLabel(l1); Label elseLabel = new Label(); Label labels[] = new Label[count]; for (int i = 0; i < count; i++) labels[i] = new Label(); if (count > 0) { mv.visitVarInsn(ILOAD, 2); mv.visitTableSwitchInsn(0, count - 1, elseLabel, labels); for (int i = 0; i < count; i++) { Label label = labels[i]; mv.visitLabel(label); Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); Method setter = ci.setters[i]; Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null; boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null; if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 3); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); if (useSetter) { unbox(mv, setterClass); mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V"); } else { unbox(mv, fieldClass); mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor); } mv.visitInsn(RETURN); } } mv.visitLabel(elseLabel); mv.visitLineNumber(178, elseLabel); if (count > 0) { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Illegal field index"); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitLabel(endLabel); mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, endLabel, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1); mv.visitLocalVariable("index", "I", null, l0, endLabel, 2); mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, endLabel, 3); //mv.visitLocalVariable("x", "L"+className+";", null, l1, endLabel, 4); mv.visitMaxs(3, 5); mv.visitEnd(); } // IsImmutable { mv = cv.visitMethod(ACC_PUBLIC, "isImmutable", "()Z", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } // IsInstance { mv = cv.visitMethod(ACC_PUBLIC, "isInstance", "(Ljava/lang/Object;)Z", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(INSTANCEOF, className); mv.visitInsn(IRETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l1, 1); mv.visitMaxs(1, 2); mv.visitEnd(); } // SetComponents { mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "setComponents", "(Ljava/lang/Object;[Ljava/lang/Object;)V", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 3); Label firstLabel = l0; for (int i = 0; i < count; i++) { Label label = new Label(); if (firstLabel == l0) firstLabel = label; Field field = ci.fields[i]; String fieldName = field.getName(); Class<?> fieldClass = ci.fields[i].getType(); Class<?> boxClass = getBoxClass(fieldClass); String typeDescriptor = toTypeDescriptor(fieldClass); String boxTypeDescriptor = toTypeDescriptor(boxClass); Method setter = ci.setters[i]; Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null; boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null; mv.visitLabel(label); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 2); if (i < 6) { mv.visitInsn(ICONST_0 + i); } else { mv.visitIntInsn(BIPUSH, i); } mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass)); if (useSetter) { unbox(mv, setterClass); mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V"); } else { unbox(mv, fieldClass); mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor); } } Label l17 = new Label(); mv.visitLabel(l17); mv.visitInsn(RETURN); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("this", "L" + className + ";", null, l0, endLabel, 0); mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1); mv.visitLocalVariable("value", "[Ljava/lang/Object;", null, l0, endLabel, 2); //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, firstLabel, endLabel, 3); mv.visitMaxs(3, 4); mv.visitEnd(); } // Add primitive setters { addGetSetPrimitive(ci, cv, "Boolean", "Z", bindingClassName); addGetSetPrimitive(ci, cv, "Byte", "B", bindingClassName); addGetSetPrimitive(ci, cv, "Int", "I", bindingClassName); addGetSetPrimitive(ci, cv, "Long", "J", bindingClassName); addGetSetPrimitive(ci, cv, "Float", "F", bindingClassName); addGetSetPrimitive(ci, cv, "Double", "D", bindingClassName); } cv.visitEnd(); return cw.toByteArray(); }
From source file:org.simantics.databoard.binding.reflection.AsmBindingClassLoader.java
License:Open Source License
private void addGetSetPrimitive(ClassInfo ci, ClassVisitor cv, String setterName, String signature, String bindingClassName) { String className = ci.clazz.getName().replaceAll("\\.", "/"); Label firstLabel = new Label(); Label secondLabel = new Label(); Label errorLabel = new Label(); Label exitLabel = new Label(); Label lastLabel = new Label(); boolean oneByte = !signature.equals("J") && !signature.equals("D"); int c = 0;/*from w w w . j ava2s.c o m*/ for (Field f : ci.fields) { if (toTypeDescriptor(getPrimitiveClass(f.getType())).equals(signature)) c++; } int[] indices = new int[c]; Label[] caseLabel = new Label[c]; c = 0; for (int i = 0; i < ci.fields.length; i++) { Class<?> fieldClass = ci.fields[i].getType(); fieldClass = getPrimitiveClass(fieldClass); String s = toTypeDescriptor(fieldClass); if (!s.equals(signature)) continue; indices[c] = i; caseLabel[c] = new Label(); c++; } ////////////////// /// Setter /// MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "set" + setterName, "(Ljava/lang/Object;I" + signature + ")V", null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); mv.visitLabel(firstLabel); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, oneByte ? 4 : 5); mv.visitLabel(secondLabel); mv.visitVarInsn(ILOAD, 2); // switch mv.visitLookupSwitchInsn(errorLabel, indices, caseLabel); // case 1: if (c > 0) { for (int i = 0; i < c; i++) { int index = indices[i]; Method setter = ci.setters[index]; Field field = ci.fields[index]; Class<?> fieldClass = field.getType(); Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null; boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null; String typeDescriptor = toTypeDescriptor(useSetter ? setterClass : fieldClass); mv.visitLabel(caseLabel[i]); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { className }, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, new Object[] { className }, 0, null); } if (signature.equals("F")) { mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(FLOAD, 3); } else if (signature.equals("D")) { mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(DLOAD, 3); } else if (signature.equals("J")) { mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(LLOAD, 3); } else { mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 3); } if (useSetter) { boxTo(mv, setterClass); mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V"); } else { boxTo(mv, fieldClass); mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor); } mv.visitJumpInsn(GOTO, exitLabel); } } else { mv.visitInsn(POP); } // default: (error) /* mv.visitLabel(errorLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Field is not "+setterName); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); */ // default: setComponent mv.visitLabel(errorLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings", "[Lorg/simantics/databoard/binding/Binding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); if (signature.equals("F")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/FloatBinding"); mv.visitVarInsn(FLOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/FloatBinding", "create", "(F)Ljava/lang/Object;"); } else if (signature.equals("D")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/DoubleBinding"); mv.visitVarInsn(DLOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/DoubleBinding", "create", "(D)Ljava/lang/Object;"); } else if (signature.equals("J")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/LongBinding"); mv.visitVarInsn(LLOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/LongBinding", "create", "(J)Ljava/lang/Object;"); } else if (signature.equals("Z")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/BooleanBinding"); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/BooleanBinding", "create", "(Z)Ljava/lang/Object;"); } else if (signature.equals("I")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/IntBinding"); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/IntBinding", "create", "(I)Ljava/lang/Object;"); } else if (signature.equals("B")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/ByteBinding"); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/ByteBinding", "create", "(B)Ljava/lang/Object;"); } mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponent", "(Ljava/lang/Object;ILjava/lang/Object;)V"); // return mv.visitLabel(exitLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); // Something at the end mv.visitLabel(lastLabel); // mv.visitLocalVariable("this", "L"+bindingClassName+";", null, firstLabel, lastLabel, 0); // mv.visitLocalVariable("r", "Ljava/lang/Object;", null, firstLabel, lastLabel, 1); // mv.visitLocalVariable("index", "I", null, firstLabel, lastLabel, 2); // mv.visitLocalVariable("z", signature, null, firstLabel, lastLabel, 3); // mv.visitLocalVariable("x", "L"+className+";", null, secondLabel, lastLabel, 4); mv.visitMaxs(oneByte ? 5 : 6, oneByte ? 5 : 6); mv.visitEnd(); ////////////////// /// Getter /// firstLabel = new Label(); secondLabel = new Label(); errorLabel = new Label(); exitLabel = new Label(); lastLabel = new Label(); for (int i = 0; i < c; i++) caseLabel[i] = new Label(); mv = cv.visitMethod(ACC_PUBLIC, "get" + setterName, "(Ljava/lang/Object;I)" + signature, null, new String[] { "org/simantics/databoard/binding/error/BindingException" }); mv.visitCode(); mv.visitLabel(firstLabel); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, className); mv.visitVarInsn(ASTORE, 3); mv.visitLabel(secondLabel); mv.visitVarInsn(ILOAD, 2); // switch if (c > 0) { mv.visitLookupSwitchInsn(errorLabel, indices, caseLabel); // case i: for (int i = 0; i < c; i++) { int index = indices[i]; Method getter = ci.getters[index]; Field field = ci.fields[index]; Class<?> fieldClass = field.getType(); Class<?> getterClass = getter != null ? getter.getReturnType() : null; boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null; String typeDescriptor = toTypeDescriptor(useGetter ? getterClass : fieldClass); mv.visitLabel(caseLabel[i]); if (i == 0) { mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { className }, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, new Object[] { className }, 0, null); } mv.visitVarInsn(ALOAD, 3); if (useGetter) { mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor); unboxFrom(mv, getterClass); } else { mv.visitFieldInsn(GETFIELD, className, field.getName(), typeDescriptor); unboxFrom(mv, fieldClass); } if (signature.equals("F")) { mv.visitInsn(FRETURN); } else if (signature.equals("D")) { mv.visitInsn(DRETURN); } else if (signature.equals("J")) { mv.visitInsn(LRETURN); } else { mv.visitInsn(IRETURN); } } } else { mv.visitInsn(POP); } // default: (error) /* mv.visitLabel(errorLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException"); mv.visitInsn(DUP); mv.visitLdcInsn("Field is not "+setterName); mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); */ // default: mv.visitLabel(errorLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings", "[Lorg/simantics/databoard/binding/Binding;"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(AALOAD); if (signature.equals("Z")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/BooleanBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/BooleanBinding", "getValue_", "(Ljava/lang/Object;)Z"); mv.visitInsn(IRETURN); } else if (signature.equals("B")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/ByteBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/ByteBinding", "getValue_", "(Ljava/lang/Object;)B"); mv.visitInsn(IRETURN); } else if (signature.equals("I")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/IntBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/IntBinding", "getValue_", "(Ljava/lang/Object;)I"); mv.visitInsn(IRETURN); } else if (signature.equals("J")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/LongBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/LongBinding", "getValue_", "(Ljava/lang/Object;)J"); mv.visitInsn(LRETURN); } else if (signature.equals("F")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/FloatBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/FloatBinding", "getValue_", "(Ljava/lang/Object;)F"); mv.visitInsn(FRETURN); } else if (signature.equals("D")) { mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/DoubleBinding"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;"); mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/DoubleBinding", "getValue_", "(Ljava/lang/Object;)D"); mv.visitInsn(DRETURN); } // Something at the end mv.visitLabel(lastLabel); // mv.visitLocalVariable("this", "Lorg/simantics/databoard/binding/reflection/MyBinding;", null, firstLabel, lastLabel, 0); // mv.visitLocalVariable("r", "Ljava/lang/Object;", null, firstLabel, lastLabel, 1); // mv.visitLocalVariable("index", "I", null, firstLabel, lastLabel, 2); // mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, secondLabel, lastLabel, 3); mv.visitMaxs(4, 4); mv.visitEnd(); }