private void writeNonAbstractMethodWrapper( ClassVisitor visitor, Type generatedType, Class<?> managedTypeClass, Method method) { Label start = new Label(); Label end = new Label(); Label handler = new Label(); MethodVisitor methodVisitor = declareMethod(visitor, method); methodVisitor.visitTryCatchBlock(start, end, handler, null); setCanCallSettersField(methodVisitor, generatedType, false); methodVisitor.visitLabel(start); invokeSuperMethod(methodVisitor, managedTypeClass, method); methodVisitor.visitLabel(end); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ARETURN); methodVisitor.visitLabel(handler); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ATHROW); methodVisitor.visitMaxs(0, 0); 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 appendGetDelayedCellSetter( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, ClassWriter cw, String targetType, String classType, int maxMethodSize) { MethodVisitor mv; mv = cw.visitMethod( ACC_PUBLIC, "getDelayedCellSetter", "(I)L" + DELAYED_CELL_SETTER_TYPE + ";", "(I)L" + DELAYED_CELL_SETTER_TYPE + "<L" + targetType + ";*>;", null); mv.visitCode(); if (delayedCellSetters.length != 0) { final int switchStart = 0; final int switchEnd = delayedCellSetters.length; appendGetDelayedCellSetterSwitch(delayedCellSetters, classType, mv, switchStart, switchEnd); } mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); mv.visitMaxs(1, 2); mv.visitEnd(); }
@Override public Object visitUnaryExpression(UnaryExpression unaryExpression, Object arg) throws Exception { MethodVisitor mv = ((InheritedAttributes) arg).mv; // this should be the Kind op = unaryExpression.op.kind; unaryExpression.expression.visit(this, arg); String type = unaryExpression.expression.expressionType; if (op.equals(Kind.MINUS)) { unaryExpression.setType(intType); mv.visitInsn(INEG); } else if (op.equals(Kind.NOT)) { unaryExpression.setType(booleanType); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitInsn(ICONST_0); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); mv.visitInsn(ICONST_1); mv.visitLabel(l2); } return unaryExpression.getType(); }
@Override public DataType visitAnd_test(@NotNull PythonParser.And_testContext ctx) { DataType type = visitNot_test(ctx.not_test(0)); if (!ctx.isEmpty() && ctx.not_test().size() > 1) { if (!type.isPrimitive()) { throw new CompileException(String.format("Doing and with %s is making no sense!", type)); } for (int i = 1; i < ctx.not_test().size(); i++) { visitNot_test(ctx.not_test(i)); Label falseLabel = new Label(); Label fastFalseLabel = new Label(); Label exitLabel = new Label(); mv.visitJumpInsn(IFEQ, fastFalseLabel); mv.visitJumpInsn(IFEQ, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, exitLabel); mv.visitLabel(fastFalseLabel); mv.visitInsn(POP); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(exitLabel); } return PrimitiveType.BOOLEAN; } return type; }
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); }
@Override public DataType visitArith_expr(@NotNull PythonParser.Arith_exprContext ctx) { DataType type = visitTerm(ctx.term(0)); int i = 1; if (!ctx.MINUS().isEmpty()) { if (!type.isPrimitive()) { throw new CompileException( String.format( "Doing %s with %s is making no sense!", ctx.MINUS().get(0).getText(), type)); } for (TerminalNode ignored : ctx.MINUS()) { type = visitTerm(ctx.term(i++)); mv.visitInsn(ISUB); } if (type.equals(PrimitiveType.BOOLEAN)) return PrimitiveType.INTEGER; } else if (!ctx.PLUS().isEmpty()) { if (!type.isPrimitive()) { throw new CompileException( String.format( "Doing %s with %s is making no sense!", ctx.PLUS().get(0).getText(), type)); } for (TerminalNode ignored : ctx.PLUS()) { type = visitTerm(ctx.term(i++)); mv.visitInsn(IADD); } if (type.equals(PrimitiveType.BOOLEAN)) return PrimitiveType.INTEGER; } return type; }
@Override public DataType visitFactor(@NotNull PythonParser.FactorContext ctx) { if (ctx.power() != null) { return visitPower(ctx.power()); } else if (ctx.factor() != null) { DataType type = visitFactor(ctx.factor()); if (type.isInteger()) { if (ctx.PLUS() != null) { return type; } else if (ctx.MINUS() != null) { mv.visitInsn(INEG); return type; } } else if (type.isBoolean()) { if (ctx.PLUS() != null) { return type; } else if (ctx.MINUS() != null) { mv.visitInsn(INEG); return PrimitiveType.INTEGER; } } else { if (ctx.PLUS() != null) { throw new CompileException( String.format("Doing %s with %s is making no sense!", ctx.PLUS().getText(), type)); } else if (ctx.MINUS() != null) { throw new CompileException( String.format("Doing %s with %s is making no sense!", ctx.MINUS().getText(), type)); } } } throw new CompileException( String.format( "Something gone wrong! Please write to [email protected] with example test.")); }
@Override public void emitStore(MethodVisitor mv, ExprGenerator valueGenerator) { arrayVar.load(mv); mv.visitInsn(Opcodes.ICONST_0); valueGenerator.emitPrimitiveValue(mv); mv.visitInsn(componentType.getOpcode(Opcodes.IASTORE)); }
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 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); }
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 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(); }
/** duplicate top element */ public void dup() { ClassNode type = getTopOperand(); stack.add(type); MethodVisitor mv = controller.getMethodVisitor(); if (type == ClassHelper.double_TYPE || type == ClassHelper.long_TYPE) { mv.visitInsn(DUP2); } else { mv.visitInsn(DUP); } }
/** negate a boolean on stack. true->false, false->true */ public static void negateBoolean(MethodVisitor mv) { // code to negate the primitive boolean Label endLabel = new Label(); Label falseLabel = new Label(); mv.visitJumpInsn(IFNE, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, endLabel); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(endLabel); }
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); }
/** Generates the bytecode that pushes the given value onto the stack */ public void pushLong(long aValue) { if (aValue == 0) { itsVisitor.visitInsn(Opcodes.LCONST_0); return; } else if (aValue == 1) { itsVisitor.visitInsn(Opcodes.LCONST_1); return; } itsVisitor.visitLdcInsn(new Long(aValue)); }
/** Generates the bytecode that pushes the given value onto the stack */ public void pushDouble(double aValue) { if (aValue == 0) { itsVisitor.visitInsn(Opcodes.DCONST_0); return; } else if (aValue == 1) { itsVisitor.visitInsn(Opcodes.DCONST_1); return; } itsVisitor.visitLdcInsn(new Double(aValue)); }
private void throwExceptionBecauseCalledOnItself(MethodVisitor methodVisitor) { String exceptionInternalName = Type.getInternalName(UnsupportedOperationException.class); methodVisitor.visitTypeInsn(NEW, exceptionInternalName); methodVisitor.visitInsn(DUP); putConstantOnStack(methodVisitor, "Calling setters of a managed type on itself is not allowed"); String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, STRING_TYPE); methodVisitor.visitMethodInsn( INVOKESPECIAL, exceptionInternalName, CONSTRUCTOR_NAME, constructorDescriptor, false); methodVisitor.visitInsn(ATHROW); }
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()); }
public void popDownTo(int elements) { int last = stack.size(); MethodVisitor mv = controller.getMethodVisitor(); while (last > elements) { last--; ClassNode element = popWithMessage(last); if (isTwoSlotType(element)) { mv.visitInsn(POP2); } else { mv.visitInsn(POP); } } }
private void buildObjectAccessor(ClassWriter cw, Class cls) { MethodVisitor mv; if (fDebugEn) { debug("--> buildAccessor cls=" + cls.getName()); } // Constructor String tgt_clsname = getClassName(cls); String cls_name = getClassLeafName(cls); // Read method // // 0 - this // 1 - parent // 2 - object mv = cw.visitMethod( ACC_PRIVATE, "read" + cls_name, "(L" + fChildItem + ";" + "L" + tgt_clsname + ";)V", null, new String[] {fDBFormatException}); mv.visitCode(); visit(false, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); // Write method // // 0 - this // 1 - object mv = cw.visitMethod( ACC_PRIVATE, "write" + cls_name, // "(L" + tgt_clsname + ";)V", "(L" + tgt_clsname + ";)V", null, new String[] {fDBWriteException}); mv.visitCode(); visit(true, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); if (fDebugEn) { debug("<-- buildAccessor cls=" + cls.getName()); } }
/** 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; }
private void unwrapResult(final MethodVisitor mv, final String desc) { Type returnType = Type.getReturnType(desc); if (returnType == Type.VOID_TYPE) { mv.visitInsn(POP); mv.visitInsn(RETURN); } else { if (isPrimitive(returnType)) { BytecodeHelper.unbox(mv, ClassHelper.make(returnType.getClassName())); } else { mv.visitTypeInsn(CHECKCAST, returnType.getInternalName()); } mv.visitInsn(getReturnInsn(returnType)); } }
/** Generates the bytecode that pushes the given value onto the stack */ public void pushFloat(float aValue) { if (aValue == 0) { itsVisitor.visitInsn(Opcodes.FCONST_0); return; } else if (aValue == 1) { itsVisitor.visitInsn(Opcodes.FCONST_1); return; } else if (aValue == 2) { itsVisitor.visitInsn(Opcodes.FCONST_2); return; } itsVisitor.visitLdcInsn(new Float(aValue)); }
/** * convert primitive (not boolean) to boolean or byte. type needs to be a primitive type (not * checked) */ private void primitive2b(MethodVisitor mv, ClassNode type) { Label trueLabel = new Label(); Label falseLabel = new Label(); // for the various types we make first a // kind of conversion to int using a compare // operation and then handle the result common // for all cases. In case of long that is LCMP, // for int nothing is to be done if (type == ClassHelper.double_TYPE) { mv.visitInsn(DCONST_0); mv.visitInsn(DCMPL); } else if (type == ClassHelper.long_TYPE) { mv.visitInsn(LCONST_0); mv.visitInsn(LCMP); } else if (type == ClassHelper.float_TYPE) { mv.visitInsn(FCONST_0); mv.visitInsn(FCMPL); } else if (type == ClassHelper.int_TYPE) { // nothing, see comment above } mv.visitJumpInsn(IFEQ, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, trueLabel); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(trueLabel); // other cases can be used directly }
void compile(MethodVisitor mv) { // compiles e1 e1.compile(mv); // tests if e1 is true mv.visitInsn(DUP); Label end = new Label(); mv.visitJumpInsn(IFNE, end); // case where e1 is false : e1 || e2 is equal to e2 mv.visitInsn(POP); e2.compile(mv); // if e1 is true, e1 || e2 is equal to e1: // we jump directly to this label, without evaluating e2 mv.visitLabel(end); }
/** {@inheritDoc} */ @Override public void visitInsn(int opcode) { if (opcode == Opcodes.ATHROW) { super.visitInsn(Opcodes.DUP); this.visitLdcInsn(className); this.visitLdcInsn(methodName); mv.visitMethodInsn( Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(ExecutionTracer.class), "exceptionThrown", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", false); } super.visitInsn(opcode); }
public void visitConstructor(ConstructorNode node) { visitParameters(node, node.getParameters()); String methodType = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, node.getParameters()); mv = cv.visitMethod(node.getModifiers(), "<init>", methodType, null, null); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitLdcInsn("not intended for execution"); mv.visitMethodInsn( INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitMaxs(0, 0); }