List of usage examples for org.objectweb.asm ClassVisitor visitEnd
public void visitEnd()
From source file:org.adjective.stout.writer.ByteCodeWriter.java
License:Apache License
public byte[] write(ClassDescriptor cls) { begin(cls);//from w w w .j a v a 2s. c o m ClassWriter writer = createClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = writer; if (_trace) { cv = new TraceClassVisitor(cv, new PrintWriter(System.err)); } if (_check) { cv = new CheckClassAdapter(cv); } String signature = null; // @TODO cv.visit(Opcodes.V1_5, getModifierCode(cls.getModifiers(), cls.getSort()), cls.getInternalName(), signature, getInternalName(cls.getSuperClass()), getInterfaceNames(cls)); if (cls.getSourceFile() != null) { cv.visitSource(cls.getSourceFile(), ""); } UnresolvedType outer = cls.getOuterClass(); if (outer != null) { cv.visitOuterClass(outer.getInternalName(), null, null); } for (AnnotationDescriptor annotation : cls.getAnnotations()) { writeAnnotation(cv, annotation); } for (ClassDescriptor inner : cls.getInnerClasses()) { String name = inner.getInternalName(); String simpleName = name.substring(name.lastIndexOf('/') + 1); cv.visitInnerClass(name, cls.getInternalName(), simpleName, getModifierCode(inner.getModifiers(), inner.getSort())); } for (FieldDescriptor field : cls.getFields()) { writeField(cv, field); } for (MethodDescriptor method : cls.getMethods()) { writeMethod(cv, cls, method); } cv.visitEnd(); end(cls); return writer.toByteArray(); }
From source file:org.apache.commons.weaver.normalizer.Normalizer.java
License:Apache License
/** * Create the normalized version of a given class in the configured target package. The {@link Normalizer} will * gladly do so in a package from which the normalized class will not actually be able to reference any types upon * which it relies; in such a situation you must specify the target package as the package of the supertype. * @param key used to generate the normalized classname. * @param classWrapper/*www . jav a2 s . co m*/ * @return the generated classname. * @throws IOException */ private String copy(final Pair<String, String> key, final ClassWrapper classWrapper) throws IOException { env.debug("Copying %s to %s", key, targetPackage); final MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (final NoSuchAlgorithmException e) { throw new IllegalStateException(e); } md5.update(key.getLeft().getBytes(StandardCharsets.UTF_8)); md5.update(key.getRight().getBytes(StandardCharsets.UTF_8)); final long digest = Conversion.byteArrayToLong(md5.digest(), 0, 0L, 0, Long.SIZE / Byte.SIZE); final String result = MessageFormat.format("{0}/$normalized{1,number,0;_0}", targetPackage, digest); env.debug("Copying class %s to %s", classWrapper.wrapped.getName(), result); try (InputStream bytecode = env.getClassfile(classWrapper.wrapped).getInputStream()) { final ClassReader reader = new ClassReader(bytecode); final ClassVisitor writeClass = new WriteClass(); // we're doing most of this by hand; we only read the original class to hijack signature, ctor exceptions, // etc.: reader.accept(new ClassVisitor(ASM_VERSION) { Type supertype; @Override @SuppressWarnings("PMD.UseVarargs") //overridden method public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { supertype = Type.getObjectType(superName); writeClass.visit(version, Opcodes.ACC_PUBLIC, result, signature, superName, interfaces); visitAnnotation(Type.getType(Marker.class).getDescriptor(), false); } @Override @SuppressWarnings("PMD.UseVarargs") //overridden method public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { if (INIT.equals(name)) { final Method staticCtor = new Method(INIT, key.getRight()); final Type[] argumentTypes = staticCtor.getArgumentTypes(); final Type[] exceptionTypes = toObjectTypes(exceptions); { final GeneratorAdapter mgen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, staticCtor, signature, exceptionTypes, writeClass); mgen.visitCode(); mgen.loadThis(); for (int i = 0; i < argumentTypes.length; i++) { mgen.loadArg(i); } mgen.invokeConstructor(supertype, staticCtor); mgen.returnValue(); mgen.endMethod(); } /* * now declare a dummy constructor that will match, and discard, * any originally inner-class bound constructor i.e. that set up a this$0 field. * By doing this we can avoid playing with the stack that originally * invoked such a constructor and simply rewrite the method */ { final Method instanceCtor = new Method(INIT, Type.VOID_TYPE, ArrayUtils.insert(0, argumentTypes, OBJECT_TYPE)); final GeneratorAdapter mgen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, instanceCtor, signature, exceptionTypes, writeClass); mgen.visitCode(); mgen.loadThis(); for (int i = 0; i < argumentTypes.length; i++) { mgen.loadArg(i + 1); } mgen.invokeConstructor(supertype, staticCtor); mgen.returnValue(); mgen.endMethod(); } return null; } return null; } @Override public void visitEnd() { writeClass.visitEnd(); } }, 0); } return result; }
From source file:org.eclipse.objectteams.otredyn.bytecode.asm.MultiClassAdapter.java
License:Open Source License
@Override public void visitEnd() { for (ClassVisitor visitor : visitors) { visitor.visitEnd(); } }
From source file:org.eclipse.sisu.scanners.QualifiedScanningTest.java
License:Open Source License
public void testEmptyMethods() { final AnnotationVisitor emptyAnnotationVisitor = new EmptyAnnotationVisitor(); emptyAnnotationVisitor.visit(null, null); emptyAnnotationVisitor.visitEnum(null, null, null); emptyAnnotationVisitor.visitAnnotation(null, null); emptyAnnotationVisitor.visitArray(null); emptyAnnotationVisitor.visitEnd();//from w w w . j ava 2s . c o m final ClassVisitor emptyClassVisitor = new EmptyClassVisitor(); emptyClassVisitor.visit(0, 0, null, null, null, null); emptyClassVisitor.visitAnnotation(null, false); emptyClassVisitor.visitAttribute(null); emptyClassVisitor.visitSource(null, null); emptyClassVisitor.visitEnd(); }
From source file:org.elasticsearch.painless.node.SSource.java
License:Apache License
public void write() { // Create the ClassWriter. int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS; int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL; String classBase = BASE_CLASS_TYPE.getInternalName(); String className = CLASS_TYPE.getInternalName(); String classInterfaces[] = reserved.usesScore() ? new String[] { WriterConstants.NEEDS_SCORE_TYPE.getInternalName() } : null;/*from w w w . j a va 2s .co m*/ ClassWriter writer = new ClassWriter(classFrames); ClassVisitor visitor = writer; // if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace. if (settings.isPicky()) { visitor = new SimpleChecksAdapter(visitor); } if (debugStream != null) { visitor = new TraceClassVisitor(visitor, debugStream, null); } visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces); visitor.visitSource(Location.computeSourceName(name, source), null); // Write the constructor: MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, CONSTRUCTOR, visitor, globals.getStatements(), settings); constructor.visitCode(); constructor.loadThis(); constructor.loadArgs(); constructor.invokeConstructor(org.objectweb.asm.Type.getType(Executable.class), CONSTRUCTOR); constructor.returnValue(); constructor.endMethod(); // Write the execute method: MethodWriter execute = new MethodWriter(Opcodes.ACC_PUBLIC, EXECUTE, visitor, globals.getStatements(), settings); execute.visitCode(); write(execute, globals); execute.endMethod(); // Write all functions: for (SFunction function : functions) { function.write(visitor, settings, globals); } // Write all synthetic functions. Note that this process may add more :) while (!globals.getSyntheticMethods().isEmpty()) { List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values()); globals.getSyntheticMethods().clear(); for (SFunction function : current) { function.write(visitor, settings, globals); } } // Write the constants if (false == globals.getConstantInitializers().isEmpty()) { Collection<Constant> inits = globals.getConstantInitializers().values(); // Fields for (Constant constant : inits) { visitor.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, constant.name, constant.type.getDescriptor(), null, null).visitEnd(); } // Initialize the constants in a static initializer final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, visitor, globals.getStatements(), settings); clinit.visitCode(); for (Constant constant : inits) { constant.initializer.accept(clinit); clinit.putStatic(CLASS_TYPE, constant.name, constant.type); } clinit.returnValue(); clinit.endMethod(); } // End writing the class and store the generated bytes. visitor.visitEnd(); bytes = writer.toByteArray(); }
From source file:org.jephyr.common.agent.DelegationClassAdapter.java
License:Open Source License
@Override public void visitEnd() { ClassVisitor cv1 = delegate(); if (cv1 != null) { cv1.visitEnd(); } }
From source file:org.jruby.compiler.util.HandleFactory.java
License:LGPL
public static byte[] createHandleBytes(Method method, String name) { Class returnType = method.getReturnType(); Class[] paramTypes = method.getParameterTypes(); ClassVisitor cv = new ClassWriter(ClassWriter.COMPUTE_MAXS); cv.visit(ACC_PUBLIC | ACC_FINAL | ACC_SUPER, V1_5, name, null, p(Handle.class), null); SkinnyMethodAdapter m;/*from ww w .jav a 2 s . c o m*/ String signature; boolean needsArgsVersion = true; switch (paramTypes.length) { case 0: signature = sig(Object.class, Object.class); break; case 1: signature = sig(Object.class, Object.class, Object.class); break; case 2: signature = sig(Object.class, Object.class, Object.class, Object.class); break; case 3: signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class); break; // case 4: // signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class); // break; // case 5: // signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class); // break; default: needsArgsVersion = false; signature = sig(Object.class, Object.class, Object[].class); break; } m = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "invoke", signature, null, null); m.start(); // load receiver if (!Modifier.isStatic(method.getModifiers())) { m.aload(1); // receiver if (method.getDeclaringClass() != Object.class) { m.checkcast(p(method.getDeclaringClass())); } } // load arguments switch (paramTypes.length) { case 0: case 1: case 2: case 3: // case 4: // case 5: for (int i = 0; i < paramTypes.length; i++) { loadUnboxedArgument(m, i + 2, paramTypes[i]); } break; default: for (int i = 0; i < paramTypes.length; i++) { m.aload(2); // Object[] args m.pushInt(i); m.aaload(); Class paramClass = paramTypes[i]; if (paramClass.isPrimitive()) { Class boxType = getBoxType(paramClass); m.checkcast(p(boxType)); m.invokevirtual(p(boxType), paramClass.toString() + "Value", sig(paramClass)); } else if (paramClass != Object.class) { m.checkcast(p(paramClass)); } } break; } if (Modifier.isStatic(method.getModifiers())) { m.invokestatic(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes)); } else if (Modifier.isInterface(method.getDeclaringClass().getModifiers())) { m.invokeinterface(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes)); } else { m.invokevirtual(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes)); } if (returnType == void.class) { m.aconst_null(); } else if (returnType.isPrimitive()) { Class boxType = getBoxType(returnType); m.invokestatic(p(boxType), "valueOf", sig(boxType, returnType)); } m.areturn(); m.end(); if (needsArgsVersion) { m = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "invoke", sig(Object.class, Object.class, Object[].class), null, null); m.start(); // load handle m.aload(0); // load receiver m.aload(1); // load arguments for (int i = 0; i < paramTypes.length; i++) { m.aload(2); // args array m.ldc(i); m.aaload(); // i'th argument } // invoke specific arity version m.invokevirtual(name, "invoke", sig(Object.class, params(Object.class, Object.class, paramTypes.length))); // return result m.areturn(); m.end(); } // constructor m = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "<init>", sig(void.class), null, null); m.start(); m.aload(0); m.invokespecial(p(Handle.class), "<init>", sig(void.class)); m.voidreturn(); m.end(); cv.visitEnd(); byte[] bytes = ((ClassWriter) cv).toByteArray(); return bytes; }
From source file:org.kjots.json.object.JsonObjectGeneratorBase.java
License:Apache License
/** * Generate the class.//from ww w. j a va2 s . c o m * * @param classVisitor The class visitor. * @param jsonObjectClass The class of the JSON object. * @param jsonObjectType The type of the JSON object. * @param superJsonObjectImplType The type of the super JSON object implementation. */ private void generateClass(ClassVisitor classVisitor, Class<? extends JsonObject> jsonObjectClass, Type jsonObjectType, Type superJsonObjectImplType) { Type jsonObjectImplType = Type .getObjectType(jsonObjectType.getInternalName() + "$" + this.jsonObjectImplClass.getSimpleName()); classVisitor.visit(V1_6, ACC_PUBLIC + ACC_SUPER, jsonObjectImplType, null, superJsonObjectImplType, jsonObjectType); this.generateConstructor(classVisitor, jsonObjectImplType, superJsonObjectImplType); for (java.lang.reflect.Method method : jsonObjectClass.getDeclaredMethods()) { if (method.getAnnotation(JsonFunction.class) != null) { this.generateFunctionMethod(classVisitor, jsonObjectImplType, jsonObjectClass, Method.getMethod(method), method.getAnnotation(JsonFunction.class), method.isVarArgs()); } else if (method.getAnnotation(JsonException.class) != null) { this.generateExceptionMethod(classVisitor, jsonObjectImplType, jsonObjectClass, Method.getMethod(method), method.getAnnotation(JsonException.class), method.isVarArgs()); } else if (method.getAnnotation(JsonProperty.class) != null) { this.generatePropertyMethod(classVisitor, jsonObjectImplType, method, Method.getMethod(method), method.getAnnotation(JsonProperty.class)); } else { throw new IllegalArgumentException( method.getName() + "() is not annotated with suitable annotation"); } } Set<Method> implementedMethods = new HashSet<Method>(classVisitor.getImplementedMethods()); for (GenericMethod declaredMethod : this.getExtraInterfaceMethods(jsonObjectClass)) { Method implementedMethod = null; if (declaredMethod.getGenericReturnType() || !declaredMethod.getGenericTypeIndices().isEmpty()) { implementedMethod = declaredMethod.getCompatibleMethod(implementedMethods); } else if (!declaredMethod.getGenericReturnType() && !implementedMethods.contains(declaredMethod)) { int returnTypeSort = declaredMethod.getReturnType().getSort(); if (returnTypeSort == Type.ARRAY) { returnTypeSort = declaredMethod.getReturnType().getElementType().getSort(); } if (returnTypeSort == Type.OBJECT) { GenericMethod newDeclaredMethod = new GenericMethod(declaredMethod.getName(), declaredMethod.getDescriptor(), true, declaredMethod.getGenericTypeIndices()); implementedMethod = newDeclaredMethod.getCompatibleMethod(implementedMethods); } } if (implementedMethod != null && !implementedMethod.equals(declaredMethod)) { this.generateBridgeMethod(classVisitor, jsonObjectImplType, declaredMethod, implementedMethod); } } classVisitor.visitEnd(); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Accepts a visitor and fills it with information for a given class. * @param classRep the representation for the top-level class. * @param cv the class visitor to accept. * @throws JavaGenerationException/*from w ww. j a va 2s . c om*/ */ private static void encodeClassAcceptingVisitor(JavaClassRep classRep, ClassVisitor cv) throws JavaGenerationException { // Get the fully-qualified internal class and superclass names. final JavaTypeName classRepTypeName = classRep.getClassName(); final String className = classRepTypeName.getJVMInternalName(); final String superclassName = classRep.getSuperclassName().getJVMInternalName(); // Determine if the class or any inner class contains assert statements. int assertPresence = classRep.getAssertionContainment(); if ((assertPresence & JavaClassRep.ASSERTS_UNKNOWN) > 0) { assertPresence = AsmJavaBytecodeGenerator.containsAsserts(classRep); } // Create the interfaces[] array. final int nInterfaces = classRep.getNInterfaces(); final String[] interfaces = new String[nInterfaces]; for (int i = 0; i < nInterfaces; i++) { interfaces[i] = classRep.getInterface(i).getJVMInternalName(); } //ACC_SUPER flag should always be set for the flags defining a class file. //(see the Java language specification under ACC_SUPER in the index. The flag is not set only //by older Java compilers and exists for backwards compatibility reasons). int classModifiers = classRep.getModifiers() | Opcodes.ACC_SUPER; //static inner classes are marked with the static modifier, but this is not a valid access flag for a class. classModifiers &= ~Modifier.STATIC; // We aren't generating or using generics, so the signature can be null String classSignature = null; cv.visit(Opcodes.V1_5, classModifiers, className, classSignature, superclassName, interfaces); //sourcefileName = null, since this class was not compiled from a Java source file. //However, if we are debugging byte codes, use a "fake" source file name as if this class were generated from a Java source file. //This eliminates a trivial difference between the byte code generated by ASM and that of javac and makes inspecting the //differences in a differencing tool easier. String sourceFileName = null; // if (AsmJavaBytecodeGenerator.DEBUG_GENERATED_BYTECODE) { String unqualifiedName = classRepTypeName.getUnqualifiedJavaSourceName(); int dotPosition = unqualifiedName.indexOf('.'); if (dotPosition != -1) { //get the top level class name. unqualifiedName = unqualifiedName.substring(0, dotPosition); } sourceFileName = unqualifiedName + ".java"; // } cv.visitSource(sourceFileName, null); //add the fields for (int i = 0, nFields = classRep.getNFieldDeclarations(); i < nFields; ++i) { JavaFieldDeclaration fieldDeclaration = classRep.getFieldDeclaration(i); //todoBI it may be more efficient to handle initializers for static-fields here in the cases where it is possible //(int, long, float, double, String). cv.visitField(fieldDeclaration.getModifiers(), fieldDeclaration.getFieldName(), fieldDeclaration.getFieldType().getJVMDescriptor(), null, null); } /* * When dealing with assert statements there is possibly an additional field that needs to be * added. * If a class contains an assert statement a static final synthetic boolean field called '$assertionsDisabled' is * added. This field is initialized in the class static initializer and is used to determine whether to * check or skip assertions. */ if (assertPresence != JavaClassRep.ASSERTS_NONE) { if ((assertPresence & JavaClassRep.ASSERTS_IN_CLASS) > 0) { // We need to add a static final synthetic boolean field to indicate the enabled/disabled state of assertions. cv.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, "$assertionsDisabled", "Z", null, null); } } //add the constructors final int nConstructors = classRep.getNConstructors(); if (nConstructors == 0) { //if empty, add the default constructor. JavaConstructor defaultConstructor = new JavaConstructor(Modifier.PUBLIC, ((JavaTypeName.Reference.Object) classRepTypeName).getBaseName()); defaultConstructor.addStatement(new JavaStatement.ReturnStatement()); encodeConstructor(classRep, defaultConstructor, cv); } else { for (int i = 0; i < nConstructors; ++i) { encodeConstructor(classRep, classRep.getConstructor(i), cv); } } //add the methods for (int i = 0, nMethods = classRep.getNMethods(); i < nMethods; ++i) { encodeMethod(classRep, classRep.getMethod(i), cv); } //add the initializers for the static fields encodeClassInitializer(classRep, cv, (assertPresence & JavaClassRep.ASSERTS_IN_CLASS) > 0); //add the inner classes (these are basically just references to the inner classes) //if classRep itself is an inner class, call visitInnerClass on itself. This is what the eclipse java compiler does. //javac annotates for every inner class reference occurring within the class file e.g. a field declared of inner class type, //an instance of expression of inner class type, a throws declaration on a method where an inner class is thrown. if (classRepTypeName.isInnerClass()) { JavaTypeName.Reference.Object classTypeName = (JavaTypeName.Reference.Object) classRepTypeName; String internalImportName = classTypeName.getImportName().replace('.', '/'); cv.visitInnerClass(classTypeName.getJVMInternalName(), internalImportName, classTypeName.getBaseName(), classRep.getModifiers()); } /* * Previously we would call visitInnerClass for any inner classes associated with this class. However, * we are no longer doing this. * Bytecode is generated in different scenarios (i.e. static generation, dynamic generation, etc). In some * scenarios inner classes are generated separately from the containing class. In order to keep the generated * bytecode consistent between the dynamic and static scenarios wer are not adding the attributes for contained * inner classes to the bytecode. * for (int i = 0, nInnerClasses = classRep.getNInnerClasses(); i < nInnerClasses; ++i) { JavaClassRep innerClass = classRep.getInnerClass(i); JavaTypeName.Reference.Object innerClassTypeName = (JavaTypeName.Reference.Object)innerClass.getClassName(); cw.visitInnerClass(innerClassTypeName.getJVMInternalName(), className, innerClassTypeName.getBaseName(), innerClass.getModifiers()); } */ cv.visitEnd(); }
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 w w .j a va 2s .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(); }