should get picked up. I will look at this some more. > > You are right, the data flow analysis is not sufficient here. In > fact, we should not only track what comes from the method > parameters (i.e. the local variables), but also make sure that a > GETFIELD that refers to the original instance should be either > split in two GETFIELD if the variable is extended to include a > deriviative (when there is another PUTFIELD elsewhere), or that > event if the field is only read, that we try to recover it from > the primitive and not from the instance itself.
Thanks again, Luc, for your patience explaining things that I should have been able to see in the code. Things are getting much clearer now. I have been able to get field access to work as follows: The data flow analysis is never going to flag the GETFIELD instruction as needing to be transformed. It works beautifully for what it does, but instructions that are not producers or consumers of values originating from method parameters are not going to be picked up. To just handle GETFIELD, I added the following at the end of MethodDifferentiator#changeCode: // transform GETFIELD Iterator<AbstractInsnNode> iter = instructions.iterator(); while (iter.hasNext()) { AbstractInsnNode insn = iter.next(); if (insn.getOpcode() == Opcodes.GETFIELD) { instructions.insert(insn, getReplacement(insn)); instructions.remove(insn); } } and then inside getReplacement replace the RTE on GETFIELD with case Opcodes.GETFIELD : return GetFieldTransformer.getInstance().getReplacement(insn, this); where GetFieldTransformer does FieldInsnNode fieldIns = (FieldInsnNode) insn.clone(null); String owner = fieldIns.owner; final InsnList list = new InsnList(); list.add(new FieldInsnNode(Opcodes.GETFIELD, owner + "$NablaForwardModeUnivariateDerivative", "primitive", "L" + owner + ";")); // primitive list.add(fieldIns); return list; For a primitive class named "PartialFunction" this generates ALOAD 0 GETFIELD PartialFunction$NablaForwardModeUnivariateDerivative.primitive : LPartialFunction; GETFIELD PartialFunction.x : D This works great except for one problem: If the field in the primitive, "x" in the example above, is not public, you get java.lang.IllegalAccessError: tried to access field PartialFunction.x from class PartialFunction$NablaForwardModeUnivariateDerivative at PartialFunction$NablaForwardModeUnivariateDerivative.f(Unknown Source) (one case where I am not cursing the "Unknown Source" he he) I am not sure exactly what to do about that. Is PartialFunction$NablaForwardModeUnivariateDerivative a static inner class? Shouldn't it in theory be able to access the field from an instance reference? I think the compiler generates a hidden field accessor when static inner classes are defined. It looks like it does that when I manually add a static inner class, in any case. Could be we need to manufacture that and attach it to the primitive. Or could be I am misunderstanding things. Alternatively, we could document and require that for a method to be "differentiable" it must use only fields that have public getters with bean naming and we could generate code to invoke the getter on the primitive. Phil > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org