mv.visitInsn(ft.getOpcode(IRETURN));
mv.visitMaxs(0, 0);
}
private void generateFieldSetter(Field f, Type ft, String ftd, int nbField) {
CodeVisitor mv;
int nextLocalVarIdx = 1 + ft.getSize();
mv = cv.visitMethod(ACC_PUBLIC, f.getSetter(), "(" + ftd + ")V", null, null);
//if (!speedoIsActive()) {
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, ISACTIVE_FIELD_NAME, "()Z");
Label l1 = new Label();
mv.visitJumpInsn(IFNE, l1);
{
//if(speedoReferenceState.getDetachedStatus() != DetachedLifeCycle.DETACHED_NONE) {
generateGetRefState(mv, false);
mv.visitMethodInsn(INVOKEVIRTUAL, xfieldsAncestorJCN, "getDetachedStatus", "()B");
Util.visitIntConstant(mv, DetachedLifeCycle.DETACHED_NONE);
mv.visitInsn(I2B);
Label l3 = new Label();
mv.visitJumpInsn(IF_ICMPEQ, l3);
{
//if (!(($classNameFields) speedoReferenceState).${f.name}Loaded ) {
generateGetRefState(mv, true);
mv.visitFieldInsn(GETFIELD, xfieldsJCN, f.getName() + "Loaded", "Z");
Label l5 = new Label();
mv.visitJumpInsn(IFNE, l5);
{
//throw new DetachedFieldAccessException("Field $f.name cannot be accessed: not loaded when the object has been detached");
mv.visitTypeInsn(NEW, personality.getDetachedFieldAccessExceptionClassNameSlash());
mv.visitInsn(DUP);
mv.visitLdcInsn("Field " + f.getName()
+ " cannot be accessed: not loaded when the object has been detached");
mv.visitMethodInsn(INVOKESPECIAL, personality.getDetachedFieldAccessExceptionClassNameSlash(), "<init>", "(Ljava/lang/String;)V");
mv.visitInsn(ATHROW);
}
mv.visitLabel(l5);
//mark the detached copy as dirty
//speedoReferenceState.setDetachedStatus(DetachedLifeCycle.DETACHED_DIRTY);
generateGetRefState(mv, false);
Util.visitIntConstant(mv, DetachedLifeCycle.DETACHED_DIRTY);
mv.visitInsn(I2B);
mv.visitMethodInsn(INVOKEVIRTUAL, xfieldsAncestorJCN, "setDetachedStatus", "(B)V");
}
mv.visitLabel(l3);
//(($classNameFields) speedoReferenceState).${f.name} = val;
generateGetRefState(mv, true);
mv.visitVarInsn(ft.getOpcode(ILOAD), 1);
mv.visitFieldInsn(PUTFIELD, xfieldsJCN, f.getName(), ftd);
//return
mv.visitInsn(RETURN);
}
mv.visitLabel(l1);
//The po is activated
//Logger logger = ((org.objectweb.jorm.util.api.Loggable) getPClassMapping()).getLogger();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, "getPClassMapping",
"()Lorg/objectweb/jorm/api/PClassMapping;");
mv.visitTypeInsn(CHECKCAST, "org/objectweb/jorm/util/api/Loggable");
mv.visitMethodInsn(INVOKEINTERFACE, "org/objectweb/jorm/util/api/Loggable",
"getLogger", "()Lorg/objectweb/util/monolog/api/Logger;");
final int loggerIdx = nextLocalVarIdx;
nextLocalVarIdx++;
mv.visitVarInsn(ASTORE, loggerIdx);
//$classNameFields state = ($classNameFields) speedoWriteIntention(${f.jormFielIdDecl});
mv.visitVarInsn(ALOAD, 0);
generateFieldIdAsLongArray(f, nbField, mv);
mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, "speedoWriteIntention",
"([J)" + JT_STATE);
mv.visitTypeInsn(CHECKCAST, xfieldsJCN);
final int stateIdx = nextLocalVarIdx;
nextLocalVarIdx++;
mv.visitVarInsn(ASTORE, stateIdx);
if (f.getIsReference()) {
generateReferenceSetter(f, ft, nbField, loggerIdx, stateIdx, nextLocalVarIdx, mv);
} else {
mv.visitVarInsn(ALOAD, stateIdx);
mv.visitVarInsn(ft.getOpcode(ILOAD), 1);
mv.visitFieldInsn(PUTFIELD, xfieldsJCN, f.getName(), ftd);
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
}