.getArgumentTypes());
//
// construct the proxy method
//
GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null,
ex, cw);
ga.loadThis();
ga.getField(selfType, INVOCATION_HANDLER_FIELD_NAME,
INVOCATION_HANDLER_TYPE);
// if the method is extending something, then we have
// to test if the handler is initialized...
if (md.isImplemented()) {
ga.dup();
Label ok = ga.newLabel();
ga.ifNonNull(ok);
ga.loadThis();
ga.loadArgs();
ga.invokeConstructor(superType, m);
ga.returnValue();
ga.mark(ok);
}
ga.loadThis();
ga.getStatic(selfType, field_name, PROXY_METHOD_TYPE);
if (m.getArgumentTypes().length == 0) {
// load static empty array
ga.getStatic(JAVA_PROXY_TYPE, "NO_ARGS", Type
.getType(Object[].class));
} else {
// box arguments
ga.loadArgArray();
}
Label before = ga.mark();
ga.invokeInterface(INVOCATION_HANDLER_TYPE,
INVOCATION_HANDLER_INVOKE_METHOD);
Label after = ga.mark();
ga.unbox(m.getReturnType());
ga.returnValue();
// this is a simple rethrow handler
Label rethrow = ga.mark();
ga.visitInsn(Opcodes.ATHROW);
for (int i = 0; i < ex.length; i++) {
ga.visitTryCatchBlock(before, after, rethrow, ex[i]
.getInternalName());
}
ga.visitTryCatchBlock(before, after, rethrow, "java/lang/Error");
ga.visitTryCatchBlock(before, after, rethrow,
"java/lang/RuntimeException");
Type thr = Type.getType(Throwable.class);
Label handler = ga.mark();
Type udt = Type.getType(UndeclaredThrowableException.class);
int loc = ga.newLocal(thr);
ga.storeLocal(loc, thr);
ga.newInstance(udt);
ga.dup();
ga.loadLocal(loc, thr);
ga.invokeConstructor(udt, org.objectweb.asm.commons.Method
.getMethod("void <init>(java.lang.Throwable)"));
ga.throwException();
ga.visitTryCatchBlock(before, after, handler, "java/lang/Throwable");
ga.endMethod();
//
// construct the super-proxy method
//
if (md.isImplemented()) {
GeneratorAdapter ga2 = new GeneratorAdapter(Opcodes.ACC_PUBLIC, sm,
null, ex, cw);
ga2.loadThis();
ga2.loadArgs();
ga2.invokeConstructor(superType, m);
ga2.returnValue();
ga2.endMethod();
}
}