private Instruction createInvokeInstruction(Element inst, short kind) throws IllegalXMLVMException { String classType = inst.getAttributeValue("class-type"); String methodName = inst.getAttributeValue("method"); Element signature = inst.getChild("signature", nsXMLVM); Type retType = collectReturnType(signature); Type[] argTypes = collectArgumentTypes(signature); return _factory.createInvoke(classType, methodName, retType, argTypes, kind); }
private void generateInvokeEntryPoint( GenScope scope, InstructionList il, InstructionFactory ifact, String transformationName, String entryPointName, LocalVariableGen lvg) { // Configure the transformation il.append(InstructionFactory.DUP); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "configure_", Type.VOID, new Type[] {}, Constants.INVOKEVIRTUAL)); // TODO: Configure the models properly, not as I'm doing directly in instantiateTransformation // directly // Put the params into the stack and invoke, but first check the type of the transformation // object ObjectType transformationType = new ObjectType(transformationName); il.append(ifact.createCheckCast(transformationType)); // [Transformation, param1, ..., paramN] EList<Variable> params = this.getEntryPointParameters(); Type[] types = new Type[params.size()]; int i = 0; for (Variable variable : params) { scope.loadVariable(variable, il); types[i++] = Type.OBJECT; } il.append( ifact.createInvoke( transformationType.getClassName(), entryPointName, Type.OBJECT, types, Constants.INVOKEVIRTUAL)); il.append(new ASTORE(lvg.getIndex())); }
private Method generateSuperAccessor( ConstantPoolGen cpg, String className, SuperMethodDescriptor superMethod, InstructionFactory factory) { int endPos = superMethod.signature.indexOf(')'); String segment = superMethod.signature.substring(1, endPos); String[] typeNames = (segment.length() > 0) ? segment.split(",") : new String[0]; Type[] argTypes = new Type[typeNames.length]; for (int i = 0; i < argTypes.length; i++) argTypes[i] = Type.getType(typeNames[i]); int index = superMethod.signature.lastIndexOf(')') + 1; Type returnType = Type.getType(superMethod.signature.substring(index)); Type baseType = new ObjectType(className); Type[] wrapperTypes = new Type[argTypes.length + 1]; System.arraycopy(argTypes, 0, wrapperTypes, 1, argTypes.length); wrapperTypes[0] = baseType; String[] argNames = new String[wrapperTypes.length]; for (int i = 0; i < argNames.length; i++) { argNames[i] = "arg" + i; } InstructionList il = new InstructionList(); MethodGen mg = new MethodGen( (Constants.ACC_PUBLIC | Constants.ACC_STATIC), returnType, wrapperTypes, argNames, OT_PREFIX + superMethod.methodName + "$super", className, il, cpg); il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is base instance for (int i = 0; i < argTypes.length; i++) il.append(InstructionFactory.createLoad(argTypes[i], i + 1)); // if super method is also callin bound directly invoke the orig-version // (to avoid that BaseMethodTransformation.checkReplaceWickedSuper() has to rewrite this code // again): String methodName = (CallinBindingManager.isBoundBaseMethod( superMethod.superClass, superMethod.methodName, superMethod.signature)) ? genOrigMethName(superMethod.methodName) : superMethod.methodName; il.append( factory.createInvoke( superMethod.superClass, methodName, returnType, argTypes, INVOKESPECIAL)); il.append(InstructionFactory.createReturn(returnType)); mg.setMaxStack(); mg.setMaxLocals(); return mg.getMethod(); }
/** * Transforms the init method to create the newly added join point member field. * * @param cp the ConstantPoolGen * @param cg the ClassGen * @param init the constructor for the class * @param method the current method * @param factory the objectfactory * @param methodSequence the methods sequence number * @return the modified constructor */ private MethodGen createJoinPointField( final ConstantPoolGen cp, final ClassGen cg, final Method init, final Method method, final InstructionFactory factory, final int methodSequence) { final MethodGen mg = new MethodGen(init, cg.getClassName(), cp); final InstructionList il = mg.getInstructionList(); final InstructionHandle[] ihs = il.getInstructionHandles(); // grab the handle to the the return instruction of the constructor InstructionHandle ih = ihs[0]; for (int i = 0; i < ihs.length; i++) { Instruction instruction = ihs[i].getInstruction(); if (instruction instanceof ReturnInstruction) { ih = ihs[i]; // set the instruction handle to the return instruction break; } } final String joinPoint = getJoinPointName(method, methodSequence); final InstructionHandle ihPost; ihPost = il.insert(ih, factory.createLoad(Type.OBJECT, 0)); il.insert(ih, factory.createNew(TransformationUtil.THREAD_LOCAL_CLASS)); il.insert(ih, InstructionConstants.DUP); il.insert( ih, factory.createInvoke( TransformationUtil.THREAD_LOCAL_CLASS, "<init>", Type.VOID, new Type[] {}, Constants.INVOKESPECIAL)); il.insert( ih, factory.createFieldAccess( cg.getClassName(), joinPoint, new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.PUTFIELD)); il.redirectBranches(ih, ihPost); mg.setMaxStack(); mg.setMaxLocals(); return mg; }
private void createMethod_0() { InstructionList il = new InstructionList(); MethodGen method = new MethodGen( ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", objectType, il, _cp); InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0)); il.append( _factory.createInvoke( "java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID)); method.setMaxStack(); method.setMaxLocals(); _cg.addMethod(method.getMethod()); il.dispose(); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); String transformationName = this.getTransformationName(); String entryPointName = this.getEntryPointName(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // Probably this could be improved, but for the moment a transformation // object will provide a facility to instantiate another transformation // Create the new transformation // [This_Transformation, "TransformationName"] -> instantiateTransformation -> // [Created_Transformation] scope.generateGetTransformation(); il.append(ifact.createConstant(transformationName)); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "instantiateTransformation", DefaultTypes.IdcTransformation, new Type[] {Type.STRING}, Constants.INVOKEVIRTUAL)); // There are two cases // // 1. Explicit invocation of a transformation rule if (entryPointName != null) { generateInvokeEntryPoint(scope, il, ifact, transformationName, entryPointName, lvg); } else { generateInvokeTransformation(scope, il, ifact, transformationName, lvg); } }
private static void addTimer(ClassGen cgen, Method method) { // set up the construction tools InstructionFactory ifact = new InstructionFactory(cgen); InstructionList ilist = new InstructionList(); ConstantPoolGen pgen = cgen.getConstantPool(); String cname = cgen.getClassName(); MethodGen wrapgen = new MethodGen(method, cname, pgen); wrapgen.setInstructionList(ilist); // rename a copy of the original method MethodGen methgen = new MethodGen(method, cname, pgen); cgen.removeMethod(method); String iname = methgen.getName() + "_timing"; methgen.setName(iname); cgen.addMethod(methgen.getMethod()); Type result = methgen.getReturnType(); // compute the size of the calling parameters Type[] parameters = methgen.getArgumentTypes(); int stackIndex = methgen.isStatic() ? 0 : 1; for (int i = 0; i < parameters.length; i++) { stackIndex += parameters[i].getSize(); } // save time prior to invocation ilist.append( ifact.createInvoke( "java.lang.System", "currentTimeMillis", Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC)); ilist.append(InstructionFactory.createStore(Type.LONG, stackIndex)); // call the wrapped method int offset = 0; short invoke = Constants.INVOKESTATIC; if (!methgen.isStatic()) { ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0)); offset = 1; invoke = Constants.INVOKEVIRTUAL; } for (int i = 0; i < parameters.length; i++) { Type type = parameters[i]; ilist.append(InstructionFactory.createLoad(type, offset)); offset += type.getSize(); } ilist.append(ifact.createInvoke(cname, iname, result, parameters, invoke)); // store result for return later if (result != Type.VOID) { ilist.append(InstructionFactory.createStore(result, stackIndex + 2)); } // print time required for method call ilist.append( ifact.createFieldAccess( "java.lang.System", "out", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC)); ilist.append(InstructionConstants.DUP); ilist.append(InstructionConstants.DUP); String text = "Call to method " + methgen.getName() + " took "; ilist.append(new PUSH(pgen, text)); ilist.append( ifact.createInvoke( "java.io.PrintStream", "print", Type.VOID, new Type[] {Type.STRING}, Constants.INVOKEVIRTUAL)); ilist.append( ifact.createInvoke( "java.lang.System", "currentTimeMillis", Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC)); ilist.append(InstructionFactory.createLoad(Type.LONG, stackIndex)); ilist.append(InstructionConstants.LSUB); ilist.append( ifact.createInvoke( "java.io.PrintStream", "print", Type.VOID, new Type[] {Type.LONG}, Constants.INVOKEVIRTUAL)); ilist.append(new PUSH(pgen, " ms.")); ilist.append( ifact.createInvoke( "java.io.PrintStream", "println", Type.VOID, new Type[] {Type.STRING}, Constants.INVOKEVIRTUAL)); // return result from wrapped method call if (result != Type.VOID) { ilist.append(InstructionFactory.createLoad(result, stackIndex + 2)); } ilist.append(InstructionFactory.createReturn(result)); // finalize the constructed method wrapgen.stripAttributes(true); wrapgen.setMaxStack(); wrapgen.setMaxLocals(); cgen.addMethod(wrapgen.getMethod()); ilist.dispose(); }
/** * Transforms invoke instructions that match the specified list for this class to call the * specified static call instead. */ private InstructionList xform_inst(MethodGen mg, Instruction inst) { switch (inst.getOpcode()) { case Constants.INVOKESTATIC: { InstructionList il = new InstructionList(); INVOKESTATIC is = (INVOKESTATIC) inst; String cname = is.getClassName(pgen); String mname = is.getMethodName(pgen); Type[] args = is.getArgumentTypes(pgen); MethodDef orig = new MethodDef(cname + "." + mname, args); MethodInfo call = method_map.get(orig); if (call != null) { call.cnt++; String classname = call.method_class; String methodname = mname; debug_map.log( "%s.%s: Replacing method %s.%s (%s) with %s.%s%n", mg.getClassName(), mg.getName(), cname, mname, UtilMDE.join(args, ", "), classname, methodname); il.append( ifact.createInvoke( classname, methodname, is.getReturnType(pgen), args, Constants.INVOKESTATIC)); } return (il); } case Constants.INVOKEVIRTUAL: { InstructionList il = new InstructionList(); INVOKEVIRTUAL iv = (INVOKEVIRTUAL) inst; String cname = iv.getClassName(pgen); String mname = iv.getMethodName(pgen); Type[] args = iv.getArgumentTypes(pgen); Type instance_type = iv.getReferenceType(pgen); Type[] new_args = BCELUtil.insert_type(instance_type, args); MethodDef orig = new MethodDef(cname + "." + mname, args); if (debug_class) System.out.printf("looking for %s in map %s%n", orig, method_map); MethodInfo call = method_map.get(orig); if (call != null) { call.cnt++; String classname = call.method_class; String methodname = mname; debug_map.log( "Replacing method %s.%s (%s) with %s.%s%n", cname, mname, ArraysMDE.toString(args), classname, methodname); il.append( ifact.createInvoke( classname, methodname, iv.getReturnType(pgen), new_args, Constants.INVOKESTATIC)); } return (il); } default: return (null); } }
private void generateInvokeTransformation( GenScope scope, InstructionList il, InstructionFactory ifact, String transformationName, LocalVariableGen lvg) { il.append(InstructionFactory.DUP); il.append(InstructionFactory.DUP); il.append(InstructionFactory.DUP); // Configure the invoked transformation: view filter scope.loadVariable(this.getInputViewFilter(), il); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "configure_invocation_", Type.VOID, new Type[] {DefaultTypes.RunnableClosure}, Constants.INVOKEVIRTUAL)); // Configure the transformation il.append(InstructionFactory.DUP); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "configure_", Type.VOID, new Type[] {}, Constants.INVOKEVIRTUAL)); // Set parameters for (NamedInvocationParameter p : this.getParameters()) { il.append(InstructionFactory.DUP); il.append(ifact.createConstant(p.getFormalName())); scope.loadVariable(p.getResult(), il); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "setParameterValue", Type.VOID, new Type[] {Type.STRING, Type.OBJECT}, Constants.INVOKEVIRTUAL)); } // Start the transformation il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "start_", Type.VOID, new Type[] {}, Constants.INVOKEVIRTUAL)); // Get a target element from a trace if (this.getOutputResolutionSourceElement() != null) { scope.loadVariable(this.getOutputResolutionSourceElement(), il); il.append(ifact.createConstant(this.getQueueName())); il.append(ifact.createConstant(this.getSrcTraceAttributeName())); il.append(ifact.createConstant(this.getTgtTraceAttributeName())); il.append( ifact.createInvoke( DefaultTypes.IdcTransformation.getClassName(), "retrieve_from_invocation_", Type.OBJECT, new Type[] {Type.OBJECT, Type.STRING, Type.STRING, Type.STRING}, Constants.INVOKEVIRTUAL)); } else { il.append(InstructionFactory.ACONST_NULL); } il.append(new ASTORE(lvg.getIndex())); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // TODO: I'm going to assume that there is an optional kindOf and // and p() predicate. if (this.getPredicates().size() > 2) throw new UnsupportedOperationException("QMatchJVMGen. Only 2 fixed predicates implemented."); KindOfPredicate kindOf = null; PropertyEqualsPredicate prop = null; if (getPredicates().get(0) instanceof KindOfPredicate) { kindOf = (KindOfPredicate) getPredicates().get(0); prop = (PropertyEqualsPredicate) getPredicates().get(1); } else { prop = (PropertyEqualsPredicate) getPredicates().get(0); } // Create the object, then the parameters of the constructor String requestClass = "org.eclectic.idc.jvm.runtime.RequestKindProperty"; il.append(ifact.createNew(requestClass)); il.append(InstructionConstants.DUP); scope.generateGetModelManager(); if (kindOf == null) { il.append(InstructionConstants.ACONST_NULL); } else { ReadMetaJVMGen readMeta = new ReadMetaJVMGen(); readMeta.setClassName(kindOf.getClassName()); readMeta.setModel(kindOf.getModel()); readMeta.setName("_readMeta_for" + getName()); readMeta.setFile(this.getFile()); readMeta.setColumn(this.getColumn()); readMeta.setRow(this.getRow()); readMeta.generate(scope); scope.loadVariable(readMeta, il); } il.append(ifact.createConstant(prop.getPropertyName())); scope.loadVariable(prop.getValue(), il); // In the stack: IdcMetaclass, featureName, value + receptor x 2 il.append( ifact.createInvoke( requestClass, "<init>", Type.VOID, new Type[] { DefaultTypes.ModelManager, DefaultTypes.IdcMetaclass, Type.STRING, Type.OBJECT }, Constants.INVOKESPECIAL)); if (getGetterClosure() != null) { il.append(InstructionConstants.DUP); scope.loadVariable(getGetterClosure(), il); il.append( ifact.createInvoke( requestClass, "setGetterClosure", Type.VOID, new Type[] {DefaultTypes.IClosure}, Constants.INVOKEVIRTUAL)); } // Generate debug info il.append(InstructionConstants.DUP); if (getFile() == null) { il.append(InstructionConstants.ACONST_NULL); } else { il.append(ifact.createConstant(getFile())); } il.append(ifact.createConstant(getRow())); il.append(ifact.createConstant(getColumn())); il.append( ifact.createInvoke( requestClass, "setDebugInfo", Type.VOID, new Type[] {Type.STRING, Type.INT, Type.INT}, Constants.INVOKEVIRTUAL)); // End-of debug info QueueJVMGen jvmQ = (QueueJVMGen) getQueue(); CommonGen.generateGetQueue(scope, jvmQ); il.append(InstructionConstants.SWAP); il.append( ifact.createInvoke( DefaultTypes.ContinuationResolverHelper.getClassName(), "requestAndWait", Type.OBJECT, new Type[] {DefaultTypes.HistoryQueue, DefaultTypes.IRequest}, Constants.INVOKESTATIC)); // il.append(ifact.createInvoke(jvmQ.getClassName(), // "requestAndWait", Type.OBJECT, new Type[] { DefaultTypes.IRequest }, // Constants.INVOKEVIRTUAL)); // il.append(InstructionConstants.DUP); // CommonGen.print(il, ifact); il.append(new ASTORE(lvg.getIndex())); }
/** * Creates a proxy method for the original method specified. This method has the same signature as * the original method and catches the invocation for further processing by the framework before * redirecting to the original method. * * @todo pass the 'class' as a Class instance not a String to the join point. Add the class field * to the class using BCEL (see AdviseStaticMethodTransformer.java) * @param cp the ConstantPoolGen * @param cg the ClassGen * @param originalMethod the current method * @param factory the objectfactory * @param methodId the id of the current method in the lookup tabl * @param methodSequence the methods sequence number * @param accessFlags the access flags of the original method * @param uuid the uuid for the weave model defining the pointcut * @param controllerClassName the class name of the controller class to use * @return the proxy method */ private Method createProxyMethod( final ConstantPoolGen cp, final ClassGen cg, final MethodGen originalMethod, final InstructionFactory factory, final int methodId, final int methodSequence, final int accessFlags, final String uuid, final String controllerClassName) { InstructionList il = new InstructionList(); String joinPoint = getJoinPointName(originalMethod.getMethod(), methodSequence); final MethodGen method = new MethodGen( accessFlags, Type.getReturnType(originalMethod.getSignature()), Type.getArgumentTypes(originalMethod.getSignature()), originalMethod.getArgumentNames(), originalMethod.getName(), cg.getClassName(), il, cp); String[] exceptions = originalMethod.getExceptions(); for (int i = 0; i < exceptions.length; i++) { method.addException(exceptions[i]); } int indexParam = 1; int indexStack = 0; int indexJoinPoint = Type.getArgumentTypes(originalMethod.getSignature()).length * 2 + 1; // if (threadLocal == null) { // threadLocal = new SerializableThreadLocal(); // } il.append(factory.createLoad(Type.OBJECT, 0)); il.append( factory.createFieldAccess( cg.getClassName(), joinPoint, new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.GETFIELD)); BranchInstruction ifNotNull = factory.createBranchInstruction(Constants.IFNONNULL, null); il.append(ifNotNull); il.append(factory.createLoad(Type.OBJECT, 0)); il.append(factory.createNew(TransformationUtil.THREAD_LOCAL_CLASS)); il.append(InstructionConstants.DUP); il.append( factory.createInvoke( TransformationUtil.THREAD_LOCAL_CLASS, "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); il.append( factory.createFieldAccess( cg.getClassName(), joinPoint.toString(), new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.PUTFIELD)); // Object joinPoint = ___jp.get(); BranchInstruction biIfNotNull = null; InstructionHandle ihIfNotNull = null; ifNotNull.setTarget(il.append(factory.createLoad(Type.OBJECT, 0))); il.append( factory.createFieldAccess( cg.getClassName(), joinPoint.toString(), new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.GETFIELD)); il.append( factory.createInvoke( TransformationUtil.THREAD_LOCAL_CLASS, "get", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(factory.createStore(Type.OBJECT, indexJoinPoint)); il.append(factory.createLoad(Type.OBJECT, indexJoinPoint)); // if (joinPoint == null) { biIfNotNull = factory.createBranchInstruction(Constants.IFNONNULL, null); il.append(biIfNotNull); // joinPoint = new WeakReference(new MemberMethodJoinPoint(uuid, this, "foo.bar.Baz", 10)); // il.append(factory.createNew(TransformationUtil.WEAK_REFERENCE_CLASS)); // il.append(InstructionConstants.DUP); il.append(factory.createNew(TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS)); il.append(InstructionConstants.DUP); il.append(new PUSH(cp, uuid)); il.append(factory.createLoad(Type.OBJECT, 0)); il.append(new PUSH(cp, cg.getClassName())); il.append(new PUSH(cp, methodId)); il.append(new PUSH(cp, controllerClassName)); il.append( factory.createInvoke( TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS, "<init>", Type.VOID, new Type[] {Type.STRING, Type.OBJECT, Type.STRING, Type.INT, Type.STRING}, Constants.INVOKESPECIAL)); il.append(factory.createStore(Type.OBJECT, indexJoinPoint)); // threadLocal.set(joinPoint); il.append(factory.createLoad(Type.OBJECT, 0)); il.append( factory.createFieldAccess( cg.getClassName(), joinPoint.toString(), new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.GETFIELD)); il.append(factory.createLoad(Type.OBJECT, indexJoinPoint)); il.append( factory.createInvoke( TransformationUtil.THREAD_LOCAL_CLASS, "set", Type.VOID, new Type[] {Type.OBJECT}, Constants.INVOKEVIRTUAL)); ihIfNotNull = il.append(factory.createLoad(Type.OBJECT, indexJoinPoint)); indexJoinPoint += 2; il.append(factory.createCheckCast(TransformationUtil.MEMBER_METHOD_JOIN_POINT_TYPE)); il.append(factory.createStore(Type.OBJECT, indexJoinPoint)); biIfNotNull.setTarget(ihIfNotNull); // if we have parameters, wrap them up if (Type.getArgumentTypes(originalMethod.getSignature()).length != 0) { // create and allocate the parameters array il.append(new PUSH(cp, Type.getArgumentTypes(originalMethod.getSignature()).length)); il.append(factory.createNewArray(Type.OBJECT, (short) 1)); il.append(InstructionConstants.DUP); il.append(new PUSH(cp, indexStack)); indexStack++; // add all the parameters, wrap the primitive types in their object counterparts for (int count = 0; count < Type.getArgumentTypes(originalMethod.getSignature()).length; count++) { String wrapperClass = null; BasicType type = null; boolean hasLongOrDouble = false; if (Type.getArgumentTypes(originalMethod.getSignature())[count] instanceof ObjectType || Type.getArgumentTypes(originalMethod.getSignature())[count] instanceof ArrayType) { // we have an object or an array il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(InstructionConstants.AASTORE); indexParam++; } else if (Type.getArgumentTypes(originalMethod.getSignature())[count] instanceof ArrayType) { // we have an array il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(InstructionConstants.AASTORE); indexParam++; } else if (Type.getArgumentTypes(originalMethod.getSignature())[count] instanceof BasicType) { hasLongOrDouble = false; // we have a primitive type if ((Type.getArgumentTypes(originalMethod.getSignature())[count]).equals(Type.LONG)) { wrapperClass = "java.lang.Long"; type = Type.LONG; hasLongOrDouble = true; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.INT)) { wrapperClass = "java.lang.Integer"; type = Type.INT; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.SHORT)) { wrapperClass = "java.lang.Short"; type = Type.SHORT; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.DOUBLE)) { wrapperClass = "java.lang.Double"; type = Type.DOUBLE; hasLongOrDouble = true; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.FLOAT)) { wrapperClass = "java.lang.Float"; type = Type.FLOAT; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.CHAR)) { wrapperClass = "java.lang.Character"; type = Type.CHAR; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.BYTE)) { wrapperClass = "java.lang.Byte"; type = Type.BYTE; } else if ((Type.getArgumentTypes(originalMethod.getSignature())[count]) .equals(Type.BOOLEAN)) { wrapperClass = "java.lang.Boolean"; type = Type.BOOLEAN; } else { throw new RuntimeException( "unknown parameter type: " + Type.getArgumentTypes(originalMethod.getSignature())[count]); } il.append(factory.createNew(wrapperClass)); il.append(InstructionConstants.DUP); il.append(factory.createLoad(type, indexParam)); il.append( factory.createInvoke( wrapperClass, "<init>", Type.VOID, new Type[] {type}, Constants.INVOKESPECIAL)); il.append(InstructionConstants.AASTORE); indexParam++; } // end handle basic or object type if (count != Type.getArgumentTypes(originalMethod.getSignature()).length - 1) { // if we don't have the last parameter, create the parameter on the stack il.append(InstructionConstants.DUP); il.append(new PUSH(cp, indexStack)); indexStack++; // long or double needs two registers to fit if (hasLongOrDouble) indexParam++; } } // create the object array il.append(factory.createStore(Type.OBJECT, indexParam)); // if threadsafe grab the newly retrieved local join point field from the stack il.append(factory.createLoad(Type.OBJECT, indexJoinPoint)); // invoke joinPoint.setParameter(..) il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append( factory.createInvoke( TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS, "setParameters", Type.VOID, new Type[] {new ArrayType(Type.OBJECT, 1)}, Constants.INVOKEVIRTUAL)); indexParam++; } // end - if parameters.length != 0 // if threadsafe grab the newly retrieved local join point field from the stack il.append(factory.createLoad(Type.OBJECT, indexJoinPoint)); il.append( factory.createInvoke( TransformationUtil.MEMBER_METHOD_JOIN_POINT_CLASS, "proceed", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); if (!Type.getReturnType(originalMethod.getSignature()).equals(Type.VOID)) { // create the result from the invocation il.append(factory.createStore(Type.OBJECT, indexParam)); il.append(factory.createLoad(Type.OBJECT, indexParam)); // cast the result and return it, if the return type is a // primitive type, retrieve it from the wrapped object first // unless the return object is null (AW-100) if (Type.getReturnType(originalMethod.getSignature()) instanceof BasicType) { if (Type.getReturnType(originalMethod.getSignature()).equals(Type.VOID)) {; // skip } else { BranchInstruction ifNullBranch = factory.createBranchInstruction(Constants.IFNONNULL, null); InstructionHandle elseBranch = null; il.append(ifNullBranch); if (Type.getReturnType(originalMethod.getSignature()).equals(Type.LONG)) { il.append(new PUSH(cp, 0L)); il.append(factory.createReturn(Type.LONG)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Long"))); il.append( factory.createInvoke( "java.lang.Long", "longValue", Type.LONG, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.INT)) { il.append(new PUSH(cp, 0)); il.append(factory.createReturn(Type.INT)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Integer"))); il.append( factory.createInvoke( "java.lang.Integer", "intValue", Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.SHORT)) { il.append(new PUSH(cp, (short) 0)); il.append(factory.createReturn(Type.SHORT)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Short"))); il.append( factory.createInvoke( "java.lang.Short", "shortValue", Type.SHORT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.DOUBLE)) { il.append(new PUSH(cp, 0.0d)); il.append(factory.createReturn(Type.DOUBLE)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Double"))); il.append( factory.createInvoke( "java.lang.Double", "doubleValue", Type.DOUBLE, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.FLOAT)) { il.append(new PUSH(cp, 0.0f)); il.append(factory.createReturn(Type.FLOAT)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Float"))); il.append( factory.createInvoke( "java.lang.Float", "floatValue", Type.FLOAT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.CHAR)) { il.append(new PUSH(cp, '\u0000')); il.append(factory.createReturn(Type.CHAR)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Character"))); il.append( factory.createInvoke( "java.lang.Character", "charValue", Type.CHAR, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.BYTE)) { il.append(new PUSH(cp, (byte) 0)); il.append(factory.createReturn(Type.BYTE)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Byte"))); il.append( factory.createInvoke( "java.lang.Byte", "byteValue", Type.BYTE, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (Type.getReturnType(originalMethod.getSignature()).equals(Type.BOOLEAN)) { il.append(new PUSH(cp, false)); il.append(factory.createReturn(Type.BOOLEAN)); elseBranch = il.append(factory.createLoad(Type.OBJECT, indexParam)); il.append(factory.createCheckCast(new ObjectType("java.lang.Boolean"))); il.append( factory.createInvoke( "java.lang.Boolean", "booleanValue", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else { throw new Error( "unknown return type: " + Type.getReturnType(originalMethod.getSignature())); } ifNullBranch.setTarget(elseBranch); } } else { // cast the result to the right type il.append( factory.createCast(Type.OBJECT, Type.getReturnType(originalMethod.getSignature()))); } } il.append(factory.createReturn(Type.getReturnType(originalMethod.getSignature()))); method.setMaxStack(); method.setMaxLocals(); return method.getMethod(); }