List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn
public void visitLdcInsn(final Object value)
From source file:one.nio.http.gen.RequestHandlerGenerator.java
License:Apache License
private void setupHeader(MethodVisitor mv, Class type, Header header) { String name = header.value(); String defaultValue = null;//from ww w .j a v a 2 s . com int eq = name.indexOf('='); if (eq > 0) { defaultValue = name.substring(eq + 1); name = name.substring(0, eq); } mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn(name + ": "); boolean needNullCheck = false; if (header.required()) { mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/http/Request", "getRequiredHeader", "(Ljava/lang/String;)Ljava/lang/String;"); } else if (defaultValue != null) { mv.visitLdcInsn(defaultValue); mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/http/Request", "getHeader", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); } else { mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/http/Request", "getHeader", "(Ljava/lang/String;)Ljava/lang/String;"); needNullCheck = true; } convertArgument(mv, type, needNullCheck); }
From source file:one.nio.serial.gen.DelegateGenerator.java
License:Apache License
private static void generateRead(ClassVisitor cv, Class cls, FieldDescriptor[] fds, List<Field> defaultFields) { MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "read", "(Lone/nio/serial/DataStream;)Ljava/lang/Object;", null, new String[] { "java/io/IOException", "java/lang/ClassNotFoundException" }); mv.visitCode();//from ww w.j a va 2s.co m mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(NEW, Type.getInternalName(cls)); mv.visitInsn(DUP); mv.visitVarInsn(ASTORE, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", "register", "(Ljava/lang/Object;)V"); ArrayList<Field> parents = new ArrayList<Field>(1); for (FieldDescriptor fd : fds) { Field ownField = fd.ownField(); Field parentField = fd.parentField(); Class sourceClass = fd.type().resolve(); FieldType srcType = FieldType.valueOf(sourceClass); if (parentField != null && !parents.contains(parentField)) { parents.add(parentField); mv.visitFieldInsn(GETSTATIC, "one/nio/util/JavaInternals", "unsafe", "Lsun/misc/Unsafe;"); mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(unsafe.objectFieldOffset(parentField)); mv.visitTypeInsn(NEW, Type.getInternalName(parentField.getType())); mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V"); } if (ownField == null) { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(), srcType.readSignature()); mv.visitInsn(srcType.convertTo(FieldType.Void)); } else if (Modifier.isFinal(ownField.getModifiers())) { FieldType dstType = FieldType.valueOf(ownField.getType()); mv.visitFieldInsn(GETSTATIC, "one/nio/util/JavaInternals", "unsafe", "Lsun/misc/Unsafe;"); mv.visitVarInsn(ALOAD, 2); if (parentField != null) emitGetField(mv, parentField); mv.visitLdcInsn(unsafe.objectFieldOffset(ownField)); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(), srcType.readSignature()); if (srcType == FieldType.Object) emitTypeCast(mv, Object.class, sourceClass); emitTypeCast(mv, sourceClass, ownField.getType()); mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", dstType.putMethod(), dstType.putSignature()); } else { mv.visitVarInsn(ALOAD, 2); if (parentField != null) emitGetField(mv, parentField); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(), srcType.readSignature()); if (srcType == FieldType.Object) emitTypeCast(mv, Object.class, sourceClass); emitTypeCast(mv, sourceClass, ownField.getType()); emitPutField(mv, ownField); } } if (defaultFields != null && !defaultFields.isEmpty()) { for (Field defaultField : defaultFields) { String defaultValue = defaultField.getAnnotation(Default.class).value(); putFieldConstant(mv, defaultField, defaultValue); } } Method readObjectMethod = JavaInternals.findMethodRecursively(cls, "readObject", ObjectInputStream.class); if (readObjectMethod != null && !Repository.hasOptions(readObjectMethod.getDeclaringClass(), Repository.SKIP_READ_OBJECT)) { mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETSTATIC, "one/nio/serial/gen/NullObjectInputStream", "INSTANCE", "Lone/nio/serial/gen/NullObjectInputStream;"); emitInvoke(mv, readObjectMethod); } mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:one.nio.serial.gen.DelegateGenerator.java
License:Apache License
private static void generateToJson(ClassVisitor cv, FieldDescriptor[] fds) { MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "toJson", "(Ljava/lang/Object;Ljava/lang/StringBuilder;)V", null, new String[] { "java/io/IOException" }); mv.visitCode();/*from www . ja va 2 s . com*/ boolean firstWritten = false; mv.visitVarInsn(ALOAD, 2); for (FieldDescriptor fd : fds) { Field ownField = fd.ownField(); if (ownField == null) { continue; } String fieldName = "\"" + ownField.getName() + "\":"; mv.visitLdcInsn(firstWritten ? ',' + fieldName : '{' + fieldName); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); firstWritten = true; Class sourceClass = fd.type().resolve(); FieldType srcType = FieldType.valueOf(sourceClass); mv.visitVarInsn(ALOAD, 1); if (fd.parentField() != null) emitGetField(mv, fd.parentField()); emitGetField(mv, ownField); emitTypeCast(mv, ownField.getType(), sourceClass); switch (srcType) { case Object: mv.visitMethodInsn(INVOKESTATIC, "one/nio/serial/Json", "appendObject", "(Ljava/lang/StringBuilder;Ljava/lang/Object;)V"); mv.visitVarInsn(ALOAD, 2); break; case Char: mv.visitMethodInsn(INVOKESTATIC, "one/nio/serial/Json", "appendChar", "(Ljava/lang/StringBuilder;C)V"); mv.visitVarInsn(ALOAD, 2); break; default: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", srcType.appendSignature()); } } if (!firstWritten) { emitInt(mv, '{'); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;"); } emitInt(mv, '}'); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;"); mv.visitInsn(POP); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:one.nio.serial.gen.DelegateGenerator.java
License:Apache License
private static void putFieldConstant(MethodVisitor mv, Field field, String value) { if (Modifier.isFinal(field.getModifiers())) { mv.visitFieldInsn(GETSTATIC, "one/nio/util/JavaInternals", "unsafe", "Lsun/misc/Unsafe;"); mv.visitVarInsn(ALOAD, 2);/* w ww . j a v a 2 s . com*/ mv.visitLdcInsn(unsafe.objectFieldOffset(field)); } else { mv.visitVarInsn(ALOAD, 2); } Class<?> fieldType = field.getType(); FieldType dstType = FieldType.valueOf(fieldType); switch (dstType) { case Int: case Byte: case Short: emitInt(mv, Integer.decode(value)); break; case Long: emitLong(mv, Long.decode(value)); break; case Boolean: emitInt(mv, Boolean.parseBoolean(value) ? 1 : 0); break; case Char: emitInt(mv, value.length() == 1 ? value.charAt(0) : Integer.decode(value)); break; case Float: emitFloat(mv, Float.parseFloat(value)); break; case Double: emitDouble(mv, Double.parseDouble(value)); break; default: if (fieldType == String.class) { mv.visitLdcInsn(value); } else if (fieldType == Character.class) { emitInt(mv, value.length() == 1 ? value.charAt(0) : Integer.decode(value)); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); } else if (fieldType == Class.class) { try { mv.visitLdcInsn(Class.forName(value, false, INSTANCE)); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Cannot set default value \"" + value + "\" to " + field, e); } } else { try { Method valueOf = fieldType.getMethod("valueOf", String.class); if (!Modifier.isStatic(valueOf.getModifiers()) || valueOf.getReturnType() != fieldType) { throw new NoSuchMethodException( "valueOf(String) is not found in class " + fieldType.getName()); } mv.visitLdcInsn(value); emitInvoke(mv, valueOf); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Cannot set default value \"" + value + "\" to " + field, e); } } } if (Modifier.isFinal(field.getModifiers())) { mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", dstType.putMethod(), dstType.putSignature()); } else { emitPutField(mv, field); } }
From source file:one.nio.serial.gen.StubGenerator.java
License:Apache License
public static Class generateEnum(String className, String[] constants) { String internalClassName = getStubName(className); ClassWriter cv = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL | ACC_ENUM, internalClassName, null, "java/lang/Enum", null); String classDesc = 'L' + internalClassName + ';'; for (String c : constants) { cv.visitField(ACC_PUBLIC | ACC_STATIC | ACC_FINAL, c, classDesc, null, null).visitEnd(); }/*from w ww .j a v a 2 s. c om*/ String arrayDesc = '[' + classDesc; cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$VALUES", arrayDesc, null, null).visitEnd(); MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "<init>", "(Ljava/lang/String;I)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Enum", "<init>", "(Ljava/lang/String;I)V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cv.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); emitInt(mv, constants.length); mv.visitTypeInsn(ANEWARRAY, internalClassName); for (int i = 0; i < constants.length; i++) { mv.visitInsn(DUP); emitInt(mv, i); mv.visitTypeInsn(NEW, internalClassName); mv.visitInsn(DUP); mv.visitLdcInsn(constants[i]); emitInt(mv, i); mv.visitMethodInsn(INVOKESPECIAL, internalClassName, "<init>", "(Ljava/lang/String;I)V"); mv.visitInsn(DUP); mv.visitFieldInsn(PUTSTATIC, internalClassName, constants[i], classDesc); mv.visitInsn(AASTORE); } mv.visitFieldInsn(PUTSTATIC, internalClassName, "$VALUES", arrayDesc); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "values", "()" + arrayDesc, null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, internalClassName, "$VALUES", arrayDesc); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "valueOf", "(Ljava/lang/String;)" + classDesc, null, null); mv.visitCode(); mv.visitLdcInsn(Type.getObjectType(internalClassName)); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); mv.visitTypeInsn(CHECKCAST, internalClassName); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cv.visitEnd(); return INSTANCE.defineClassIfNotExists(internalClassName.replace('/', '.'), cv.toByteArray()); }
From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java
License:Apache License
/** * Create or get a MessageCaller implementation for the given method. * @param ownerClass the class that owns the message * @param method the method to invoke//www. j a v a 2 s .c om * @return the message caller * @throws NoSuchMethodException * @throws SecurityException */ @SuppressWarnings("unchecked") public static Class<MessageCaller<?>> createMessageCaller(Class<?> ownerClass, Method method) throws SecurityException, NoSuchMethodException { String className = String.format("%s_%s_%d__MESSAGECALLER", ownerClass.getName(), method.getName(), getMethodNumber(method)); String classNameInternal = className.replace('.', '/'); java.lang.reflect.Type fullReturnType = method.getGenericReturnType(); if ((!(fullReturnType instanceof ParameterizedType)) && AsyncResult.class.isAssignableFrom(((Class) ((ParameterizedType) fullReturnType).getRawType()))) throw new RuntimeException("Something's wrong here: should not be called for such a method"); String returnSignature = GenericTypeHelper .getSignature(((ParameterizedType) fullReturnType).getActualTypeArguments()[0]); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); MethodVisitor mv; cw.visit(codeVersion, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC, classNameInternal, "L" + classNameInternal + "<" + returnSignature + ">;", "org/actorsguildframework/internal/MessageCaller", null); cw.visitSource(null, null); { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/actorsguildframework/internal/MessageCaller", "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Lorg/actorsguildframework/Actor;[Ljava/lang/Object;)Lorg/actorsguildframework/AsyncResult;", "(Lorg/actorsguildframework/Actor;[Ljava/lang/Object;)Lorg/actorsguildframework/AsyncResult<" + returnSignature + ">;", null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(method.getDeclaringClass()) + "__ACTORPROXY"); int idx = 0; for (Class<?> t : method.getParameterTypes()) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.visitIntInsn(Opcodes.BIPUSH, idx); mv.visitInsn(Opcodes.AALOAD); if (t.isPrimitive()) { String wrapperDescr = GenerationUtils.getWrapperInternalName(t); mv.visitTypeInsn(Opcodes.CHECKCAST, wrapperDescr); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, wrapperDescr, t.getName() + "Value", "()" + Type.getDescriptor(t)); } else { if (isArgumentFreezingRequired(method, idx, t)) { mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(SerializableFreezer.class)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(SerializableFreezer.class), "get", Type.getMethodDescriptor(SerializableFreezer.class.getMethod("get"))); } if (!t.equals(Object.class)) mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(t)); } idx++; } mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(method.getDeclaringClass()) + "__ACTORPROXY", String.format(SUPER_CALLER_NAME_FORMAT, method.getName()), Type.getMethodDescriptor(method)); mv.visitInsn(Opcodes.ARETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l2, 0); mv.visitLocalVariable("instance", "Lorg/actorsguildframework/Actor;", null, l0, l2, 1); mv.visitLocalVariable("arguments", "[Ljava/lang/Object;", null, l0, l2, 2); mv.visitMaxs(0, 0); mv.visitEnd(); } { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getMessageName", "()Ljava/lang/String;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLdcInsn(method.getName()); mv.visitInsn(Opcodes.ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l1, 0); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); return (Class<MessageCaller<?>>) GenerationUtils.loadClass(className, cw.toByteArray()); }
From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java
License:Apache License
/** * Writes a proxy method for messages.// w w w .j ava 2s . c om * @param classNameInternal the internal class name * @param classNameDescriptor the class name descriptor * @param cw the ClassWriter * @param index the message index * @param type the ActorState type to use * @param concurrencyModel the concurrency model of the message * @param messageDescriptor the message's descriptor * @param method the method to override * @param simpleDescriptor a simple descriptor of the message * @param genericSignature the signature of the message */ private static void writeProxyMethod(String classNameInternal, String classNameDescriptor, ClassWriter cw, int index, Type actorState, ConcurrencyModel concurrencyModel, MessageImplDescriptor messageDescriptor, Method method, String simpleDescriptor, String genericSignature) throws NoSuchMethodException { MethodVisitor mv; { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), simpleDescriptor, genericSignature, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitIntInsn(Opcodes.BIPUSH, method.getParameterTypes().length); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int j = 0; j < method.getParameterTypes().length; j++) { mv.visitInsn(Opcodes.DUP); mv.visitIntInsn(Opcodes.BIPUSH, j); Class<?> paraType = method.getParameterTypes()[j]; if (paraType.isPrimitive()) { String wrapperClass = GenerationUtils.getWrapperInternalName(paraType); Type primType = Type.getType(paraType); mv.visitVarInsn(primType.getOpcode(Opcodes.ILOAD), j + 1); mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClass, "valueOf", "(" + primType.getDescriptor() + ")" + "L" + wrapperClass + ";"); } else if (isArgumentFreezingRequired(method, j, paraType)) { mv.visitVarInsn(Opcodes.ALOAD, j + 1); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(SerializableFreezer.class), "freeze", Type.getMethodDescriptor(SerializableFreezer.class.getMethod("freeze", Object.class))); } else if (paraType.isInterface()) { mv.visitVarInsn(Opcodes.ALOAD, j + 1); mv.visitInsn(Opcodes.DUP); mv.visitTypeInsn(Opcodes.INSTANCEOF, "org/actorsguildframework/Actor"); Label lEndif = new Label(); mv.visitJumpInsn(Opcodes.IFNE, lEndif); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ActorRuntimeException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(String.format( "Argument %d is an non-Serializable interface, but you did not give an Actor. If a message's argument type is an interface that does not extend Serializable, only Actors are acceptable as argument.", j)); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ActorRuntimeException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lEndif); } else mv.visitVarInsn(Opcodes.ALOAD, j + 1); mv.visitInsn(Opcodes.AASTORE); } Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(Opcodes.ASTORE, method.getParameterTypes().length + 1); // method.getParameterTypes().length+1 ==> 'args' local variable mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY", actorState.getDescriptor()); mv.visitFieldInsn(Opcodes.GETSTATIC, classNameInternal, String.format(MESSAGE_CALLER_NAME_FORMAT, index), "Lorg/actorsguildframework/internal/MessageCaller;"); mv.visitFieldInsn(Opcodes.GETSTATIC, "org/actorsguildframework/annotations/ThreadUsage", messageDescriptor.getThreadUsage().name(), "Lorg/actorsguildframework/annotations/ThreadUsage;"); mv.visitVarInsn(Opcodes.ALOAD, method.getParameterTypes().length + 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, actorState.getInternalName(), "queueMessage", "(Lorg/actorsguildframework/internal/MessageCaller;Lorg/actorsguildframework/annotations/ThreadUsage;[Ljava/lang/Object;)Lorg/actorsguildframework/internal/AsyncResultImpl;"); mv.visitInsn(Opcodes.ARETURN); Label l4 = new Label(); mv.visitLabel(l4); mv.visitLocalVariable("this", classNameDescriptor, null, l0, l4, 0); for (int j = 0; j < method.getParameterTypes().length; j++) mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]), GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l4, j + 1); mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l1, l4, method.getParameterTypes().length + 1); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:org.actorsguildframework.internal.codegenerator.BeanCreator.java
License:Apache License
/** * Writes the bean constructor to the given ClassWriter. * @param beanClass the original bean class to extend * @param bcd the descriptor of the bean * @param classNameInternal the internal name of the new class * @param cw the ClassWriter to write to * @param snippetWriter if not null, this will be invoked to add a snippet * after the invocation of the super constructor */// www. j a va 2 s . c om public static void writeConstructor(Class<?> beanClass, BeanClassDescriptor bcd, String classNameInternal, ClassWriter cw, SnippetWriter snippetWriter) { String classNameDescriptor = "L" + classNameInternal + ";"; int localPropertySize = 0; ArrayList<PropertyDescriptor> localVarProperties = new ArrayList<PropertyDescriptor>(); for (int i = 0; i < bcd.getPropertyCount(); i++) { PropertyDescriptor pd = bcd.getProperty(i); if (pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null)) { localVarProperties.add(pd); localPropertySize += Type.getType(pd.getPropertyClass()).getSize(); } } final int locVarThis = 0; final int locVarController = 1; final int locVarProps = 2; final int locVarPropertiesOffset = 3; final int locVarP = 3 + localPropertySize; final int locVarK = 4 + localPropertySize; final int locVarV = 5 + localPropertySize; MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lorg/actorsguildframework/internal/Controller;Lorg/actorsguildframework/Props;)V", null, null); mv.visitCode(); Label lTry = new Label(); Label lCatch = new Label(); mv.visitTryCatchBlock(lTry, lCatch, lCatch, "java/lang/ClassCastException"); Label lBegin = new Label(); mv.visitLabel(lBegin); mv.visitVarInsn(Opcodes.ALOAD, locVarThis); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(beanClass), "<init>", "()V"); if (snippetWriter != null) snippetWriter.write(mv); Label lPropertyInit = new Label(); mv.visitLabel(lPropertyInit); // load default values into the local variables for each property that must be set int varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); if (pd.getDefaultValue() != null) mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(pd.getDefaultValue().getDeclaringClass()), pd.getDefaultValue().getName(), Type.getDescriptor(pd.getDefaultValue().getType())); else GenerationUtils.generateLoadDefault(mv, pd.getPropertyClass()); mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), locVarPropertiesOffset + varCount); varCount += pt.getSize(); } // loop through the props argument's list mv.visitVarInsn(Opcodes.ALOAD, locVarProps); mv.visitVarInsn(Opcodes.ASTORE, locVarP); Label lWhile = new Label(); Label lEndWhile = new Label(); Label lWhileBody = new Label(); mv.visitLabel(lWhile); mv.visitJumpInsn(Opcodes.GOTO, lEndWhile); mv.visitLabel(lWhileBody); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getKey", "()Ljava/lang/String;"); mv.visitVarInsn(Opcodes.ASTORE, locVarK); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getValue", "()Ljava/lang/Object;"); mv.visitVarInsn(Opcodes.ASTORE, locVarV); mv.visitLabel(lTry); // write an if for each property Label lEndIf = new Label(); varCount = 0; int ifCount = 0; for (int i = 0; i < bcd.getPropertyCount(); i++) { PropertyDescriptor pd = bcd.getProperty(i); boolean usesLocal = pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null); Class<?> propClass = pd.getPropertyClass(); Type pt = Type.getType(propClass); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitLdcInsn(pd.getName()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); Label lElse = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, lElse); if (!usesLocal) mv.visitVarInsn(Opcodes.ALOAD, locVarThis); // for setter invocation, load 'this' if (propClass.isPrimitive()) { mv.visitLdcInsn(pd.getName()); mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(BeanHelper.class), String.format("get%s%sFromPropValue", propClass.getName().substring(0, 1).toUpperCase(Locale.US), propClass.getName().substring(1)), "(Ljava/lang/String;Ljava/lang/Object;)" + pt.getDescriptor()); } else if (!propClass.equals(Object.class)) { mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitTypeInsn(Opcodes.CHECKCAST, pt.getInternalName()); } else mv.visitVarInsn(Opcodes.ALOAD, locVarV); if (!usesLocal) mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(), Type.getMethodDescriptor(pd.getSetter())); else mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), varCount + locVarPropertiesOffset); mv.visitJumpInsn(Opcodes.GOTO, lEndIf); mv.visitLabel(lElse); ifCount++; if (usesLocal) varCount += pt.getSize(); } // else (==> if not prop matched) throw IllegalArgumentException mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("Unknown property \"%s\"."); mv.visitInsn(Opcodes.ICONST_1); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitInsn(Opcodes.AASTORE); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lCatch); mv.visitInsn(Opcodes.POP); // pop the exception object (not needed) mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("Incompatible type for property \"%s\". Got %s."); mv.visitInsn(Opcodes.ICONST_2); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitInsn(Opcodes.AASTORE); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_1); mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;"); mv.visitInsn(Opcodes.AASTORE); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lEndIf); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "tail", "()Lorg/actorsguildframework/Props;"); mv.visitVarInsn(Opcodes.ASTORE, locVarP); mv.visitLabel(lEndWhile); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitJumpInsn(Opcodes.IFNONNULL, lWhileBody); // write local variables back into properties varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); mv.visitVarInsn(Opcodes.ALOAD, locVarThis); if (pd.getPropertySource() == PropertySource.ABSTRACT_METHOD) { mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount); mv.visitFieldInsn(Opcodes.PUTFIELD, classNameInternal, String.format(PROP_FIELD_NAME_TEMPLATE, pd.getName()), pt.getDescriptor()); } else if (pd.getPropertySource() == PropertySource.USER_WRITTEN) { mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(), Type.getMethodDescriptor(pd.getSetter())); } else throw new RuntimeException("Internal error"); varCount += pt.getSize(); } // if bean is thread-safe, publish all writes now if (bcd.isThreadSafe()) { mv.visitVarInsn(Opcodes.ALOAD, locVarThis); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.MONITORENTER); mv.visitInsn(Opcodes.MONITOREXIT); } mv.visitInsn(Opcodes.RETURN); Label lEnd = new Label(); mv.visitLabel(lEnd); mv.visitLocalVariable("this", classNameDescriptor, null, lBegin, lEnd, locVarThis); mv.visitLocalVariable("controller", "Lorg/actorsguildframework/internal/Controller;", null, lBegin, lEnd, locVarController); mv.visitLocalVariable("props", "Lorg/actorsguildframework/Props;", null, lBegin, lEnd, locVarProps); varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); mv.visitLocalVariable("__" + pd.getName(), pt.getDescriptor(), GenericTypeHelper.getSignature(pd.getPropertyType()), lPropertyInit, lEnd, locVarPropertiesOffset + varCount); varCount += pt.getSize(); } mv.visitLocalVariable("p", "Lorg/actorsguildframework/Props;", null, lPropertyInit, lEnd, locVarP); mv.visitLocalVariable("k", "Ljava/lang/String;", null, lWhile, lEndWhile, locVarK); mv.visitLocalVariable("v", "Ljava/lang/Object;", null, lWhile, lEndWhile, locVarV); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.adjective.stout.instruction.LoadConstantInstruction.java
License:Apache License
public void accept(MethodVisitor visitor) { visitor.visitLdcInsn(_value); }
From source file:org.alkemy.instr.ConstructorWriter.java
License:Open Source License
public static void appendCreateArgs(ClassWriter cw, String className, List<String> orderedNames, Map<String, FieldProperties> fieldMap, boolean defaultCtor) { final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_ARGS, // "([Ljava/lang/Object;)" + AlkemizerUtils.toDescFromClassName(className), null, null); mv.visitCode();// w w w .j a va2 s. c o m if (defaultCtor) { mv.visitTypeInsn(NEW, className); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false); mv.visitVarInsn(ASTORE, 1); } else { mv.visitMethodInsn(INVOKESTATIC, className, CREATE_DEFAULT, // "()" + AlkemizerUtils.toDescFromClassName(className), false); mv.visitVarInsn(ASTORE, 1); } for (int i = 0; i < orderedNames.size(); i++) { final String name = orderedNames.get(i); final FieldProperties props = fieldMap.get(name); mv.visitVarInsn(ALOAD, 1); if (props.isEnum) { mv.visitLdcInsn(Type.getType(props.desc)); } mv.visitVarInsn(ALOAD, 0); visitInStack(i, mv); mv.visitInsn(AALOAD); final ClassCaster classCaster = getCastClassForDesc(props.desc); if (props.isEnum) { mv.visitMethodInsn(INVOKESTATIC, "org/alkemy/instr/AlkemizerUtils$Proxy", "toEnum", "(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object;", false); } mv.visitTypeInsn(CHECKCAST, classCaster.name); if (classCaster.method != null) { mv.visitMethodInsn(INVOKEVIRTUAL, classCaster.name, classCaster.method, "()" + props.desc, false); } mv.visitFieldInsn(PUTFIELD, className, name, props.desc); } mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }