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(); }
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(); }
protected void injectReflectiveSetter(MethodVisitor methodVisitor) { methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitFieldInsn( GETFIELD, getAccessorNameInternal(this.getTarget(), this.getAccessorType()), "fieldTable", "[Ljava/lang/reflect/Field;"); methodVisitor.visitVarInsn(ILOAD, 2); methodVisitor.visitInsn(AALOAD); methodVisitor.visitVarInsn(ASTORE, 4); methodVisitor.visitVarInsn(ALOAD, 4); methodVisitor.visitInsn(ICONST_1); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/reflect/Field", "setAccessible", "(Z)V", false); methodVisitor.visitVarInsn(ALOAD, 4); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitVarInsn(ALOAD, 3); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, "java/lang/reflect/Field", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", false); methodVisitor.visitInsn(RETURN); }
@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 static mixin field. * * @param mv * @param fieldInfo */ private void initializeStaticMixinField(final MethodVisitor mv, final MixinFieldInfo fieldInfo) { mv.visitLdcInsn(fieldInfo.mixinClassInfo.getName().replace('/', '.')); if (fieldInfo.isPerJVM) { mv.visitFieldInsn( GETSTATIC, m_declaringTypeName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE); mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_CLASS, GETCLASSLOADER_METHOD_NAME, CLASS_CLASS_GETCLASSLOADER_METHOD_SIGNATURE); mv.visitMethodInsn( INVOKESTATIC, MIXINS_CLASS_NAME, MIXIN_OF_METHOD_NAME, MIXIN_OF_METHOD_PER_JVM_SIGNATURE); } else { mv.visitFieldInsn( GETSTATIC, m_declaringTypeName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE); mv.visitMethodInsn( INVOKESTATIC, MIXINS_CLASS_NAME, MIXIN_OF_METHOD_NAME, MIXIN_OF_METHOD_PER_CLASS_SIGNATURE); } mv.visitTypeInsn(CHECKCAST, fieldInfo.mixinClassInfo.getName().replace('.', '/')); mv.visitFieldInsn( PUTSTATIC, m_declaringTypeName, fieldInfo.fieldName, fieldInfo.mixinClassInfo.getSignature()); }
@Override public Object visitPrintStatement(PrintStatement printStatement, Object arg) throws Exception { MethodVisitor mv = ((InheritedAttributes) arg).mv; Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(printStatement.firstToken.getLineNumber(), l0); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); printStatement.expression.visit(this, arg); // adds code to leave value // of expression on top of // stack. // Unless there is a good // reason to do otherwise, // pass arg down the tree String etype = printStatement.expression.getType(); if (etype.equals("I") || etype.equals("Z") || etype.equals("Ljava/lang/String;")) { String desc = "(" + etype + ")V"; mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", desc, false); } else { // mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "toString", // "()Ljava/lang/String;",false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false); } return null; }
@Override public Object visitListOrMapElemExpression( ListOrMapElemExpression listOrMapElemExpression, Object arg) throws Exception { MethodVisitor mv = ((InheritedAttributes) arg).mv; mv.visitFieldInsn( GETSTATIC, className, listOrMapElemExpression.identToken.getText(), emptyList); listOrMapElemExpression.expression.visit(this, arg); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); if (listOrMapElemExpression.expressionType.equalsIgnoreCase(intType)) { mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); } else if (listOrMapElemExpression.expressionType.equalsIgnoreCase(booleanType)) { mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); } else if (listOrMapElemExpression.expressionType.equalsIgnoreCase(stringType)) mv.visitTypeInsn(CHECKCAST, "java/lang/String"); else if (listOrMapElemExpression.expressionType.startsWith("Ljava/util/List<Ljava/util/List")) { mv.visitTypeInsn(CHECKCAST, "java/util/ArrayList"); listOrMapElemExpression.setType(emptyList); // mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer","intValue","()I",false); return "Ljava/util/ArrayList;"; } // mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer","intValue","()I",false); return listOrMapElemExpression.getType(); }
@Override public Object visitExpressionLValue(ExpressionLValue expressionLValue, Object arg) throws Exception { MethodVisitor mv = ((InheritedAttributes) arg).mv; if (expressionLValue.getType().equalsIgnoreCase("Ljava/util/List<I>;")) { mv.visitFieldInsn( GETSTATIC, className, expressionLValue.identToken.getText(), expressionLValue.getType()); expressionLValue.expression.visit(this, arg); // mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", // "(I)Ljava/lang/Integer;",false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); Label l1 = new Label(); mv.visitInsn(DUP); mv.visitJumpInsn(IFNONNULL, l1); mv.visitInsn(POP); mv.visitTypeInsn(NEW, "java/util/ArrayList"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false); mv.visitLabel(l1); mv.visitTypeInsn(CHECKCAST, "java/util/ArrayList"); mv.visitInsn(POP); } return null; }
private void writeGroovyMethods(ClassVisitor visitor, Class<?> managedTypeClass) { // Object propertyMissing(String name) MethodVisitor methodVisitor = declareMethod( visitor, "propertyMissing", GET_PROPERTY_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingPropertyException(name, <managed-type>.class) methodVisitor.visitTypeInsn(NEW, MISSING_PROPERTY_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putFirstMethodArgumentOnStack(methodVisitor); putClassOnStack(methodVisitor, managedTypeClass); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_PROPERTY_EXCEPTION_TYPE, "<init>", MISSING_PROPERTY_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); // Object propertyMissing(String name, Object value) methodVisitor = declareMethod( visitor, "propertyMissing", SET_PROPERTY_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingPropertyException(name, <managed-type>.class) methodVisitor.visitTypeInsn(NEW, MISSING_PROPERTY_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putFirstMethodArgumentOnStack(methodVisitor); putClassOnStack(methodVisitor, managedTypeClass); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_PROPERTY_EXCEPTION_TYPE, "<init>", MISSING_PROPERTY_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); // Object methodMissing(String name, Object args) methodVisitor = declareMethod( visitor, "methodMissing", METHOD_MISSING_METHOD_DESCRIPTOR, CONCRETE_SIGNATURE); // throw new MissingMethodException(name, <managed-type>.class, args) methodVisitor.visitTypeInsn(NEW, MISSING_METHOD_EXCEPTION_TYPE); methodVisitor.visitInsn(DUP); putMethodArgumentOnStack(methodVisitor, 1); putClassOnStack(methodVisitor, managedTypeClass); putMethodArgumentOnStack(methodVisitor, 2); methodVisitor.visitTypeInsn(CHECKCAST, OBJECT_ARRAY_TYPE); methodVisitor.visitMethodInsn( INVOKESPECIAL, MISSING_METHOD_EXCEPTION_TYPE, "<init>", MISSING_METHOD_EXCEPTION_CONSTRUCTOR_DESCRIPTOR, false); finishVisitingMethod(methodVisitor, ATHROW); }
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(); }
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); } }
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()); }
// the overload of type Object for Groovy coercions: public void setFoo(Object foo) private void createTypeConvertingSetter( ClassVisitor visitor, Type generatedType, ModelProperty<?> property) { if (!property.isWritable() || !(property.getSchema() instanceof ScalarValueSchema)) { return; } Class<?> propertyClass = property.getType().getConcreteClass(); Type propertyType = Type.getType(propertyClass); Class<?> boxedClass = propertyClass.isPrimitive() ? BOXED_TYPES.get(propertyClass) : propertyClass; Type boxedType = Type.getType(boxedClass); Method setter = property.getSetter().getMethod(); MethodVisitor methodVisitor = declareMethod( visitor, setter.getName(), SET_OBJECT_PROPERTY_DESCRIPTOR, SET_OBJECT_PROPERTY_DESCRIPTOR); putThisOnStack(methodVisitor); putTypeConverterFieldValueOnStack(methodVisitor, generatedType); // Object converted = $typeConverter.convert(foo, Float.class, false); methodVisitor.visitVarInsn(ALOAD, 1); // put var #1 ('foo') on the stack methodVisitor.visitLdcInsn(boxedType); // push the constant Class onto the stack methodVisitor.visitInsn( propertyClass.isPrimitive() ? ICONST_1 : ICONST_0); // push int 1 or 0 (interpreted as true or false) onto the stack methodVisitor.visitMethodInsn( INVOKEINTERFACE, TYPE_CONVERTER_TYPE.getInternalName(), "convert", COERCE_TO_SCALAR_DESCRIPTOR, true); methodVisitor.visitTypeInsn(CHECKCAST, boxedType.getInternalName()); if (propertyClass.isPrimitive()) { unboxType(methodVisitor, propertyClass); } // invoke the typed setter, popping 'this' and 'converted' from the stack methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, propertyType), false); finishVisitingMethod(methodVisitor); }
/** 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; }
/** * Insert the necessary methods to unbox a primitive type (if the given type is a primitive). * * @param mv The method visitor * @param type The type to unbox */ public static void visitUnboxingMethod(MethodVisitor mv, Type type) { if (type.getSort() == Type.BOOLEAN) { mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); } else if (type.getSort() == Type.INT) { mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); } else if (type.getSort() == Type.BYTE) { mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); } else if (type.getSort() == Type.SHORT) { mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); } else if (type.getSort() == Type.LONG) { mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); } else if (type.getSort() == Type.FLOAT) { mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); } else if (type.getSort() == Type.DOUBLE) { mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); } else if (type.getSort() == Type.CHAR) { mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); } else { mv.visitTypeInsn(CHECKCAST, type.getInternalName()); } }
private void writePowerCall( Expression receiver, Expression arguments, final ClassNode rType, ClassNode aType) { OperandStack operandStack = controller.getOperandStack(); int m1 = operandStack.getStackLength(); // slow Path prepareSiteAndReceiver(receiver, "power", false, controller.getCompileStack().isLHS()); operandStack.doGroovyCast(getWrapper(rType)); visitBoxedArgument(arguments); operandStack.doGroovyCast(getWrapper(aType)); int m2 = operandStack.getStackLength(); MethodVisitor mv = controller.getMethodVisitor(); if (BigDecimal_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) { mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigDecimal;Ljava/lang/Integer;)Ljava/lang/Number;", false); } else if (BigInteger_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) { mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigInteger;Ljava/lang/Integer;)Ljava/lang/Number;", false); } else if (Long_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) { mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Long;Ljava/lang/Integer;)Ljava/lang/Number;", false); } else if (Integer_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) { mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Number;", false); } else { mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false); } controller.getOperandStack().replace(Number_TYPE, m2 - m1); }
private void writeHashCodeMethod(ClassVisitor visitor, Type generatedType) { MethodVisitor methodVisitor = declareMethod(visitor, "hashCode", HASH_CODE_METHOD_DESCRIPTOR, null); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, generatedType.getInternalName(), "getBackingNode", GET_BACKING_NODE_METHOD_DESCRIPTOR, false); methodVisitor.visitMethodInsn( INVOKEINTERFACE, MUTABLE_MODEL_NODE_TYPE, "hashCode", HASH_CODE_METHOD_DESCRIPTOR, true); methodVisitor.visitInsn(IRETURN); finishVisitingMethod(methodVisitor, Opcodes.IRETURN); }
@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); }
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(); }
private void writeMapDotProperty( final Expression receiver, final String methodName, final MethodVisitor mv, final boolean safe) { receiver.visit(controller.getAcg()); // load receiver Label exit = new Label(); if (safe) { Label doGet = new Label(); mv.visitJumpInsn(IFNONNULL, doGet); controller.getOperandStack().remove(1); mv.visitInsn(ACONST_NULL); mv.visitJumpInsn(GOTO, exit); mv.visitLabel(doGet); receiver.visit(controller.getAcg()); } mv.visitLdcInsn(methodName); // load property name mv.visitMethodInsn( INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); if (safe) { mv.visitLabel(exit); } controller.getOperandStack().replace(OBJECT_TYPE); }
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 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 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 storeVar(BytecodeVariable variable) { MethodVisitor mv = controller.getMethodVisitor(); int idx = variable.getIndex(); ClassNode type = variable.getType(); // value is on stack if (variable.isHolder()) { doGroovyCast(type); box(); mv.visitVarInsn(ALOAD, idx); mv.visitTypeInsn(CHECKCAST, "groovy/lang/Reference"); mv.visitInsn(SWAP); mv.visitMethodInsn( INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false); } else { doGroovyCast(type); if (type == ClassHelper.double_TYPE) { mv.visitVarInsn(DSTORE, idx); } else if (type == ClassHelper.float_TYPE) { mv.visitVarInsn(FSTORE, idx); } else if (type == ClassHelper.long_TYPE) { mv.visitVarInsn(LSTORE, 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(ISTORE, idx); } else { mv.visitVarInsn(ASTORE, idx); } } // remove RHS value from operand stack remove(1); }
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; }
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { _touchBranch(); super.visitMethodInsn(opcode, owner, name, desc, itf); }
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 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); }
/** {@inheritDoc} */ @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { if (opcode == Opcodes.INVOKESPECIAL) { if (methodName.equals("<init>")) hadInvokeSpecial = true; } super.visitMethodInsn(opcode, owner, name, desc, itf); }
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(); } }