private static <T> void appendApplyDelayedCellSetterN( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, ClassWriter cw, String classType) { MethodVisitor mv; for (int i = 0; i < delayedCellSetters.length; i++) { if (delayedCellSetters[i] != null) { mv = cw.visitMethod( ACC_PRIVATE, "applyDelayedCellSetter" + i, "()V", null, new String[] {"java/lang/Exception"}); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, classType, "delayedCellSetter" + i, "L" + DELAYED_CELL_SETTER_TYPE + ";"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classType, "currentInstance", "Ljava/lang/Object;"); mv.visitMethodInsn( INVOKEINTERFACE, DELAYED_CELL_SETTER_TYPE, "set", "(Ljava/lang/Object;)V", true); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } } }
public void addSetMethod(MetaBeanProperty property) throws Exception { MetaMethod setter = property.getSetter(); Type paramType = Type.getType(setter.getParameterTypes()[0].getTheClass()); Type returnType = Type.getType(setter.getReturnType()); String setterDescriptor = Type.getMethodDescriptor(returnType, new Type[] {paramType}); // GENERATE public void <propName>(<type> v) { <setter>(v) } String setMethodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {paramType}); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, property.getName(), setMethodDescriptor, null, new String[0]); methodVisitor.visitCode(); // GENERATE <setter>(v) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(paramType.getOpcode(Opcodes.ILOAD), 1); methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), setterDescriptor); // END methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private static <T> void appendCellValue( CellSetter<T>[] setters, boolean ignoreException, ClassWriter cw, String classType) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "cellValue", "([CIII)V", null, null); mv.visitCode(); if (setters.length != 0) { if (ignoreException) { callCellValue(mv, classType); } else { Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); mv.visitLabel(l0); callCellValue(mv, classType); 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/Exception"}); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn( INVOKEVIRTUAL, classType, "fieldError", "(ILjava/lang/Exception;)V", false); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } } mv.visitInsn(RETURN); mv.visitMaxs(5, 6); mv.visitEnd(); }
private void createAddMessage(ClassNode cn) { Pattern p = new PatternBuilder() .add( new InstructionElement(ALOAD), new LdcElement(new LdcInsnNode("")), new InstructionElement(ALOAD), new InstructionElement(INVOKEVIRTUAL)) .build(); MethodInsnNode ebola1 = null; for (MethodNode mn : cn.methods) { if (!p.contains(mn.instructions)) continue; int offset = p.getOffset(mn.instructions); ebola1 = (MethodInsnNode) mn.instructions.get(offset + 3); } { MethodVisitor mv = cn.visitMethod(ACC_PUBLIC, "addChatMessage", "(Ljava/lang/String;)V", null, null); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(""); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, ebola1.owner, ebola1.name, ebola1.desc, ebola1.itf); mv.visitInsn(RETURN); mv.visitEnd(); } }
public static byte[] dumpInner() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$Inner", null, "java/lang/Object", null); cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$Inner", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
public static void loadReference(String name, WriterController controller) { CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); ClassNode classNode = controller.getClassNode(); AsmClassGenerator acg = controller.getAcg(); // compileStack.containsVariable(name) means to ask if the variable is already declared // compileStack.getScope().isReferencedClassVariable(name) means to ask if the variable is a // field // If it is no field and is not yet declared, then it is either a closure shared variable or // an already declared variable. if (!compileStack.containsVariable(name) && compileStack.getScope().isReferencedClassVariable(name)) { acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name))); } else { BytecodeVariable v = compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode())); if (v == null) { // variable is not on stack because we are // inside a nested Closure and this variable // was not used before // then load it from the Closure field FieldNode field = classNode.getDeclaredField(name); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, controller.getInternalClassName(), name, BytecodeHelper.getTypeDescription(field.getType())); } else { mv.visitVarInsn(ALOAD, v.getIndex()); } controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE); } }
protected void injectSetByName(ClassWriter classWriter) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "set", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", null, new String[] {"java/lang/IllegalAccessException"}); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 2); methodVisitor.visitMethodInsn( INVOKESPECIAL, getAccessorNameInternal(this.getTarget(), this.getAccessorType()), "getIndex", "(Ljava/lang/String;)I", false); methodVisitor.visitVarInsn(ALOAD, 3); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, getAccessorNameInternal(this.getTarget(), this.getAccessorType()), "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", false); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(4, 4); methodVisitor.visitEnd(); }
protected void injectGetByIndex( ClassWriter classWriter, String targetClassName, List<Field> fields) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())}); Boxer boxer = new Boxer(methodVisitor); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ILOAD, 2); int maxStack = 6; Label[] labels = new Label[fields.size()]; Label errorLabel = new Label(); for (int i = 0; i < fields.size(); i++) { labels[i] = new Label(); } methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels); if (!fields.isEmpty()) { maxStack--; for (int i = 0; i < fields.size(); i++) { Field field = fields.get(i); Class<?> type = field.getType(); String fieldDescriptor = Type.getDescriptor(type); methodVisitor.visitLabel(labels[i]); if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null); else methodVisitor.visitFrame(F_SAME, 0, null, 0, null); if (isPublic(field)) { methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, targetClassName); methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor); boxer.box(Type.getType(type)); } else { injectReflectiveGetter(methodVisitor); } methodVisitor.visitInsn(ARETURN); } methodVisitor.visitLabel(errorLabel); methodVisitor.visitFrame(F_SAME, 0, null, 0, null); } injectException(methodVisitor, IllegalAccessException.class); methodVisitor.visitMaxs(maxStack, 3); methodVisitor.visitEnd(); }
private void finalizeToString(MethodVisitor mv) { // The StringBuilder is on the top of the stack from the last append() - // duplicate it for call to replace() mv.visitVarInsn(ALOAD, 1); mv.visitInsn(DUP); // The replace starts at 2 characters before the end, to remove the // extra command and space added mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false); mv.visitLdcInsn(2); mv.visitInsn(ISUB); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false); mv.visitLdcInsn("}"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "replace", "(IILjava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
private static <T> void appendGetDelayedCellSetterSwitch( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, String classType, MethodVisitor mv, int switchStart, int switchEnd) { mv.visitVarInsn(ILOAD, 1); Label defaultLabel = new Label(); Label[] labels = newLabels(switchEnd - switchStart); mv.visitTableSwitchInsn(switchStart, switchEnd - 1, defaultLabel, labels); for (int i = switchStart; i < switchEnd; i++) { mv.visitLabel(labels[i - switchStart]); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); if (delayedCellSetters != null) { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, classType, "delayedCellSetter" + i, "L" + DELAYED_CELL_SETTER_TYPE + ";"); } else { mv.visitInsn(ACONST_NULL); } mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); }
private static void callDelayedCellValue(MethodVisitor mv, String classType) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitMethodInsn(INVOKESPECIAL, classType, "_delayedCellValue", "([CIII)V", false); }
private static byte[] generate(String name, Class<?> type, Class<?> parameter) { name = name.replace('.', '/'); String typeName = Type.getInternalName(type); String typeDesc = Type.getDescriptor(type); String parameterName = Type.getInternalName(parameter); String parameterDesc = Type.getDescriptor(parameter); String constructSignature = '(' + parameterDesc + ')' + typeDesc; ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, BASE_CLASS, null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Class;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "<init>", "(Ljava/lang/Class;)V", false); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "construct", constructSignature, null, null); mv.visitCode(); mv.visitTypeInsn(NEW, typeName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, typeName, "<init>", '(' + parameterDesc + ")V", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "construct", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, parameterName); mv.visitMethodInsn(INVOKEVIRTUAL, name, "construct", constructSignature, false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
public static byte[] dump1() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null); cw.visitOuterClass("pkg/Outer", "m", "()V"); cw.visitInnerClass("pkg/Outer$1", null, null, 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(" "); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
private static void insertGetString( ClassWriter cw, String classNameInternal, ArrayList<Field> fields) { int maxStack = 6; MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "getString", "(Ljava/lang/Object;I)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 2); if (!fields.isEmpty()) { maxStack--; Label[] labels = new Label[fields.size()]; Label labelForInvalidTypes = new Label(); boolean hasAnyBadTypeLabel = false; for (int i = 0, n = labels.length; i < n; i++) { if (fields.get(i).getType().equals(String.class)) labels[i] = new Label(); else { labels[i] = labelForInvalidTypes; hasAnyBadTypeLabel = true; } } Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); for (int i = 0, n = labels.length; i < n; i++) { if (!labels[i].equals(labelForInvalidTypes)) { Field field = fields.get(i); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); if (!Modifier.isStatic(field.getModifiers())) { mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); } mv.visitFieldInsn( Modifier.isStatic(field.getModifiers()) ? GETSTATIC : GETFIELD, classNameInternal, field.getName(), "Ljava/lang/String;"); mv.visitInsn(ARETURN); } } // Rest of fields: different type if (hasAnyBadTypeLabel) { mv.visitLabel(labelForInvalidTypes); mv.visitFrame(F_SAME, 0, null, 0, null); insertThrowExceptionForFieldType(mv, "String"); } // Default: field not found mv.visitLabel(defaultLabel); mv.visitFrame(F_SAME, 0, null, 0, null); } insertThrowExceptionForFieldNotFound(mv); mv.visitMaxs(maxStack, 3); mv.visitEnd(); }
public void inlineGet( ThreadContext tc, STable st, MethodVisitor mv, String className, String prefix) { mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0 + ThreadContext.NATIVE_NUM); mv.visitFieldInsn(Opcodes.PUTFIELD, "org/perl6/nqp/runtime/ThreadContext", "native_type", "I"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, prefix, "D"); mv.visitFieldInsn(Opcodes.PUTFIELD, "org/perl6/nqp/runtime/ThreadContext", "native_n", "D"); mv.visitInsn(Opcodes.RETURN); }
public Class<?> createWrapper(Method callback) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); /* System.out.println("Name: " + name); System.out.println("Desc: " + desc); System.out.println("InstType: " + instType); System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback)); System.out.println("Event: " + eventType); */ cw.visit( V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC}); cw.visitSource(".dynamic", null); { cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, instType); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, eventType); mv.visitMethodInsn( INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback)); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return LOADER.define(name, cw.toByteArray()); }
private void contributeToString( String internalName, Property<Class<?>, Method> property, MethodVisitor toStringMv) { if (property.isLeastSpecificType()) { Type returnType = Type.getReturnType(property.getAccessor()); toStringMv.visitVarInsn(ALOAD, 0); toStringMv.visitVarInsn(ALOAD, 1); toStringMv.visitLdcInsn(property.getName()); toStringMv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;", false); toStringMv.visitLdcInsn("="); toStringMv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;", false); toStringMv.visitVarInsn(ALOAD, 0); toStringMv.visitMethodInsn( INVOKESPECIAL, internalName, property.getAccessor().getName(), Type.getMethodDescriptor(property.getAccessor()), false); String desc = property.getType().isPrimitive() ? Type.getDescriptor(property.getType()) : "Ljava/lang/Object;"; toStringMv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(" + desc + ")Ljava/lang/StringBuilder;", false); toStringMv.visitLdcInsn(", "); toStringMv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;", false); } }
/** Generate a call to the delegate object. */ protected MethodVisitor makeDelegateCall( final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) { MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions); mv.visitVarInsn(ALOAD, 0); // load this mv.visitFieldInsn( GETFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass)); // load delegate // using InvokerHelper to allow potential intercepted calls int size; mv.visitLdcInsn(name); // method name Type[] args = Type.getArgumentTypes(desc); BytecodeHelper.pushConstant(mv, args.length); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); size = 3; int idx = 1; for (int i = 0; i < args.length; i++) { Type arg = args[i]; mv.visitInsn(DUP); BytecodeHelper.pushConstant(mv, i); // primitive types must be boxed if (isPrimitive(arg)) { mv.visitIntInsn(getLoadInsn(arg), idx); String wrappedType = getWrappedClassDescriptor(arg); mv.visitMethodInsn( INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";"); } else { mv.visitVarInsn(ALOAD, idx); // load argument i } size = Math.max(6, 5 + registerLen(arg)); idx += registerLen(arg); mv.visitInsn(AASTORE); // store value into array } mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;"); unwrapResult(mv, desc); mv.visitMaxs(size, registerLen(args) + 1); return EMPTY_VISITOR; }
@Override protected void insertTransform( MethodVisitor mv, Parameter param, Class<?> targetType, int local) { mv.visitVarInsn(ALOAD, local); Label failure = new Label(); Label success = new Label(); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "isPresent", "()Z", false); mv.visitJumpInsn(IFEQ, failure); // Unwrap the optional mv.visitVarInsn(ALOAD, local); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Optional", "get", "()Ljava/lang/Object;", false); mv.visitVarInsn(ASTORE, local); mv.visitVarInsn(ALOAD, local); mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(targetType)); if (this.anno.typeFilter().length != 0) { mv.visitJumpInsn(IFEQ, failure); mv.visitVarInsn(ALOAD, local); // For each type we do an instance check and jump to either failure or success if matched for (int i = 0; i < this.anno.typeFilter().length; i++) { Class<?> filter = this.anno.typeFilter()[i]; if (i < this.anno.typeFilter().length - 1) { mv.visitInsn(DUP); } mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(filter)); if (this.anno.inverse()) { mv.visitJumpInsn(IFNE, failure); } else { mv.visitJumpInsn(IFNE, success); } } if (this.anno.inverse()) { mv.visitJumpInsn(GOTO, success); } // If the annotation was not reversed then we fall into failure as no types were matched } else { mv.visitJumpInsn(IFNE, success); } mv.visitLabel(failure); mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); mv.visitLabel(success); }
private void build_boilerplate(ClassWriter cw) { String classname = "SVDBPersistenceDelegate"; String full_classname = transform_cls(fTargetPkg) + "/" + classname; cw.visit( Opcodes.V1_5, ACC_PROTECTED + ACC_PUBLIC + ACC_SUPER, full_classname, null, fBaseClass, null); cw.visitSource(classname + ".java", null); MethodVisitor mv; // Constructor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, fBaseClass, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); buildItemDispatchMethods(cw); buildObjectDispatchMethods(cw); }
@Override public void generateMethods(Object classVisitor) { assert classVisitor instanceof ClassVisitor; ClassVisitor cv = (ClassVisitor) classVisitor; // generated by compiling the class: // class foo { public ClassLoader getFrameworkClassLoader() { return // getClass().getClassLoader(); } } // and then running ASMifier on it: // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo MethodVisitor mv = cv.visitMethod( ACC_PUBLIC, "getFrameworkClassLoader", "()Ljava/lang/ClassLoader;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // generated code ends. }
/** * Initializes a member mixin field. * * @param mv * @param fieldInfo */ private void initializeMemberMixinField(final MethodVisitor mv, final MixinFieldInfo fieldInfo) { mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(fieldInfo.mixinClassInfo.getName().replace('/', '.')); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESTATIC, MIXINS_CLASS_NAME, MIXIN_OF_METHOD_NAME, MIXIN_OF_METHOD_PER_INSTANCE_SIGNATURE); mv.visitTypeInsn(CHECKCAST, fieldInfo.mixinClassInfo.getName().replace('.', '/')); mv.visitFieldInsn( PUTFIELD, m_declaringTypeName, fieldInfo.fieldName, fieldInfo.mixinClassInfo.getSignature()); }
public boolean addGeneratedClosureConstructorCall(ConstructorCallExpression call) { ClassNode classNode = controller.getClassNode(); if (!classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type)) return false; AsmClassGenerator acg = controller.getAcg(); OperandStack operandStack = controller.getOperandStack(); MethodVisitor mv = controller.getMethodVisitor(); mv.visitVarInsn(ALOAD, 0); ClassNode callNode = classNode.getSuperClass(); TupleExpression arguments = (TupleExpression) call.getArguments(); if (arguments.getExpressions().size() != 2) throw new GroovyBugError( "expected 2 arguments for closure constructor super call, but got" + arguments.getExpressions().size()); arguments.getExpression(0).visit(acg); operandStack.box(); arguments.getExpression(1).visit(acg); operandStack.box(); // TODO: replace with normal String, p not needed Parameter p = new Parameter(ClassHelper.OBJECT_TYPE, "_p"); String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[] {p, p}); mv.visitMethodInsn( INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false); operandStack.remove(2); return true; }
public void loadOrStoreVariable(BytecodeVariable variable, boolean useReferenceDirectly) { CompileStack compileStack = controller.getCompileStack(); if (compileStack.isLHS()) { storeVar(variable); } else { MethodVisitor mv = controller.getMethodVisitor(); int idx = variable.getIndex(); ClassNode type = variable.getType(); if (variable.isHolder()) { mv.visitVarInsn(ALOAD, idx); if (!useReferenceDirectly) { mv.visitMethodInsn( INVOKEVIRTUAL, "groovy/lang/Reference", "get", "()Ljava/lang/Object;", false); BytecodeHelper.doCast(mv, type); push(type); } else { push(ClassHelper.REFERENCE_TYPE); } } else { load(type, idx); } } }
private void generateAccessor( ClassWriter cw, Class<?> parentType, String internalName, Property<Class<?>, Method> property) { Method accessor = property.getAccessor(); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, accessor.getName(), Type.getMethodDescriptor(accessor), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, internalName, property.getName(), Type.getDescriptor(property.getLeastSpecificType())); if (!property.isLeastSpecificType()) { mv.visitTypeInsn(CHECKCAST, Type.getInternalName(property.getType())); } mv.visitInsn(Type.getType(property.getType()).getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); }
private static byte[] generateEventExecutor(Method m, String name) { final boolean staticMethod = Modifier.isStatic(m.getModifiers()); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); writer.visit( V1_8, ACC_PUBLIC, name, null, "java/lang/Object", new String[] {Type.getInternalName(EventExecutor.class)}); // Generate constructor MethodVisitor methodGenerator = writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); methodGenerator.visitVarInsn(ALOAD, 0); methodGenerator.visitMethodInsn( INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); // Invoke the super class (Object) constructor methodGenerator.visitInsn(RETURN); methodGenerator.visitMaxs(1, 1); methodGenerator.visitEnd(); // Generate the execute method methodGenerator = writer.visitMethod( ACC_PUBLIC, "fire", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null); if (!staticMethod) { methodGenerator.visitVarInsn(ALOAD, 1); methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getDeclaringClass())); } methodGenerator.visitVarInsn(ALOAD, 2); methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getParameterTypes()[0])); methodGenerator.visitMethodInsn( staticMethod ? INVOKESTATIC : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface()); if (m.getReturnType() != void.class) { methodGenerator.visitInsn(POP); } methodGenerator.visitInsn(RETURN); methodGenerator.visitMaxs(staticMethod ? 1 : 2, 3); methodGenerator.visitEnd(); writer.visitEnd(); return writer.toByteArray(); }
public static void load(MethodVisitor mv, ClassNode type, int idx) { if (type == ClassHelper.double_TYPE) { mv.visitVarInsn(DLOAD, idx); } else if (type == ClassHelper.float_TYPE) { mv.visitVarInsn(FLOAD, idx); } else if (type == ClassHelper.long_TYPE) { mv.visitVarInsn(LLOAD, idx); } else if (type == ClassHelper.boolean_TYPE || type == ClassHelper.char_TYPE || type == ClassHelper.byte_TYPE || type == ClassHelper.int_TYPE || type == ClassHelper.short_TYPE) { mv.visitVarInsn(ILOAD, idx); } else { mv.visitVarInsn(ALOAD, idx); } }
public void inlineDeserialize( ThreadContext tc, STable st, MethodVisitor mv, String className, String prefix) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 3); mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "org/perl6/nqp/sixmodel/SerializationReader", "readDouble", "()D"); mv.visitFieldInsn(Opcodes.PUTFIELD, className, prefix, "D"); }
public byte[] dump() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit( V1_4, ACC_PUBLIC + ACC_SUPER + ACC_DEPRECATED, "pkg/Outer", null, "java/lang/Object", null); cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); cw.visitInnerClass("pkg/Outer$1", null, null, 0); fv = cw.visitField(ACC_PRIVATE + ACC_DEPRECATED, "i", "I", null, null); fv.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_DEPRECATED, "m", "()V", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "pkg/Outer$1"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer$1", "<init>", "(Lpkg/Outer;)V"); mv.visitInsn(POP); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "access$000", "(Lpkg/Outer;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer", "i", "I"); mv.visitInsn(IRETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
public void parse(MethodVisitor mw, int local, Map<String, Integer> variableNames) { // if (assign != null) { // context.set(assign, exps[0]); // } else { // writer.write(exps[0].toString()); // } if (getParameter(2) != null) { mw.visitVarInsn(ALOAD, CONTEXT); getParameter(2).parse(mw, local, variableNames); exp.parseObject(mw, local, variableNames); mw.visitMethodInsn( INVOKEVIRTUAL, Context.NAME, "set", "(Ljava/lang/String;Ljava/lang/Object;)V"); } else { mw.visitVarInsn(ALOAD, WRITER); exp.parseString(mw, local, variableNames); mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/Writer", "write", "(Ljava/lang/String;)V"); } }