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.createInvoke(
// TransformationUtil.WEAK_REFERENCE_CLASS,
// "<init>",
// Type.VOID,
// new Type[]{Type.OBJECT},
// 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;
// cast the weak ref, retrieve the join point from the weak ref and cast the join point
// il.append(factory.createCheckCast(TransformationUtil.WEAK_REFERENCE_TYPE));
// il.append(factory.createStore(Type.OBJECT, indexJoinPoint));
// il.append(factory.createLoad(Type.OBJECT, indexJoinPoint));
// indexJoinPoint += 1;
// il.append(factory.createInvoke(
// TransformationUtil.WEAK_REFERENCE_CLASS,
// "get",
// Type.OBJECT,
// Type.NO_ARGS,
// Constants.INVOKEVIRTUAL)
// );
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())));