public static void loadClass(MethodVisitor mv, int type, String typeName) { switch (type) { case 'V': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_VOID, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'B': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_BYTE, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'C': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_CHARACTER, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'S': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_SHORT, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'I': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_INTEGER, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'Z': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_BOOLEAN, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'J': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_LONG, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'F': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_FLOAT, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; case 'D': mv.visitFieldInsn( GETSTATIC, AsmUtil.SIGNATURE_JAVA_LANG_DOUBLE, "TYPE", AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); break; default: mv.visitLdcInsn(Type.getType(typeName)); break; } }
/** Invoked on INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE or INVOKEDYNAMIC. */ @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { // replace NEW.<init> if ((newInvokeReplacer != null) && (opcode == INVOKESPECIAL)) { String exOwner = owner; owner = newInvokeReplacer.getOwner(); name = newInvokeReplacer.getMethodName(); desc = changeReturnType(desc, 'L' + exOwner + ';'); super.visitMethodInsn(INVOKESTATIC, owner, name, desc); newInvokeReplacer = null; return; } InvokeInfo invokeInfo = new InvokeInfo(owner, name, desc); // [*] // creating FooClone.<init>; inside the FOO constructor // replace the very first invokespecial <init> call (SUB.<init>) // to targets subclass with target (FOO.<init>). if (methodInfo.getMethodName().equals(INIT)) { if ((firstSuperCtorInitCalled == false) && (opcode == INVOKESPECIAL) && name.equals(INIT) && owner.equals(wd.nextSupername)) { firstSuperCtorInitCalled = true; owner = wd.superReference; super.visitMethodInsn(opcode, owner, name, desc); return; } } // detection of super calls if ((opcode == INVOKESPECIAL) && (owner.equals(wd.nextSupername) && (name.equals(INIT) == false))) { throw new ProxettaException( "Super call detected in class " + methodInfo.getClassname() + " method: " + methodInfo.getSignature() + "\nProxetta can't handle super calls due to VM limitations."); } InvokeReplacer ir = null; // find first matching aspect for (InvokeAspect aspect : aspects) { ir = aspect.pointcut(invokeInfo); if (ir != null) { break; } } if (ir == null) { super.visitMethodInsn(opcode, owner, name, desc); return; } wd.proxyApplied = true; String exOwner = owner; owner = ir.getOwner(); name = ir.getMethodName(); switch (opcode) { case INVOKEINTERFACE: desc = prependArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT); break; case INVOKEVIRTUAL: desc = prependArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT); break; case INVOKESTATIC: break; default: throw new ProxettaException("Unsupported opcode: " + opcode); } // additional arguments if (ir.isPassOwnerName()) { desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING); super.visitLdcInsn(exOwner); } if (ir.isPassMethodName()) { desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING); super.visitLdcInsn(methodInfo.getMethodName()); } if (ir.isPassMethodSignature()) { desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING); super.visitLdcInsn(methodInfo.getSignature()); } if (ir.isPassTargetClass()) { desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS); super.mv.visitLdcInsn(Type.getType('L' + wd.superReference + ';')); } if (ir.isPassThis()) { desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT); super.mv.visitVarInsn(ALOAD, 0); } super.visitMethodInsn(INVOKESTATIC, owner, name, desc); }