You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/10/31 18:48:21 UTC

svn commit: r1404268 - in /commons/sandbox/nabla/trunk/src: main/java/org/apache/commons/nabla/ main/java/org/apache/commons/nabla/forward/ main/java/org/apache/commons/nabla/forward/analysis/ main/java/org/apache/commons/nabla/forward/instructions/ ma...

Author: luc
Date: Wed Oct 31 17:48:21 2012
New Revision: 1404268

URL: http://svn.apache.org/viewvc?rev=1404268&view=rev
Log:
Work In Progress on support for fields.

Roundtrip dependency between fields and methods is mostly in place.
The methods that are differentiated are not limited to methods that take
some double arguments that are changed to DerivativeStructure. The
methods that use fields transformed from double to DerivativeStructure
also need to be changed, the fields being some "hidden" way to pass
transformed values to them. This is now detected (but not yet handled
completely).

Added:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java   (with props)
Removed:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiableField.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiableMethod.java
Modified:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/NablaMessages.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/ClassDifferentiator.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeNonMathTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/PutTransformer.java
    commons/sandbox/nabla/trunk/src/main/resources/assets/org/apache/commons/nabla/NablaMessages_fr.properties
    commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/NablaMessagesTest.java

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/NablaMessages.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/NablaMessages.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/NablaMessages.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/NablaMessages.java Wed Oct 31 17:48:21 2012
@@ -52,6 +52,7 @@ public enum NablaMessages implements Loc
     UNABLE_TO_ANALYZE_METHOD("unable to analyze the {0}.{1} method ({2})"),
     UNKNOWN_METHOD("unknown method {0}.{1}"),
     UNEXPECTED_INSTRUCTION("unexpected instruction with opcode {0}"),
+    INVOKE_DYNAMIC_NOT_HANDLED_YET("INVOKEDYNAMIC instruction found while differentiating class {0}, it is not suported yet"),
     UNABLE_TO_HANDLE_INSTRUCTION("unable to handle instruction with opcode {0}"),
     CANNOT_USE_VOID_FIELD("unable to use value of void type field {0}"),
     ILLEGAL_LDC_CONSTANT("illegal LDC constant {0}"),

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java?rev=1404268&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java Wed Oct 31 17:48:21 2012
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward;
+
+import org.objectweb.asm.Type;
+
+/** Complete specification for an element (field or method) to differentiate.
+ * @version $Id$
+ */
+public class DifferentiatedElementSpecification {
+
+    /** Specification for the primitive element. */
+    private final PrimitiveElementSpecification primitiveSpec;
+
+    /** Type of the element in the differentiated class. */
+    private final Type differentiatedType;
+
+    /** Simple constructor.
+     * @param name element name
+     * @param isStatic if true, the element is static
+     * @param primitiveClass internal name of the class in which the element is defined
+     * @param primitiveType element type in the primitive
+     * @param differentiatedType element type in the differentiated class
+     */
+    public DifferentiatedElementSpecification(final String name, final boolean isStatic,
+                                              final String primitiveClass, final Type primitiveType,
+                                              final Type differentiatedType) {
+        this.primitiveSpec      = new PrimitiveElementSpecification(name, isStatic, primitiveClass, primitiveType);
+        this.differentiatedType = differentiatedType;
+    }
+
+    /** Get the primitive specification.
+     * @param primitive specification
+     */
+    public PrimitiveElementSpecification getPrimitiveSpec() {
+        return primitiveSpec;
+    }
+
+    /** Get the type of the element in the differentiated class.
+     * @return type of the element in the differentiated class
+     */
+    public Type getDifferentiatedType() {
+        return differentiatedType;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(final Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof DifferentiatedElementSpecification) {
+            DifferentiatedElementSpecification de = (DifferentiatedElementSpecification) other;
+            return primitiveSpec.equals(de.primitiveSpec) &&
+                   differentiatedType.equals(de.differentiatedType);
+        }
+
+        return false;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        // the following coefficients are arbitrarily chosen prime numbers
+        return primitiveSpec.hashCode() + 733 * differentiatedType.hashCode();
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/DifferentiatedElementSpecification.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java Wed Oct 31 17:48:21 2012
@@ -21,9 +21,12 @@ import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
@@ -59,6 +62,9 @@ import org.objectweb.asm.util.TraceClass
  */
 public class ForwardModeDifferentiator implements UnivariateFunctionDifferentiator {
 
+    /** Suffix for differentiated classes. */
+    private static final String CLASS_SUFFIX = "_NablaForwardModeDifferentiated";
+
     /** UnivariateFunction/UnivariateDifferentiableFunction map. */
     private final HashMap<Class<? extends UnivariateFunction>,
                           Class<? extends NablaUnivariateDifferentiableFunction>> map;
@@ -73,30 +79,34 @@ public class ForwardModeDifferentiator i
     private final Set<ClassDifferentiator> differentiators;
 
     /** Pending methods differentiations. */
-    private final Set<DifferentiableMethod> pendingMethodsDifferentiations;
+    private final Set<DifferentiatedElementSpecification> pendingMethods;
 
     /** Processed methods differentiations. */
-    private final Set<DifferentiableMethod> processedMethodsDifferentiations;
+    private final Set<DifferentiatedElementSpecification> processedMethods;
 
     /** Pending fields differentiations. */
-    private final Set<DifferentiableField> pendingFieldsDifferentiations;
+    private final Set<DifferentiatedElementSpecification> pendingFields;
 
     /** Processed fields differentiations. */
-    private final Set<DifferentiableField> processedFieldsDifferentiations;
+    private final Set<DifferentiatedElementSpecification> processedFields;
+
+    /** Map associating a field with the methods using it. */
+    private final Map<DifferentiatedElementSpecification, List<PrimitiveElementSpecification>> fieldsUsers;
 
     /** Simple constructor.
      * <p>Build a ForwardAlgorithmicDifferentiator instance with an empty cache.</p>
      */
     public ForwardModeDifferentiator() {
-        map                              = new HashMap<Class<? extends UnivariateFunction>,
-                                                       Class<? extends NablaUnivariateDifferentiableFunction>>();
-        byteCodeMap                      = new HashMap<String, byte[]>();
-        mathClasses                      = new HashSet<String>();
-        differentiators                  = new HashSet<ClassDifferentiator>();
-        pendingMethodsDifferentiations   = new HashSet<DifferentiableMethod>();
-        processedMethodsDifferentiations = new HashSet<DifferentiableMethod>();
-        pendingFieldsDifferentiations    = new HashSet<DifferentiableField>();
-        processedFieldsDifferentiations  = new HashSet<DifferentiableField>();
+        map              = new HashMap<Class<? extends UnivariateFunction>,
+                                       Class<? extends NablaUnivariateDifferentiableFunction>>();
+        byteCodeMap      = new HashMap<String, byte[]>();
+        mathClasses      = new HashSet<String>();
+        differentiators  = new HashSet<ClassDifferentiator>();
+        pendingMethods   = new HashSet<DifferentiatedElementSpecification>();
+        processedMethods = new HashSet<DifferentiatedElementSpecification>();
+        pendingFields    = new HashSet<DifferentiatedElementSpecification>();
+        processedFields  = new HashSet<DifferentiatedElementSpecification>();
+        fieldsUsers      = new HashMap<DifferentiatedElementSpecification, List<PrimitiveElementSpecification>>();
         addMathImplementation(Math.class);
         addMathImplementation(StrictMath.class);
         addMathImplementation(FastMath.class);
@@ -123,63 +133,98 @@ public class ForwardModeDifferentiator i
         throw new RuntimeException("not implemented yet");
     }
 
-    /** Request differentiation of a method.
-     * @param owner class in which the method is defined
-     * @param isStatic if true, the method is static
-     * @param method method name
-     * @param primitiveMethodType method type in the primitive (includes return and arguments types)
-     * @param differentiatedMethodType method type in the differentiated class (includes return and arguments types)
-     * @exception DifferentiationException if class cannot be found
+    /** Get the internal name of a differentiated class.
+     * @param primitiveInternalName internal name of the primitive class
+     * @return internal name of the corresponding differentiated class
      */
-    public void requestMethodDifferentiation(final String owner, final boolean isStatic,
-                                             final String method, final Type primitiveMethodType,
-                                             final Type differentiatedMethodType)
-        throws DifferentiationException {
+    public String getDifferentiatedInternalName(final String primitiveInternalName) {
+        return primitiveInternalName + CLASS_SUFFIX;
+    }
 
-        try {
+    /** Check if a method uses a differentiated field.
+     * @param method differentiable method to check
+     * @return a differentiated field used by the method, null if it does not use any differentiated fields
+     */
+    public DifferentiatedElementSpecification getUsedDifferentiatedField(final PrimitiveElementSpecification method) {
 
-            final DifferentiableMethod dm =
-                    new DifferentiableMethod(Class.forName(owner), isStatic,
-                                             method, primitiveMethodType, differentiatedMethodType);
-
-            if (!processedMethodsDifferentiations.contains(dm)) {
-                // schedule the request if method has not been processed yet
-                pendingMethodsDifferentiations.add(dm);
+        // loop over all fields and check their users
+        for (final Map.Entry<DifferentiatedElementSpecification, List<PrimitiveElementSpecification>> entry : fieldsUsers.entrySet()) {
+            if (entry.getValue().contains(method)) {
+                return entry.getKey();
             }
+        }
+
+        // none of the fields we are interested in is used by this method
+        return null;
  
-        } catch (ClassNotFoundException cnfe) {
-            throw new DifferentiationException(NablaMessages.CANNOT_READ_CLASS,
-                                               owner, cnfe.getMessage());
+    }
+
+    /** Get a differentiated element.
+     * @param primitive primitive specification to check
+     * @return a differentiated element corresponding to the primitive, null if no elements correspond
+     */
+    public DifferentiatedElementSpecification getDifferentiated(final PrimitiveElementSpecification primitive) {
+
+        // loop over all pending fields
+        for (final DifferentiatedElementSpecification field : pendingFields) {
+            if (field.getPrimitiveSpec().equals(primitive)) {
+                return field;
+            }
+        }
+
+        // loop over all processed fields
+        for (final DifferentiatedElementSpecification field : processedFields) {
+            if (field.getPrimitiveSpec().equals(primitive)) {
+                return field;
+            }
+        }
+
+        // loop over all pending methods
+        for (final DifferentiatedElementSpecification method : pendingMethods) {
+            if (method.getPrimitiveSpec().equals(primitive)) {
+                return method;
+            }
         }
 
+        // loop over all processed methods
+        for (final DifferentiatedElementSpecification method : processedMethods) {
+            if (method.getPrimitiveSpec().equals(primitive)) {
+                return method;
+            }
+        }
+
+        // none of the element we are interested in correspond to the specification
+        return null;
+ 
+    }
+
+    /** Request differentiation of a method.
+     * @param method differentiated method to check
+     */
+    public void requestMethodDifferentiation(final DifferentiatedElementSpecification method) {
+        if (!processedMethods.contains(method)) {
+            // schedule the request if method has not been processed yet
+            pendingMethods.add(method);
+        }
     }
 
     /** Request differentiation of a field.
-     * @param owner class in which the field is defined
-     * @param isStatic if true, the field is static
-     * @param field field name
-     * @param primitiveFieldType field type in the primitive
-     * @param differentiatedFieldType field type in the differentiated class
-     * @exception DifferentiationException if class cannot be found
+     * @param field field to differentiate
      */
-    public void requestFieldDifferentiation(final String owner, final boolean isStatic,
-                                            final String field, final Type primitiveFieldType,
-                                            final Type differentiatedFieldType) {
+    public void requestFieldDifferentiation(final DifferentiatedElementSpecification field) {
 
-        try {
+        if (!processedFields.contains(field)) {
 
-            final DifferentiableField df =
-                    new DifferentiableField(Class.forName(owner), isStatic,
-                                            field, primitiveFieldType, differentiatedFieldType);
-
-            if (!processedFieldsDifferentiations.contains(df)) {
-                // schedule the request if field has not been processed yet
-                pendingFieldsDifferentiations.add(df);
+            // schedule the request if field has not been processed yet
+            pendingFields.add(field);
+
+            // get the users for this field
+            final List<PrimitiveElementSpecification> users = new ArrayList<PrimitiveElementSpecification>();
+            for (final ClassDifferentiator differentiator : differentiators) {
+                users.addAll(differentiator.getMethodsUsingField(field));
             }
- 
-        } catch (ClassNotFoundException cnfe) {
-            throw new DifferentiationException(NablaMessages.CANNOT_READ_CLASS,
-                                               owner, cnfe.getMessage());
+            fieldsUsers.put(field, users);
+
         }
 
     }
@@ -237,42 +282,57 @@ public class ForwardModeDifferentiator i
     createDerivativeClass(final Class<? extends UnivariateFunction> differentiableClass)
         throws DifferentiationException {
 
-        // bootstrap differentiation using the top level value function from the UnivariateFunction interface
+        // bootstrap differentiation starting from the top level value function defined by the UnivariateFunction interface
         final Type dsType = Type.getType(DerivativeStructure.class);
-        requestMethodDifferentiation(differentiableClass.getName(), false, "value",
+        requestMethodDifferentiation(new DifferentiatedElementSpecification("value", false,
+                                     Type.getInternalName(differentiableClass),
                                      Type.getMethodType(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE),
-                                     Type.getMethodType(dsType, dsType));
+                                     Type.getMethodType(dsType, dsType)));
 
-        while (!(pendingMethodsDifferentiations.isEmpty() && pendingFieldsDifferentiations.isEmpty())) {
+        // loop while there is still something to differentiate (either fields or methods)
+        while (!(pendingFields.isEmpty() && pendingMethods.isEmpty())) {
 
-            for (final DifferentiableField df : pendingFieldsDifferentiations) {
+            for (final DifferentiatedElementSpecification df : pendingFields) {
 
                 // differentiate the field
-                getDifferentiator(df.getPrimitiveClass()).differentiateField(df);
+                getDifferentiator(df).differentiateField(df);
+
+                // get all the methods that use this field
+                final List<PrimitiveElementSpecification> users = fieldsUsers.get(df);
+
+                if (users != null) {
+
+                    // this field is used by some methods in the classes we monitor,
+                    // in order to make sure it is taken into account properly,
+                    // we invalidate the differentiation of these methods and process them again
+                    for (final PrimitiveElementSpecification user : users) {
+                        for (final Iterator<DifferentiatedElementSpecification> iterator = processedMethods.iterator(); iterator.hasNext();) {
+                            final DifferentiatedElementSpecification method = iterator.next();
+                            if (user.equals(method.getPrimitiveSpec())) {
+                                // the differentiated method uses the field, we need to differentiate it again
+                                iterator.remove();
+                                getDifferentiator(method).clearDifferentiatedElement(method);
+                                pendingMethods.add(method);
+                            }
+                        }
+                    }
 
-                // this field may be used by some methods already differentiated
-                // in order to make sure it is taken into account properly,
-                // we invalidate all existing differentiated methods and redo them all
-                pendingMethodsDifferentiations.addAll(processedMethodsDifferentiations);
-                processedMethodsDifferentiations.clear();
-                for (final ClassDifferentiator differentiator : differentiators) {
-                    differentiator.clearDifferentiatedMethods();
                 }
 
             }
 
             // move all fields from pending to processed
-            processedFieldsDifferentiations.addAll(pendingFieldsDifferentiations);
-            pendingFieldsDifferentiations.clear();
+            processedFields.addAll(pendingFields);
+            pendingFields.clear();
 
             // move one method from pending to processed
-            final Iterator<DifferentiableMethod> iterator = pendingMethodsDifferentiations.iterator();
-            final DifferentiableMethod dm = iterator.next();
+            final Iterator<DifferentiatedElementSpecification> iterator = pendingMethods.iterator();
+            final DifferentiatedElementSpecification dm = iterator.next();
             iterator.remove();
-            processedMethodsDifferentiations.add(dm);
+            processedMethods.add(dm);
 
             // differentiate the method
-            getDifferentiator(dm.getPrimitiveClass()).differentiateMethod(dm);
+            getDifferentiator(dm).differentiateMethod(dm);
 
         }
 
@@ -287,7 +347,7 @@ public class ForwardModeDifferentiator i
 
             // TODO: remove development trace
             try {
-                new ClassReader(differentiableClass.getResourceAsStream("/" + Type.getInternalName(differentiableClass) + ".class")).accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
+                new ClassReader(differentiableClass.getName()).accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
                 new ClassReader(bytecode).accept(new TraceClassVisitor(new PrintWriter(System.err)), 0);
             } catch (IOException ioe) {
                 throw new RuntimeException(ioe);
@@ -297,7 +357,7 @@ public class ForwardModeDifferentiator i
                     new DerivativeLoader(differentiableClass).defineClass(name, bytecode);
             byteCodeMap.put(name, bytecode);
 
-            if (differentiator.getPrimitiveName().equals(Type.getType(differentiableClass).getInternalName())) {
+            if (differentiator.getPrimitiveName().equals(differentiableClass.getName())) {
                 nudf = (Class<? extends NablaUnivariateDifferentiableFunction>) dClass;
             }
 
@@ -312,31 +372,38 @@ public class ForwardModeDifferentiator i
      * <p>
      * If the differentiator has not been created yet, it will be created here.
      * </p>
-     * @param primitiveClass primitive class to differentiate
-     * @return differentiator for {@code primitiveClass}
+     * @param element specification of the element to differentiate
+     * @return differentiator for {@code element}
      * @throws DifferentiationException if the class cannot be read
      */
-    private ClassDifferentiator getDifferentiator(Class<?> primitiveClass)
+    private ClassDifferentiator getDifferentiator(final DifferentiatedElementSpecification element)
         throws DifferentiationException {
         try {
 
             // find a differentiator for the class owning the method
             for (ClassDifferentiator differentiator : differentiators) {
-                if (Type.getInternalName(primitiveClass).equals(differentiator.getPrimitiveName())) {
+                if (element.getPrimitiveSpec().getPrimitiveClass().equals(differentiator.getPrimitiveInternalName())) {
                     // we have already build a differentiator for the same class, reuse it
                     return differentiator;
                 }
             }
 
             // it is the first time we process this class, create a differentiator for it
-            final ClassDifferentiator differentiator = new ClassDifferentiator(primitiveClass, mathClasses, this);
+            final ClassDifferentiator differentiator =
+                    new ClassDifferentiator(element.getPrimitiveSpec().getPrimitiveClass(), mathClasses, this);
             differentiators.add(differentiator);
+
+            // the new class may use some already monitored fields, we need to update the map
+            for (final Map.Entry<DifferentiatedElementSpecification, List<PrimitiveElementSpecification>> entry : fieldsUsers.entrySet()) {
+                entry.getValue().addAll(differentiator.getMethodsUsingField(entry.getKey()));
+            }
+
             return differentiator;
 
             
         } catch (IOException ioe) {
             throw new DifferentiationException(NablaMessages.CANNOT_READ_CLASS,
-                                               primitiveClass.getName(), ioe.getMessage());
+                                               element.getPrimitiveSpec().getPrimitiveClass(), ioe.getMessage());
         }
     }
 

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java?rev=1404268&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java Wed Oct 31 17:48:21 2012
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward;
+
+import org.objectweb.asm.Type;
+
+/** Partial specification for an element (field or method) to differentiate.
+ * @version $Id$
+ */
+public class PrimitiveElementSpecification {
+
+    /** Name of the element. */
+    private final String name;
+
+    /** Indicator for static elemnt. */
+    private final boolean isStatic;
+
+    /** Internal name of the primitive class to which the element belongs. */
+    private final String primitiveClass;
+
+    /** Type of the element in the primitive class. */
+    private final Type primitiveType;
+
+    /** Simple constructor.
+     * @param name element name
+     * @param isStatic if true, the element is static
+     * @param primitiveClass internal name of the class in which the element is defined
+     * @param primitiveType element type in the primitive
+     */
+    public PrimitiveElementSpecification(final String name, final boolean isStatic,
+                                         final String primitiveClass, final Type primitiveType) {
+        this.name           = name;
+        this.isStatic       = isStatic;
+        this.primitiveClass = primitiveClass;
+        this.primitiveType  = primitiveType;
+    }
+
+    /** Get the name of the element.
+     * @return name of the element
+     */
+    public String getName() {
+        return name;
+    }
+
+    /** Get the static indicator of the element.
+     * @return static indicator of the element
+     */
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    /** Get the internal name of the primitive class to which the element belongs.
+     * @return internal name of the primitive class to which the element belongs
+     */
+    public String getPrimitiveClass() {
+        return primitiveClass;
+    }
+
+    /** Get the type of the element in the primitive class.
+     * @return type of the element in the primitive class
+     */
+    public Type getPrimitiveType() {
+        return primitiveType;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(final Object other) {
+
+        if (this == other) {
+            return true;
+        }
+
+        if (other instanceof PrimitiveElementSpecification) {
+            PrimitiveElementSpecification de = (PrimitiveElementSpecification) other;
+            return name.equals(de.name)                     &&
+                   (isStatic == de.isStatic)                &&
+                   primitiveClass.equals(de.primitiveClass) &&
+                   primitiveType.equals(de.primitiveType);
+        }
+
+        return false;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        // the following coefficients are arbitrarily chosen prime numbers
+        return 547 * name.hashCode() +
+               457 * Boolean.valueOf(isStatic).hashCode() +
+               311 * primitiveClass.hashCode() +
+               643 * primitiveType.hashCode();
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/PrimitiveElementSpecification.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/ClassDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/ClassDifferentiator.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/ClassDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/ClassDifferentiator.java Wed Oct 31 17:48:21 2012
@@ -17,14 +17,17 @@
 package org.apache.commons.nabla.forward.analysis;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.commons.math3.analysis.UnivariateFunction;
 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.NablaMessages;
-import org.apache.commons.nabla.forward.DifferentiableField;
-import org.apache.commons.nabla.forward.DifferentiableMethod;
+import org.apache.commons.nabla.forward.PrimitiveElementSpecification;
+import org.apache.commons.nabla.forward.DifferentiatedElementSpecification;
 import org.apache.commons.nabla.forward.ForwardModeDifferentiator;
 import org.apache.commons.nabla.forward.NablaDifferentiated;
 import org.apache.commons.nabla.forward.NablaUnivariateDifferentiableFunction;
@@ -32,7 +35,9 @@ import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldInsnNode;
 import org.objectweb.asm.tree.FieldNode;
 import org.objectweb.asm.tree.MethodNode;
 
@@ -54,12 +59,15 @@ public class ClassDifferentiator {
     /** Name fo the constructor methods. */
     private static final String INIT = "<init>";
 
-    /** Suffix for differentiated classes. */
-    private static final String CLASS_SUFFIX = "_NablaForwardModeDifferentiated";
+    /** Prefix for fields getters. */
+    private static final String GETTER_PREFIX = "get_Nabla_";
 
     /** Math implementation classes. */
     private final Set<String> mathClasses;
 
+    /** Name of the class to differentiate. */
+    private final String primitiveInternalName;
+
     /** Node of the class to differentiate. */
     private final ClassNode primitiveNode;
 
@@ -71,21 +79,21 @@ public class ClassDifferentiator {
 
     /**
      * Simple constructor.
-     * @param primitiveClass primitive class
+     * @param primitiveInternalName internal name of the primitive class
      * @param mathClasses math implementation classes
      * @param forwardDifferentiator global differentiator
      * @exception DifferentiationException if class cannot be differentiated
      * @throws IOException if class cannot be read
      */
-    public ClassDifferentiator(final Class<?> primitiveClass, final Set<String> mathClasses,
+    public ClassDifferentiator(final String primitiveInternalName, final Set<String> mathClasses,
                                final ForwardModeDifferentiator forwardDifferentiator)
         throws DifferentiationException, IOException {
 
+        this.primitiveInternalName = primitiveInternalName;
         this.forwardDifferentiator = forwardDifferentiator;
 
         // get the original class
-        final ClassReader reader =
-                new ClassReader(primitiveClass.getResourceAsStream("/" + Type.getInternalName(primitiveClass) + ".class"));
+        final ClassReader reader = new ClassReader(primitiveInternalName);
         primitiveNode = new ClassNode(Opcodes.ASM4);
         reader.accept(primitiveNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
         this.mathClasses = mathClasses;
@@ -115,7 +123,8 @@ public class ClassDifferentiator {
                                Type.getType(NablaUnivariateDifferentiableFunction.class) :
                                Type.getType(NablaDifferentiated.class);
         classNode.visit(primitiveNode.version, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
-                        getDerivedName(), null, superType.getInternalName(), new String[0]);
+                        getDifferentiatedInternalName(getPrimitiveInternalName()),
+                        null, superType.getInternalName(), new String[0]);
 
     }
 
@@ -123,14 +132,14 @@ public class ClassDifferentiator {
      * @return name of the primitive class
      */
     public String getPrimitiveName() {
-        return primitiveNode.name;
+        return primitiveInternalName.replace('/', '.');
     }
 
-    /** Get the name of the derived class.
-     * @return name of the derived class
+    /** Get the internal name of the primitive class.
+     * @return internal name of the primitive class
      */
-    public String getDerivedName() {
-        return primitiveNode.name  + CLASS_SUFFIX;
+    public String getPrimitiveInternalName() {
+        return primitiveInternalName;
     }
 
     /** Get the derived class node.
@@ -173,32 +182,76 @@ public class ClassDifferentiator {
 
     /**
      * Differentiate a method.
-     * @param differentiableMethod method to differentiate
+     * @param differentiatedMethod method to differentiate
      * @exception DifferentiationException if method cannot be differentiated
      */
-    public void differentiateMethod(final DifferentiableMethod differentiableMethod)
+    public void differentiateMethod(final DifferentiatedElementSpecification differentiatedMethod)
         throws DifferentiationException {
 
         for (final MethodNode primitiveMethod : primitiveNode.methods) {
-            if (primitiveMethod.name.equals(differentiableMethod.getMethod()) &&
-                Type.getType(primitiveMethod.desc).equals(differentiableMethod.getPrimitiveMethodType())) {
+            if (primitiveMethod.name.equals(differentiatedMethod.getPrimitiveSpec().getName()) &&
+                Type.getType(primitiveMethod.desc).equals(differentiatedMethod.getPrimitiveSpec().getPrimitiveType())) {
 
                 final MethodDifferentiator differentiator = new MethodDifferentiator(mathClasses, this);
-                final MethodNode differentiatedMethod =
-                        differentiator.differentiate(primitiveMethod,
-                                                     differentiableMethod.getPrimitiveMethodType(),
-                                                     differentiableMethod.getDifferentiatedMethodType());
-                classNode.methods.add(differentiatedMethod);
-
+                final MethodNode differentiatedNode =
+                        differentiator.differentiate(primitiveMethod, differentiatedMethod);
+                classNode.methods.add(differentiatedNode);
+                return;
             }
         }
 
     }
 
-    /** Clear all differentiated methods.
+    /** Clear a differentiated method.
+     * <p>
+     * Clearing a differentiated method is used mainly when it uses a field
+     * that was once thought to not be affected by differentiation but
+     * afterwards appear to be differentiated too. So the method access to the
+     * now differentiated field needs to be updated by differentiating the
+     * method again taking the proper information into account.
+     * </p>
+     * @param method differentiated method to clear
      */
-    public void clearDifferentiatedMethods() {
-        classNode.methods.clear();
+    public void clearDifferentiatedElement(final DifferentiatedElementSpecification method) {
+        for (final Iterator<MethodNode> iterator = classNode.methods.iterator(); iterator.hasNext();) {
+            final MethodNode current = iterator.next();
+            if (current.name.equals(method.getPrimitiveSpec().getName()) &&
+                Type.getMethodType(current.desc).equals(method.getDifferentiatedType())) {
+                iterator.remove();
+            }
+        }
+    }
+
+    /** Get all methods that use a field.
+     * @param differentiatedField field to check methods against
+     * @return a list of all methods that uses the specified field, with the {@link
+     * PrimitiveElementSpecification#getDifferentiatedElementType() differentiated method type}
+     * set to null as it is not known yet
+     */
+    public List<PrimitiveElementSpecification> getMethodsUsingField(final DifferentiatedElementSpecification differentiatedField) {
+
+        List<PrimitiveElementSpecification> users = new ArrayList<PrimitiveElementSpecification>();
+        final String owner = differentiatedField.getPrimitiveSpec().getPrimitiveClass();
+        final String name  = differentiatedField.getPrimitiveSpec().getName();
+        final String desc  = differentiatedField.getPrimitiveSpec().getPrimitiveType().getDescriptor();
+
+        for (final MethodNode primitiveMethod : primitiveNode.methods) {
+            for (Iterator<AbstractInsnNode> iterator = primitiveMethod.instructions.iterator(); iterator.hasNext();) {
+                final AbstractInsnNode insn = iterator.next();
+                if (insn.getType() == AbstractInsnNode.FIELD_INSN) {
+                    final FieldInsnNode fInsn = (FieldInsnNode) insn;
+                    if (fInsn.owner.equals(owner) && fInsn.name.equals(name) && fInsn.desc.equals(desc)) {
+                        final Type primitiveMethodType = Type.getMethodType(primitiveMethod.desc);
+                        users.add(new PrimitiveElementSpecification(primitiveMethod.name,
+                                                                    (primitiveMethod.access & Opcodes.ACC_STATIC) != 0,
+                                                                    getPrimitiveInternalName(), primitiveMethodType));
+                    }
+                }
+            }
+        }
+
+        return users;
+
     }
 
     /**
@@ -206,19 +259,19 @@ public class ClassDifferentiator {
      * @param differentiableField field to differentiate
      * @exception DifferentiationException if field cannot be differentiated
      */
-    public void differentiateField(final DifferentiableField differentiableField)
+    public void differentiateField(final DifferentiatedElementSpecification differentiableField)
         throws DifferentiationException {
 
         // set up the field itself
         classNode.fields.add(new FieldNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL,
-                                           differentiableField.getField(),
-                                           differentiableField.getDifferentiatedFieldType().getDescriptor(),
+                                           differentiableField.getPrimitiveSpec().getName(),
+                                           differentiableField.getDifferentiatedType().getDescriptor(),
                                            null, null));
 
         // get the access mode of the original field
         int access = 0;
         for (final FieldNode fieldNode : primitiveNode.fields) {
-            if (fieldNode.name.equals(differentiableField.getField())) {
+            if (fieldNode.name.equals(differentiableField.getPrimitiveSpec().getName())) {
                 access = fieldNode.access;
             }
         }
@@ -234,16 +287,19 @@ public class ClassDifferentiator {
         //    }
         final Type dsType = Type.getType(DerivativeStructure.class);
         final MethodNode getter =
-                new MethodNode(access | Opcodes.ACC_SYNTHETIC, "get_" + differentiableField.getField(),
+                new MethodNode(access | Opcodes.ACC_SYNTHETIC,
+                               GETTER_PREFIX + differentiableField.getPrimitiveSpec().getName(),
                                Type.getMethodDescriptor(dsType, Type.INT_TYPE, Type.INT_TYPE),
                                null, null);
         getter.visitVarInsn(Opcodes.ALOAD, 0);
-        if (differentiableField.isStatic()) {
-            getter.visitFieldInsn(Opcodes.GETSTATIC, classNode.name, differentiableField.getField(),
-                                  differentiableField.getDifferentiatedFieldType().getDescriptor());
+        if (differentiableField.getPrimitiveSpec().isStatic()) {
+            getter.visitFieldInsn(Opcodes.GETSTATIC, getDifferentiatedInternalName(getPrimitiveInternalName()),
+                                  differentiableField.getPrimitiveSpec().getName(),
+                                  differentiableField.getDifferentiatedType().getDescriptor());
         } else {
-            getter.visitFieldInsn(Opcodes.GETFIELD, classNode.name, differentiableField.getField(),
-                                  differentiableField.getDifferentiatedFieldType().getDescriptor());
+            getter.visitFieldInsn(Opcodes.GETFIELD, getDifferentiatedInternalName(getPrimitiveInternalName()),
+                                  differentiableField.getPrimitiveSpec().getName(),
+                                  differentiableField.getDifferentiatedType().getDescriptor());
         }
         Label ifNonNull = new Label();
         getter.visitJumpInsn(Opcodes.IFNONNULL, ifNonNull);
@@ -253,8 +309,8 @@ public class ClassDifferentiator {
         getter.visitVarInsn(Opcodes.ILOAD, 1);
         getter.visitVarInsn(Opcodes.ILOAD, 2);
         getter.visitVarInsn(Opcodes.ALOAD, 0);
-        getter.visitLdcInsn(differentiableField.getField());
-        getter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNode.name,
+        getter.visitLdcInsn(differentiableField.getPrimitiveSpec().getName());
+        getter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getDifferentiatedInternalName(getPrimitiveInternalName()),
                                "getPrimitiveField", Type.getMethodDescriptor(Type.getType(Object.class),
                                                                              Type.getType(String.class)));
         final Type doubleType = Type.getType(Double.class);
@@ -264,22 +320,24 @@ public class ClassDifferentiator {
         getter.visitMethodInsn(Opcodes.INVOKESPECIAL, dsType.getInternalName(), INIT,
                                Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.DOUBLE_TYPE));
 
-        if (differentiableField.isStatic()) {
-            getter.visitFieldInsn(Opcodes.PUTSTATIC, classNode.name, differentiableField.getField(),
+        if (differentiableField.getPrimitiveSpec().isStatic()) {
+            getter.visitFieldInsn(Opcodes.PUTSTATIC, getDifferentiatedInternalName(getPrimitiveInternalName()),
+                                  differentiableField.getPrimitiveSpec().getName(),
                                   dsType.getDescriptor());
         } else {
-            getter.visitFieldInsn(Opcodes.PUTFIELD, classNode.name, differentiableField.getField(),
+            getter.visitFieldInsn(Opcodes.PUTFIELD, getDifferentiatedInternalName(getPrimitiveInternalName()),
+                                  differentiableField.getPrimitiveSpec().getName(),
                                   dsType.getDescriptor());
         }
 
         getter.visitLabel(ifNonNull);
 
         getter.visitVarInsn(Opcodes.ALOAD, 0);
-        if (differentiableField.isStatic()) {
-            getter.visitFieldInsn(Opcodes.GETSTATIC, classNode.name, differentiableField.getField(),
+        if (differentiableField.getPrimitiveSpec().isStatic()) {
+            getter.visitFieldInsn(Opcodes.GETSTATIC, classNode.name, differentiableField.getPrimitiveSpec().getName(),
                                   dsType.getDescriptor());
         } else {
-            getter.visitFieldInsn(Opcodes.GETFIELD, classNode.name, differentiableField.getField(),
+            getter.visitFieldInsn(Opcodes.GETFIELD, classNode.name, differentiableField.getPrimitiveSpec().getName(),
                                   dsType.getDescriptor());
         }
 
@@ -289,34 +347,42 @@ public class ClassDifferentiator {
 
     }
 
+    /** Get the internal name of a differentiated class.
+     * @param primitiveInternalName internal name of the primitive class
+     * @return internal name of the corresponding differentiated class
+     */
+    public String getDifferentiatedInternalName(final String primitiveInternalName) {
+        return forwardDifferentiator.getDifferentiatedInternalName(primitiveInternalName);
+    }
+
+    /** Check if a method uses a differentiated field.
+     * @param method differentiable method to check
+     * @return a differentiated field used by the method, null if it does not use any differentiated fields
+     */
+    public DifferentiatedElementSpecification getUsedDifferentiatedField(final PrimitiveElementSpecification method) {
+        return forwardDifferentiator.getUsedDifferentiatedField(method);
+    }
+
     /** Request differentiation of a method.
-     * @param owner class in which the method is defined
-     * @param isStatic if true, the method is static
-     * @param method method name
-     * @param primitiveMethodType method type in the primitive (includes return and arguments types)
-     * @param differentiatedMethodType method type in the differentiated class (includes return and arguments types)
-     * @exception DifferentiationException if class cannot be found
-     */
-    public void requestMethodDifferentiation(final String owner, final boolean isStatic,
-                                             final String method, final Type primitiveMethodType,
-                                             final Type differentiatedMethodType) {
-        forwardDifferentiator.requestMethodDifferentiation(owner, isStatic,
-                                                           method, primitiveMethodType, differentiatedMethodType);
+     * @param method method to differentiate
+     */
+    public void requestMethodDifferentiation(final DifferentiatedElementSpecification method) {
+        forwardDifferentiator.requestMethodDifferentiation(method);
+    }
+
+    /** Get a differentiated element.
+     * @param primitive primitive specification to check
+     * @return a differentiated element corresponding to the primitive, null if no elements correspond
+     */
+    public DifferentiatedElementSpecification getDifferentiated(final PrimitiveElementSpecification primitive) {
+        return forwardDifferentiator.getDifferentiated(primitive);
     }
 
     /** Request differentiation of a field.
-     * @param owner class in which the field is defined
-     * @param isStatic if true, the field is static
-     * @param field field name
-     * @param primitiveFieldType field type in the primitive
-     * @param differentiatedFieldType field type in the differentiated class
-     * @exception DifferentiationException if class cannot be found
-     */
-    public void requestFieldDifferentiation(final String owner, final boolean isStatic,
-                                            final String field, final Type primitiveFieldType,
-                                            final Type differentiatedFieldType) {
-        forwardDifferentiator.requestFieldDifferentiation(owner, isStatic, field,
-                                                          primitiveFieldType, differentiatedFieldType);
+     * @param field field to differentiate
+     */
+    public void requestFieldDifferentiation(final DifferentiatedElementSpecification field) {
+        forwardDifferentiator.requestFieldDifferentiation(field);
     }
 
 }

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java Wed Oct 31 17:48:21 2012
@@ -28,6 +28,8 @@ import java.util.Set;
 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.NablaMessages;
+import org.apache.commons.nabla.forward.PrimitiveElementSpecification;
+import org.apache.commons.nabla.forward.DifferentiatedElementSpecification;
 import org.apache.commons.nabla.forward.arithmetic.DAddTransformer;
 import org.apache.commons.nabla.forward.arithmetic.DDivTransformer;
 import org.apache.commons.nabla.forward.arithmetic.DMulTransformer;
@@ -53,6 +55,7 @@ import org.apache.commons.nabla.forward.
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
 import org.objectweb.asm.tree.IincInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
@@ -99,37 +102,29 @@ public class MethodDifferentiator {
         this.successors          = new IdentityHashMap<AbstractInsnNode, Set<AbstractInsnNode>>();
     }
 
-    /** Get the name of the primitive class.
-     * @return name of the primitive class
+    /** Get the internal name of the primitive class.
+     * @return internal name of the primitive class
      */
-    public String getPrimitiveName() {
-        return classDifferentiator.getPrimitiveName();
-    }
-
-    /** Get the name of the derived class.
-     * @return name of the derived class
-     */
-    public String getDerivedName() {
-        return classDifferentiator.getDerivedName();
+    public String getPrimitiveInternalName() {
+        return classDifferentiator.getPrimitiveInternalName();
     }
 
     /**
      * Differentiate a method.
      * @param primitiveMethod method to differentiate
-     * @param primitiveMethodType type of the method in the primitive class
-     * @param derivedMethodType type of the derived method
+     * @param differentiatedMethod specification for the differentiated method
      * @return differentiated method
      * @exception DifferentiationException if method cannot be differentiated
      */
     public MethodNode differentiate(final MethodNode primitiveMethod,
-                                    final Type primitiveMethodType, final Type derivedMethodType)
+                                    final DifferentiatedElementSpecification differentiatedMethod)
         throws DifferentiationException {
         try {
 
             // copy the primitive method as a new independent node
             final MethodNode method =
                     new MethodNode(primitiveMethod.access | Opcodes.ACC_SYNTHETIC,
-                                   primitiveMethod.name, derivedMethodType.getDescriptor(),
+                                   primitiveMethod.name, differentiatedMethod.getDifferentiatedType().getDescriptor(),
                                    null, primitiveMethod.exceptions.toArray(new String[primitiveMethod.exceptions.size()]));
             primitiveMethod.accept(method);
 
@@ -139,7 +134,7 @@ public class MethodDifferentiator {
             // analyze the original code, tracing values production/consumption
             final FlowAnalyzer analyzer =
                 new FlowAnalyzer(new TrackingInterpreter(), method.instructions);
-            final Frame<TrackingValue>[] array = analyzer.analyze(getPrimitiveName(), method);
+            final Frame<TrackingValue>[] array = analyzer.analyze(getPrimitiveInternalName(), method);
 
             // convert the array into a map, since code changes will shift all indices
             for (int i = 0; i < array.length; ++i) {
@@ -148,8 +143,9 @@ public class MethodDifferentiator {
 
             // identify the needed changes in code
             Set<AbstractInsnNode> changes =
-                    identifyChanges(method.name, usedLocals, primitiveMethodType.getArgumentTypes(),
-                                    derivedMethodType.getArgumentTypes(),
+                    identifyChanges(method.name, usedLocals,
+                                    differentiatedMethod.getPrimitiveSpec().getPrimitiveType().getArgumentTypes(),
+                                    differentiatedMethod.getDifferentiatedType().getArgumentTypes(),
                                     method.instructions, isStatic);
 
             // perform the code changes
@@ -168,8 +164,8 @@ public class MethodDifferentiator {
             if (usedLocals[usedLocals.length - 1]) {
                 // insert the preservation of the reference derivative structure
                 // (we know we have reserved the last local variable for this)
-                method.instructions.insert(preserveReferenceDerivativeStructure(derivedMethodType, isStatic,
-                                                                                usedLocals.length - 1));
+                method.instructions.insert(preserveReferenceDerivativeStructure(differentiatedMethod,
+                                                                                isStatic, usedLocals.length - 1));
             }
 
             // remove the local variables added at the beginning and not used
@@ -190,7 +186,7 @@ public class MethodDifferentiator {
                 throw (DifferentiationException) ae.getCause();
             } else {
                 throw new DifferentiationException(NablaMessages.UNABLE_TO_ANALYZE_METHOD,
-                                                   getPrimitiveName(), primitiveMethod.name, ae.getMessage());
+                                                   getPrimitiveInternalName(), primitiveMethod.name, ae.getMessage());
             }
         }
     }
@@ -249,34 +245,76 @@ public class MethodDifferentiator {
 
     }
 
-    /** Request differentiation of a method.
-     * @param owner class in which the method is defined
+    /** Get the internal name of a differentiated class.
+     * @param primitiveInternalName internal name of the primitive class
+     * @return internal name of the corresponding differentiated class
+     */
+    public String getDifferentiatedInternalName(final String primitiveInternalName) {
+        return classDifferentiator.getDifferentiatedInternalName(primitiveInternalName);
+    }
+
+    /** Check if a method uses a differentiated field.
+     * @param method method name
      * @param isStatic if true, the method is static
+     * @param owner class in which the method is defined
+     * @param primitiveMethodType method type in the primitive (includes return and arguments types)
+     * @return a differentiated field used by the method, null if it does not use any differentiated fields
+     */
+    public DifferentiatedElementSpecification getUsedDifferentiatedField(final String method,
+                                                                         final boolean isStatic,
+                                                                         final String owner,
+                                                                         final Type primitiveMethodType) {
+        final PrimitiveElementSpecification dm =
+                new PrimitiveElementSpecification(method, isStatic, owner, primitiveMethodType);
+        return classDifferentiator.getUsedDifferentiatedField(dm);
+    }
+
+    /** Request differentiation of a method.
      * @param method method name
+     * @param isStatic if true, the method is static
+     * @param owner class in which the method is defined
      * @param primitiveMethodType method type in the primitive (includes return and arguments types)
      * @param differentiatedMethodType method type in the differentiated class (includes return and arguments types)
-     * @exception DifferentiationException if class cannot be found
      */
-    public void requestMethodDifferentiation(final String owner, final boolean isStatic,
-                                             final String method, final Type primitiveMethodType,
+    public void requestMethodDifferentiation(final String method, final boolean isStatic,
+                                             final String owner, final Type primitiveMethodType,
                                              final Type differentiatedMethodType) {
-        classDifferentiator.requestMethodDifferentiation(owner, isStatic, method,
-                                                         primitiveMethodType, differentiatedMethodType);
+            final DifferentiatedElementSpecification dm =
+                    new DifferentiatedElementSpecification(method, isStatic, owner,
+                                              primitiveMethodType, differentiatedMethodType);
+            classDifferentiator.requestMethodDifferentiation(dm);
     }
 
-    /** Request differentiation of a field.
-     * @param owner class in which the field is defined
+    /** Get a differentiated element.
+     * @param name element name
      * @param isStatic if true, the field is static
+     * @param owner class in which the field is defined
+     * @param primitiveType element type in the primitive
+     * @param differentiatedType element type in the differentiated class
+     * @return a differentiated element corresponding to the primitive, null if no elements correspond
+     */
+    public DifferentiatedElementSpecification getDifferentiated(final String name, final boolean isStatic,
+                                                                final String owner, final Type primitiveType) {
+        final PrimitiveElementSpecification primitive =
+                new PrimitiveElementSpecification(name, isStatic, owner, primitiveType);
+        return classDifferentiator.getDifferentiated(primitive);
+    }
+
+    /** Request differentiation of a field.
      * @param field field name
+     * @param isStatic if true, the field is static
+     * @param owner class in which the field is defined
      * @param primitiveFieldType field type in the primitive
      * @param differentiatedFieldType field type in the differentiated class
-     * @exception DifferentiationException if class cannot be found
      */
-    public void requestFieldDifferentiation(final String owner, final boolean isStatic,
-                                            final String field, final Type primitiveFieldType,
+    public void requestFieldDifferentiation(final String field, final boolean isStatic,
+                                            final String owner, final Type primitiveFieldType,
                                             final Type differentiatedFieldType) {
-        classDifferentiator.requestFieldDifferentiation(owner, isStatic, field,
-                                                        primitiveFieldType, differentiatedFieldType);
+            final DifferentiatedElementSpecification df =
+                    new DifferentiatedElementSpecification(field, isStatic,
+                                                           owner, primitiveFieldType,
+                                                           differentiatedFieldType);
+            classDifferentiator.requestFieldDifferentiation(df);
     }
 
     /** Identify the instructions that must be changed.
@@ -288,10 +326,8 @@ public class MethodDifferentiator {
      * </p>
      * <ul>
      *   <li>the ones that consume changed variables or stack cells,</li>
-     *   <li>the GETFIELD/PUTFIELD instruction as they must access the
-     *       primitive instance fields,</li>
-     *   <li>the GETSTATIC/PUTSTATIC instruction as they must access the
-     *       primitive class fields,</li>
+     *   <li>the invoke instructions for methods that use differentiated fields,</li>
+     *   <li>the fields instructions as they must access the primitive instance or class fields,</li>
      *   <li>all DRETURN instructions (regardless of the returned value being
      *       converted or not, as in some branch codes the value may return
      *       simple constants like "return 0").</li>
@@ -312,14 +348,19 @@ public class MethodDifferentiator {
 
         // the pending set contains the values (local variables or stack cells) that have
         // been changed, they will trigger changes on the instructions that consume them,
-        // we bootstrap the analysis by looking at changed method arguments
+        // we bootstrap the analysis by looking at:
+        //   - changed method arguments
+        //   - changed return values of transformed methods
+        //   - changed fields
         final Set<TrackingValue> pending =
-                identifyArguments(isStatic, instructions, primitiveArguments, derivedArguments, usedLocals);
+                identifyChangedArguments(isStatic, instructions, primitiveArguments, derivedArguments, usedLocals);
+        pending.addAll(identifyChangedMethods(instructions));
+        pending.addAll(identifyChangedFields(instructions));
 
         // the changes set contains the instructions that must be changed
         final Set<AbstractInsnNode> changes = new HashSet<AbstractInsnNode>();
 
-        // propagate the values conversions throughout the method
+        // propagate the values conversions throughout the method using flow analysis
         while (!pending.isEmpty()) {
 
             // pop one element from the set of changed values
@@ -352,14 +393,24 @@ public class MethodDifferentiator {
             }
         }
 
-        // the various GETFIELD/PUTFIELD/GETSTATIC/PUTSTATIC/DRETURN instructions must also be changed
-        final ListIterator<AbstractInsnNode> iterator = instructions.iterator();
-        while (iterator.hasNext()) {
-            final AbstractInsnNode ins = iterator.next();
-            if ((ins.getOpcode() == Opcodes.GETFIELD)  || (ins.getOpcode() == Opcodes.PUTFIELD) ||
-                (ins.getOpcode() == Opcodes.GETSTATIC) || (ins.getOpcode() == Opcodes.PUTSTATIC) ||
-                (ins.getOpcode() == Opcodes.DRETURN)) {
-                changes.add(ins);
+        for (final ListIterator<AbstractInsnNode> iterator = instructions.iterator(); iterator.hasNext();) {
+            final AbstractInsnNode insn = iterator.next();
+            if (insn.getType() == AbstractInsnNode.FIELD_INSN) {
+                // the fields instructions must be changed
+                changes.add(insn);
+            } else if (insn.getType() == AbstractInsnNode.METHOD_INSN) {
+                final MethodInsnNode methodInsn = (MethodInsnNode) insn;
+                if (getUsedDifferentiatedField(methodInsn.name, insn.getOpcode() == Opcodes.INVOKESTATIC,
+                                               methodInsn.owner, Type.getMethodType(methodInsn.desc)) != null) {
+                    // the invoke instructions on methods that use differentiated fields must be changed
+                    changes.add(insn);
+                }
+            } else if (insn.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) {
+                // TODO: add support for INVOKE_DYNAMIC
+                throw new DifferentiationException(NablaMessages.INVOKE_DYNAMIC_NOT_HANDLED_YET, getPrimitiveInternalName());
+            } else if (insn.getOpcode() == Opcodes.DRETURN) {
+                // the DRETURN instructions must be changed
+                changes.add(insn);
             }
         }
 
@@ -375,7 +426,7 @@ public class MethodDifferentiator {
      * @param usedLocals array of variables use indicators to fill in
      * @return set of argument local variables that are changed
      */
-    private Set<TrackingValue> identifyArguments(final boolean isStatic, final InsnList instructions,
+    private Set<TrackingValue> identifyChangedArguments(final boolean isStatic, final InsnList instructions,
                                                  final Type[] primitiveArguments, final Type[] derivedArguments,
                                                  final boolean[] usedLocals) {
 
@@ -450,6 +501,96 @@ public class MethodDifferentiator {
 
     }
 
+    /** Identify how method invocations are used.
+     * @param instructions instructions of the method
+     * @return set of stack values that are changed
+     */
+    private Set<TrackingValue> identifyChangedMethods(final InsnList instructions) {
+
+        final Set<TrackingValue> changedValues = new HashSet<TrackingValue>();
+
+        for (final ListIterator<AbstractInsnNode> iterator = instructions.iterator(); iterator.hasNext();) {
+            final AbstractInsnNode insn = iterator.next();
+            if (insn.getType() == AbstractInsnNode.METHOD_INSN) {
+                final MethodInsnNode methodInsn = (MethodInsnNode) insn;
+                final DifferentiatedElementSpecification de =
+                        getDifferentiated(methodInsn.name,
+                                          methodInsn.getOpcode() == Opcodes.INVOKESTATIC,
+                                          methodInsn.owner, Type.getType(methodInsn.desc));
+                if (de != null) {
+
+                    final Type pReturn = de.getPrimitiveSpec().getPrimitiveType().getReturnType();
+                    final Type dReturn = de.getDifferentiatedType().getReturnType();
+                    if (!pReturn.equals(dReturn)) {
+                        // the invocation produces a value that is changed
+                        // the produced value is on the top of the instruction successors frame
+                        for (final AbstractInsnNode s : successors.get(methodInsn)) {
+                            final Frame<TrackingValue> frame = frames.get(s);
+                            final TrackingValue stackTop = frame.getStack(frame.getStackSize() - 1);
+                            changedValues.add(stackTop);
+                        }
+                    }
+
+                    final Type[] pArgs = de.getPrimitiveSpec().getPrimitiveType().getArgumentTypes();
+                    final Type[] dArgs = de.getDifferentiatedType().getArgumentTypes();
+                    final Frame<TrackingValue> frame = frames.get(methodInsn);
+                    for (int i = 0; i < pArgs.length; ++i) {
+                        if (!pArgs[i].equals(dArgs[i])){
+                            // the invocation consumes a value that is changed
+                            // the consumed value is on the instruction own frame
+                            final TrackingValue stackElement = frame.getStack(frame.getStackSize() - (pArgs.length - i));
+                            changedValues.add(stackElement);
+                        }
+                    }
+                }
+            }
+        }
+
+        return changedValues;
+
+    }
+
+    /** Identify how fields are used.
+     * @param instructions instructions of the method
+     * @return set of stack values that are changed
+     */
+    private Set<TrackingValue> identifyChangedFields(final InsnList instructions) {
+
+        final Set<TrackingValue> changedValues = new HashSet<TrackingValue>();
+
+        for (final ListIterator<AbstractInsnNode> iterator = instructions.iterator(); iterator.hasNext();) {
+            final AbstractInsnNode insn = iterator.next();
+            if (insn.getType() == AbstractInsnNode.FIELD_INSN) {
+                final FieldInsnNode fieldInsn = (FieldInsnNode) insn;
+                final DifferentiatedElementSpecification de =
+                        getDifferentiated(fieldInsn.name,
+                                          fieldInsn.getOpcode() == Opcodes.GETSTATIC ||
+                                          fieldInsn.getOpcode() == Opcodes.PUTSTATIC,
+                                          fieldInsn.owner, Type.getType(fieldInsn.desc));
+                if (de != null) {
+                    if (fieldInsn.getOpcode() == Opcodes.GETFIELD || fieldInsn.getOpcode() == Opcodes.GETSTATIC) {
+                        // this is a get instruction, it produces a value that is changed
+                        // the produced value is on the top of the instruction successors frame
+                        for (final AbstractInsnNode s : successors.get(fieldInsn)) {
+                            final Frame<TrackingValue> frame = frames.get(s);
+                            final TrackingValue stackTop = frame.getStack(frame.getStackSize() - 1);
+                            changedValues.add(stackTop);
+                        }
+                    } else {
+                        // this is a put instruction, it consumes a value that is changed
+                        // the consumed value is on the top of the instruction own frame
+                        final Frame<TrackingValue> frame = frames.get(fieldInsn);
+                        final TrackingValue stackTop = frame.getStack(frame.getStackSize() - 1);
+                        changedValues.add(stackTop);
+                    }
+                }
+            }
+        }
+
+        return changedValues;
+
+    }
+
     /** Get the list of double values produced by an instruction and not yet converted.
      * @param instruction instruction producing the values
      * @return list of double values produced
@@ -608,7 +749,7 @@ public class MethodDifferentiator {
             }
             case Opcodes.INVOKEDYNAMIC :
                 // TODO: add support for INVOKEDYNAMIC differentiation
-                throw new RuntimeException("INVOKEDYNAMIC not handled yet");
+                throw new DifferentiationException(NablaMessages.INVOKE_DYNAMIC_NOT_HANDLED_YET, getPrimitiveInternalName());
             case Opcodes.NEWARRAY :
                 // TODO: add support for NEWARRAY differentiation
                 throw new RuntimeException("NEWARRAY not handled yet");
@@ -625,16 +766,16 @@ public class MethodDifferentiator {
     }
 
     /** Create instructions to preserve a reference {@link DerivativeStructure} variable.
-     * @param derivedMethodType type of the derived method
+     * @param differentiatedMethod specification for the differentiated method
      * @param isStatic if true, the method is a static method
      * @param dsIndex index of the reference {@link DerivativeStructure derivative structure} variable
      * @return list of conversion instructions
      */
-    public InsnList preserveReferenceDerivativeStructure(final Type derivedMethodType,
+    public InsnList preserveReferenceDerivativeStructure(final DifferentiatedElementSpecification differentiatedMethod,
                                                          final boolean isStatic, final int dsIndex) {
 
         final Type dsType = Type.getType(DerivativeStructure.class);
-        final Type[] parameterTypes = derivedMethodType.getArgumentTypes();
+        final Type[] parameterTypes = differentiatedMethod.getDifferentiatedType().getArgumentTypes();
         int var = isStatic ? 0 : 1;
         for (int i = 0; i < parameterTypes.length; ++i) {
             if (parameterTypes[i].equals(dsType)) {
@@ -645,14 +786,37 @@ public class MethodDifferentiator {
                 list.add(new VarInsnNode(Opcodes.ALOAD, var));
                 list.add(new VarInsnNode(Opcodes.ASTORE, dsIndex));
                 return list;
+
             } else {
                 var += parameterTypes[i].getSize();
             }
 
         }
 
-        // this should never happen as we build class that do use DerivativeStructure
-        throw DifferentiationException.createInternalError(null);
+        // if we reach this point, this means there are no DerivativeStructure at all among the arguments
+        // so the method must use a differentiated field, we use this field as the reference
+        final DifferentiatedElementSpecification field =
+                classDifferentiator.getUsedDifferentiatedField(differentiatedMethod.getPrimitiveSpec());
+        if (field == null) {
+            // this should never happen as we build class that do use DerivativeStructure
+            // either from their arguments or from class/instance fields
+            throw DifferentiationException.createInternalError(null);
+        }
+
+        // preserve the field as a new variable
+        final InsnList list = new InsnList();
+        if (field.getPrimitiveSpec().isStatic()) {
+            list.add(new FieldInsnNode(Opcodes.GETSTATIC,
+                                       getDifferentiatedInternalName(field.getPrimitiveSpec().getPrimitiveClass()),
+                                       field.getPrimitiveSpec().getName(), field.getDifferentiatedType().getDescriptor()));
+        } else {
+            list.add(new VarInsnNode(Opcodes.ALOAD, 0));
+            list.add(new FieldInsnNode(Opcodes.GETFIELD,
+                                       getDifferentiatedInternalName(field.getPrimitiveSpec().getPrimitiveClass()),
+                                       field.getPrimitiveSpec().getName(), field.getDifferentiatedType().getDescriptor()));
+        }
+        list.add(new VarInsnNode(Opcodes.ASTORE, dsIndex));
+        return list;
 
     }
 

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java Wed Oct 31 17:48:21 2012
@@ -16,8 +16,10 @@
  */
 package org.apache.commons.nabla.forward.instructions;
 
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.NablaMessages;
+import org.apache.commons.nabla.forward.DifferentiatedElementSpecification;
 import org.apache.commons.nabla.forward.NablaDifferentiated;
 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
@@ -50,10 +52,61 @@ public class GetTransformer implements I
         throws DifferentiationException {
 
         final FieldInsnNode fieldInsn = (FieldInsnNode) insn;
+        final DifferentiatedElementSpecification de =
+                methodDifferentiator.getDifferentiated(fieldInsn.name,
+                                                       fieldInsn.getOpcode() == Opcodes.GETSTATIC,
+                                                       fieldInsn.owner, Type.getType(fieldInsn.desc));
+        if (de != null) {
+            // the field is differentiated
+            return getReplacementTransformedField(fieldInsn, methodDifferentiator, de);
+        } else {
+            // the field is not differentiated, it still lies in the primitive class
+            return getReplacementPrimitiveField(fieldInsn, methodDifferentiator);
+        }
+    }
+
+    /** Get the replacement instructions when the field type is transformed.
+     * <p>
+     * Transformed fields are kept within the transformed class.
+     * </p>
+     * @param fieldInsn original instruction
+     * @param methodDifferentiator method differentiator driving this transformer
+     * @param dsIndex index of a reference {@link DerivativeStructure derivative structure} variable
+     * @return replacement instructions
+     * @exception DifferentiationException if the method differentiator cannot provide
+     * a temporary variable
+     */
+    private InsnList getReplacementTransformedField(final FieldInsnNode fieldInsn,
+                                                    final MethodDifferentiator methodDifferentiator,
+                                                    final DifferentiatedElementSpecification de)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+        list.add(new FieldInsnNode(fieldInsn.getOpcode(),
+                                   methodDifferentiator.getDifferentiatedInternalName(fieldInsn.owner),
+                                   fieldInsn.name, de.getDifferentiatedType().getDescriptor()));
+        return list;
+
+    }
+
+    /** Get the replacement instructions when the field type is not transformed.
+     * <p>
+     * Original fields are kept within the primitive class.
+     * </p>
+     * @param fieldInsn original instruction
+     * @param methodDifferentiator method differentiator driving this transformer
+     * @return replacement instructions
+     * @exception DifferentiationException if the method differentiator cannot provide
+     * a temporary variable
+     */
+    private InsnList getReplacementPrimitiveField(final FieldInsnNode fieldInsn,
+                                                  final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
         final InsnList list = new InsnList();
 
         // get the field as an object
-        if (insn.getOpcode() == Opcodes.GETFIELD) {
+        if (fieldInsn.getOpcode() == Opcodes.GETFIELD) {
             // GETFIELD case
             list.add(new LdcInsnNode(fieldInsn.name));
             list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Type.getInternalName(NablaDifferentiated.class),
@@ -62,7 +115,7 @@ public class GetTransformer implements I
                                                                  Type.getType(String.class))));
         } else {
             // GETSTATIC case
-            list.add(new LdcInsnNode(Type.getType("L" + methodDifferentiator.getPrimitiveName() + ";")));
+            list.add(new LdcInsnNode(Type.getType("L" + methodDifferentiator.getPrimitiveInternalName() + ";")));
             list.add(new LdcInsnNode(fieldInsn.name));
             list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(NablaDifferentiated.class),
                                         "getPrimitiveStaticField",

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeNonMathTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeNonMathTransformer.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeNonMathTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeNonMathTransformer.java Wed Oct 31 17:48:21 2012
@@ -54,14 +54,15 @@ public class InvokeNonMathTransformer im
         final Type differentiatedMethodType = Type.getMethodType(returnType, argumentTypes);
 
         // request the global differentiator to differentiate the invoked method
-        methodDifferentiator.requestMethodDifferentiation(Type.getType("L" + methodInsn.owner + ";").getClassName(),
+        methodDifferentiator.requestMethodDifferentiation(methodInsn.name,
                                                           methodInsn.getOpcode() == Opcodes.INVOKESTATIC,
-                                                          methodInsn.name, primitiveMethodType, differentiatedMethodType);
+                                                          methodInsn.owner, primitiveMethodType, differentiatedMethodType);
 
         // create the transformed instruction
         final InsnList list = new InsnList();
         list.add(new MethodInsnNode(methodInsn.getOpcode(),
-                                    methodDifferentiator.getDerivedName(), methodInsn.name,
+                                    methodDifferentiator.getDifferentiatedInternalName(methodInsn.owner),
+                                    methodInsn.name,
                                     differentiatedMethodType.getDescriptor()));
         return list;
 

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/PutTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/PutTransformer.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/PutTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/PutTransformer.java Wed Oct 31 17:48:21 2012
@@ -69,7 +69,7 @@ public class PutTransformer implements I
      * <p>
      * Transformed fields are kept within the transformed class.
      * </p>
-     * @param original original instruction
+     * @param insn original instruction
      * @param methodDifferentiator method differentiator driving this transformer
      * @param dsIndex index of a reference {@link DerivativeStructure derivative structure} variable
      * @return replacement instructions
@@ -90,12 +90,12 @@ public class PutTransformer implements I
 
         // we need to add a new field in the transformed class
         final boolean isStatic = insn.getOpcode() == Opcodes.PUTSTATIC;
-        methodDifferentiator.requestFieldDifferentiation(Type.getType("L" + insn.owner + ";").getClassName(),
-                                                         isStatic, insn.name,
+        methodDifferentiator.requestFieldDifferentiation(insn.name, isStatic, insn.owner,
                                                          primitiveFieldType, differentiatedFieldType);
 
         final InsnList list = new InsnList();
-        list.add(new FieldInsnNode(insn.getOpcode(), methodDifferentiator.getDerivedName(),
+        list.add(new FieldInsnNode(insn.getOpcode(),
+                                   methodDifferentiator.getDifferentiatedInternalName(insn.owner),
                                    insn.name, differentiatedFieldType.getDescriptor()));
         return list;
 
@@ -105,8 +105,8 @@ public class PutTransformer implements I
      * <p>
      * Original fields are kept within the primitive class.
      * </p>
+     * @param insn original instruction
      * @param methodDifferentiator method differentiator driving this transformer
-     * @param original original instruction
      * @return replacement instructions
      * @exception DifferentiationException if the method differentiator cannot provide
      * a temporary variable
@@ -168,7 +168,7 @@ public class PutTransformer implements I
                                                                  Type.getType(String.class))));
         } else {
             // PUTSTATIC case
-            list.add(new LdcInsnNode(Type.getType("L" + methodDifferentiator.getPrimitiveName() + ";")));
+            list.add(new LdcInsnNode(Type.getType("L" + methodDifferentiator.getPrimitiveInternalName() + ";")));
             list.add(new LdcInsnNode(insn.name));
             list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(NablaDifferentiated.class),
                                         "putPrimitiveStaticField",

Modified: commons/sandbox/nabla/trunk/src/main/resources/assets/org/apache/commons/nabla/NablaMessages_fr.properties
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/resources/assets/org/apache/commons/nabla/NablaMessages_fr.properties?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/resources/assets/org/apache/commons/nabla/NablaMessages_fr.properties (original)
+++ commons/sandbox/nabla/trunk/src/main/resources/assets/org/apache/commons/nabla/NablaMessages_fr.properties Wed Oct 31 17:48:21 2012
@@ -23,6 +23,7 @@ INTERFACE_NOT_FOUND_WHILE_DIFFERENTIATIN
 UNABLE_TO_ANALYZE_METHOD = impossible d''analyser la m\u00e9thode {0}.{1} ({2})
 UNKNOWN_METHOD = m\u00e9thode {0}.{1} inconnue
 UNEXPECTED_INSTRUCTION = instruction ayant l''opcode {0} inattendue
+INVOKE_DYNAMIC_NOT_HANDLED_YET = l''instruction INVOKEDYNAMIC a \u00e9t\u00e9 rencontr\u00e9e lors de la diff\u00e9rentiation de la class {0}, elle n''est pour l''heure pas encore prise en compte"),
 UNABLE_TO_HANDLE_INSTRUCTION = incapable de g\u00e9rer une instruction ayant l''opcode {0}
 CANNOT_USE_VOID_FIELD = impossible d''utiliser la valeur du champ de type \u00ab void \u00bb {0}
 ILLEGAL_LDC_CONSTANT = constante ill\u00e9gale pour une instruction LDC : {0}

Modified: commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/NablaMessagesTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/NablaMessagesTest.java?rev=1404268&r1=1404267&r2=1404268&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/NablaMessagesTest.java (original)
+++ commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/NablaMessagesTest.java Wed Oct 31 17:48:21 2012
@@ -36,7 +36,7 @@ public class NablaMessagesTest {
 
     @Test
     public void testMessageNumber() {
-        Assert.assertEquals(14, NablaMessages.values().length);
+        Assert.assertEquals(15, NablaMessages.values().length);
     }
 
     @Test