System.out.println(" methodName = " + methodName);
System.out.println(" methodSig = " + methodSig);
System.out.println(" superName = " + superName);
}
final CodeAttribute codeAttr = method.codeAttribute();
for (Insn insn = codeAttr.theCode();
insn != null;
insn = insn.next()) {
// Found the clone method. See if it is the flavor of clone()
// which does a super.clone() call, and if it is, add
// field initializations for the jdoStateManager and jdoFlags
// fields.
if (insn.opcode() != opc_invokespecial)
continue;
final InsnConstOp invoke = (InsnConstOp)insn;
final ConstMethodRef methodRef = (ConstMethodRef)invoke.value();
final ConstNameAndType methodNT = methodRef.nameAndType();
final String methodName = methodNT.name().asString();
final String methodSig = methodNT.signature().asString();
if (!(methodName.equals("clone")
&& methodSig.equals("()Ljava/lang/Object;")))
continue;
if (false) {
final ConstClass methodClass = methodRef.className();
final String methodClassName = methodClass.asString();
System.out.println(" found invocation of: "
+ methodClassName
+ "." + methodName + methodSig);
}
// check whether next instruction already is a downcast to a
// class implementing PersistenceCapable
final String thisClass = classFile.classNameString();
final Insn checkCastInsn = insn.next();
final boolean needCheckcast;
if (checkCastInsn.opcode() != opc_checkcast) {
needCheckcast = true;
} else {
ConstClass target =
(ConstClass) ((InsnConstOp)checkCastInsn).value();
if (target.asString().equals(thisClass)) {
insn = checkCastInsn;
needCheckcast = false;
} else {
needCheckcast = true;
}
}
// clear jdo fields of clone
{
// duplicate downcasted reference
final Insn newInsn = Insn.create(opc_dup);
if (needCheckcast) {
newInsn.append(Insn.create(opc_checkcast,
pool.addClass(thisClass)));
}
newInsn.append(Insn.create(opc_dup));
// clear jdo fields
newInsn.append(Insn.create(opc_aconst_null));
newInsn.append(Insn.create(
opc_putfield,
pool.addFieldRef(
thisClass,
JDOConstants.JDO_PC_jdoStateManager_Name,
JDOConstants.JDO_PC_jdoStateManager_Sig)));
newInsn.append(Insn.create(opc_iconst_0));
newInsn.append(Insn.create(
opc_putfield,
pool.addFieldRef(
thisClass,
JDOConstants.JDO_PC_jdoFlags_Name,
JDOConstants.JDO_PC_jdoFlags_Sig)));
// insert code
insn.insert(newInsn);
// increase stack
final int annotationStack = 3;
codeAttr.setStackUsed(codeAttr.stackUsed() + annotationStack);
}
}
}