private void injectCode(MethodInfo methodInfo) throws IOException { if (methodInfo.getCode() == null) { return; } InterceptorConstants interceptorConstants = getOrInsertInterceptorConstants(methodInfo.getInterceptorClass()); fixupSignature(methodInfo.getSignature()); Map<String, Integer> wrapperMethods = getOrInsertPrimitiveWrapperMethods(methodInfo.getSignature()); ByteArrayOutputStream codeToInject = new ByteArrayOutputStream(); InstructionsFacility instructionsFacility = new InstructionsFacility( new DataOutputStream(codeToInject), methodInfo.getSignature(), interceptorConstants, wrapperMethods); instructionsFacility.generateInterceptorInstantiationCode(); instructionsFacility.generateInterceptorMethodParametersCode(getObjectClassIndex()); instructionsFacility.generateObjectArrayFillingCode(); instructionsFacility.generateInterceptorInvocationCode( interceptorConstants.getInterceptorMethod()); Code code = methodInfo.getCode(); int originalStackSize = code.getMaxStack(); code.setMaxStack(Math.max(originalStackSize, instructionsFacility.getStackSizeNeeded())); code.setInjected(codeToInject.toByteArray()); code.refresh(); }
public void generate(ClassEmitter ce, Context context, List methods) { for (Iterator it = methods.iterator(); it.hasNext(); ) { MethodInfo method = (MethodInfo) it.next(); Signature impl = context.getImplSignature(method); ce.declare_field(Constants.PRIVATE_FINAL_STATIC, impl.getName(), METHOD, null); CodeEmitter e = context.beginMethod(ce, method); Block handler = e.begin_block(); context.emitCallback(e, context.getIndex(method)); e.load_this(); e.getfield(impl.getName()); e.create_arg_array(); e.invoke_interface(INVOCATION_HANDLER, INVOKE); e.unbox(method.getSignature().getReturnType()); e.return_value(); handler.end(); EmitUtils.wrap_undeclared_throwable( e, handler, method.getExceptionTypes(), UNDECLARED_THROWABLE_EXCEPTION); e.end_method(); } }
private void generateSet(final Class target, final Method[] setters) { // setPropertyValues CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null); if (setters.length > 0) { Local index = e.make_local(Type.INT_TYPE); e.push(0); e.store_local(index); e.load_arg(0); e.checkcast(Type.getType(target)); e.load_arg(1); Block handler = e.begin_block(); int lastIndex = 0; for (int i = 0; i < setters.length; i++) { if (setters[i] != null) { MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]); int diff = i - lastIndex; if (diff > 0) { e.iinc(index, diff); lastIndex = i; } e.dup2(); e.aaload(i); e.unbox(setter.getSignature().getArgumentTypes()[0]); e.invoke(setter); } } handler.end(); e.return_value(); e.catch_exception(handler, Constants.TYPE_THROWABLE); e.new_instance(BULK_BEAN_EXCEPTION); e.dup_x1(); e.swap(); e.load_local(index); e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION); e.athrow(); } else { e.return_value(); } e.end_method(); }
private void generateGet(final Class target, final Method[] getters) { CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null); if (getters.length >= 0) { e.load_arg(0); e.checkcast(Type.getType(target)); Local bean = e.make_local(); e.store_local(bean); for (int i = 0; i < getters.length; i++) { if (getters[i] != null) { MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); e.load_arg(1); e.push(i); e.load_local(bean); e.invoke(getter); e.box(getter.getSignature().getReturnType()); e.aastore(); } } } e.return_value(); e.end_method(); }
public static boolean isConstructor(final MethodInfo method) { return method.getSignature().getName().equals(Constants.CONSTRUCTOR_NAME); }
public void generateClass(ClassVisitor v) throws NoSuchMethodException { Method proxy = ReflectUtils.findInterfaceMethod(iface); final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes()); if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) { throw new IllegalArgumentException("incompatible return types"); } MethodInfo methodInfo = ReflectUtils.getMethodInfo(method); boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers()); if ((target == null) ^ isStatic) { throw new IllegalArgumentException( "Static method " + (isStatic ? "not " : "") + "expected"); } ClassEmitter ce = new ClassEmitter(v); CodeEmitter e; ce.begin_class( Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), METHOD_DELEGATE, new Type[] {Type.getType(iface)}, Constants.SOURCE_FILE); ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null); EmitUtils.null_constructor(ce); // generate proxied method MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]); int modifiers = Constants.ACC_PUBLIC; if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) { modifiers |= Constants.ACC_VARARGS; } e = EmitUtils.begin_method(ce, proxied, modifiers); e.load_this(); e.super_getfield("target", Constants.TYPE_OBJECT); e.checkcast(methodInfo.getClassInfo().getType()); e.load_args(); e.invoke(methodInfo); e.return_value(); e.end_method(); // newInstance e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null); e.new_instance_this(); e.dup(); e.dup2(); e.invoke_constructor_this(); e.getfield("eqMethod"); e.super_putfield("eqMethod", Constants.TYPE_STRING); e.load_arg(0); e.super_putfield("target", Constants.TYPE_OBJECT); e.return_value(); e.end_method(); // static initializer e = ce.begin_static(); e.push(methodInfo.getSignature().toString()); e.putfield("eqMethod"); e.return_value(); e.end_method(); ce.end_class(); }