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/03 21:16:52 UTC

svn commit: r1393693 - in /commons/sandbox/nabla/trunk/src: main/java/org/apache/commons/nabla/forward/analysis/ main/java/org/apache/commons/nabla/forward/instructions/ test/java/org/apache/commons/nabla/forward/

Author: luc
Date: Wed Oct  3 19:16:52 2012
New Revision: 1393693

URL: http://svn.apache.org/viewvc?rev=1393693&view=rev
Log:
Added support for GETSTATIC instruction.

Added:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java   (contents, props changed)
      - copied, changed from r1393692, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetFieldTransformer.java
Removed:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetFieldTransformer.java
Modified:
    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/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java

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=1393693&r1=1393692&r2=1393693&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  3 19:16:52 2012
@@ -129,6 +129,7 @@ public class ClassDifferentiator {
         addPrimitiveField();
         addConstructor();
         addGetPrimitiveFieldMethod();
+        addGetPrimitiveStaticFieldMethod();
 
     }
 
@@ -246,4 +247,44 @@ public class ClassDifferentiator {
         classNode.methods.add(method);
     }
 
+    /** Add the getPrimitiveStaticField method.
+     */
+    private void addGetPrimitiveStaticFieldMethod() {
+        final MethodNode method =
+            new MethodNode(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, "getPrimitiveStaticField",
+                           Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(String.class)),
+                           null, null);
+        final Label start     = new Label();
+        final Label end       = new Label();
+        method.visitTryCatchBlock(start, end, end, Type.getInternalName(IllegalAccessException.class));
+        method.visitTryCatchBlock(start, end, end, Type.getInternalName(NoSuchFieldException.class));
+        method.visitLabel(start);
+        method.visitLdcInsn(Type.getType(primitiveClass));
+        method.visitVarInsn(Opcodes.ALOAD, 0);
+        method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Class.class),
+                               "getDeclaredField",
+                               Type.getMethodDescriptor(Type.getType(Field.class), Type.getType(String.class)));
+        method.visitVarInsn(Opcodes.ASTORE, 1);
+        method.visitVarInsn(Opcodes.ALOAD, 1);
+        method.visitInsn(Opcodes.ICONST_1);
+        method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Field.class),
+                               "setAccessible",
+                               Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE));
+        method.visitVarInsn(Opcodes.ALOAD, 1);
+        method.visitInsn(Opcodes.ACONST_NULL);
+        method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Field.class),
+                               "get",
+                               Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(Object.class)));
+        method.visitInsn(Opcodes.ARETURN);
+        method.visitLabel(end);
+        method.visitVarInsn(Opcodes.ASTORE, 2);
+        method.visitTypeInsn(Opcodes.NEW, Type.getInternalName(RuntimeException.class));
+        method.visitInsn(Opcodes.DUP);
+        method.visitVarInsn(Opcodes.ALOAD, 2);
+        method.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(RuntimeException.class),
+                               INIT, Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Throwable.class)));
+        method.visitInsn(Opcodes.ATHROW);
+        classNode.methods.add(method);
+    }
+
 }

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=1393693&r1=1393692&r2=1393693&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  3 19:16:52 2012
@@ -41,7 +41,7 @@ import org.apache.commons.nabla.forward.
 import org.apache.commons.nabla.forward.instructions.Dup2Transformer;
 import org.apache.commons.nabla.forward.instructions.Dup2X1Transformer;
 import org.apache.commons.nabla.forward.instructions.Dup2X2Transformer;
-import org.apache.commons.nabla.forward.instructions.GetFieldTransformer;
+import org.apache.commons.nabla.forward.instructions.GetTransformer;
 import org.apache.commons.nabla.forward.instructions.InvokeStaticTransformer;
 import org.apache.commons.nabla.forward.instructions.NarrowingTransformer;
 import org.apache.commons.nabla.forward.instructions.Pop2Transformer;
@@ -167,12 +167,14 @@ public class MethodDifferentiator {
      * Instructions that must be changed are:
      * </p>
      * <ul>
-     *   <li>the ones that consume changed variables or stack cells</li>
+     *   <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>
+     *       primitive instance fields,</li>
+     *   <li>the GETSTATIC/PUTSTATIC instruction as they must access the
+     *       primitive 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>
+     *       simple constants like "return 0").</li>
      * </ul>
      * @param instructions instructions of the method
      * @param isStatic if true, the method is a static method
@@ -226,12 +228,12 @@ public class MethodDifferentiator {
             }
         }
 
-        // the various GETFIELD/PUTFIELD/DRETURN instructions must also be changed
+        // 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) ||
+            if ((ins.getOpcode() == Opcodes.GETFIELD)  || (ins.getOpcode() == Opcodes.PUTFIELD) ||
+                (ins.getOpcode() == Opcodes.GETSTATIC) || (ins.getOpcode() == Opcodes.PUTSTATIC) ||
                 (ins.getOpcode() == Opcodes.DRETURN)) {
                 changes.add(ins);
             }
@@ -363,16 +365,12 @@ public class MethodDifferentiator {
             case Opcodes.DRETURN :
                 return new DReturnTransformer().getReplacement(insn, this, dsIndex);
             case Opcodes.GETSTATIC :
-                // TODO: add support for GETSTATIC differentiation
-                throw new RuntimeException("GETSTATIC not handled yet");
-            case Opcodes.PUTSTATIC :
-                // TODO: add support for PUTSTATIC differentiation
-                throw new RuntimeException("PUTSTATIC not handled yet");
             case Opcodes.GETFIELD :
-                return new GetFieldTransformer().getReplacement(insn, this, dsIndex);
+                return new GetTransformer().getReplacement(insn, this, dsIndex);
+            case Opcodes.PUTSTATIC :
             case Opcodes.PUTFIELD :
-                // TODO: add support for PUTFIELD differentiation
-                throw new RuntimeException("PUTFIELD not handled yet");
+                // TODO: add support for PUTSTATIC/PUTFIELD differentiation
+                throw new RuntimeException("PUTSTATIC/PUTFIELD not handled yet");
             case Opcodes.INVOKEVIRTUAL :
                 // TODO: add support for INVOKEVIRTUAL differentiation
                 throw new RuntimeException("INVOKEVIRTUAL not handled yet");

Copied: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java (from r1393692, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetFieldTransformer.java)
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java?p2=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java&p1=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetFieldTransformer.java&r1=1393692&r2=1393693&rev=1393693&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetFieldTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/GetTransformer.java Wed Oct  3 19:16:52 2012
@@ -29,17 +29,17 @@ import org.objectweb.asm.tree.LdcInsnNod
 import org.objectweb.asm.tree.MethodInsnNode;
 import org.objectweb.asm.tree.TypeInsnNode;
 
-/** Differentiation transformer for GETFIELD instructions.
- * <p>Each GETFIELD instruction is replaced by an instruction
+/** Differentiation transformer for GETFIELD/GETSTATIC instructions.
+ * <p>Each GETFIELD/GETSTATIC instruction is replaced by an instruction
  * list getting the field from the primitive class using reflection.
  * </p>
  * @version $Id$
  */
-public class GetFieldTransformer implements InstructionsTransformer {
+public class GetTransformer implements InstructionsTransformer {
 
     /** Simple constructor.
      */
-    public GetFieldTransformer() {
+    public GetTransformer() {
     }
 
     /** {@inheritDoc} */
@@ -53,10 +53,19 @@ public class GetFieldTransformer impleme
 
         // get the field as an object
         list.add(new LdcInsnNode(fieldInsn.name));
-        list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, methodDifferentiator.getDerivedName(),
-                                    "getPrimitiveField",
-                                    Type.getMethodDescriptor(Type.getType(Object.class),
-                                                             Type.getType(String.class))));
+        if (insn.getOpcode() == Opcodes.GETFIELD) {
+            // GETFIELD case
+            list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, methodDifferentiator.getDerivedName(),
+                                        "getPrimitiveField",
+                                        Type.getMethodDescriptor(Type.getType(Object.class),
+                                                                 Type.getType(String.class))));
+        } else {
+            // GETSTATIC case
+            list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, methodDifferentiator.getDerivedName(),
+                                        "getPrimitiveStaticField",
+                                        Type.getMethodDescriptor(Type.getType(Object.class),
+                                                                 Type.getType(String.class))));
+        }
 
         // convert it to the expected type
         final Type type = Type.getType(fieldInsn.desc);

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

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

Modified: commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java?rev=1393693&r1=1393692&r2=1393693&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java (original)
+++ commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java Wed Oct  3 19:16:52 2012
@@ -128,23 +128,28 @@ public class ForwardModeDifferentiatorTe
         Assert.assertEquals(3, derivative.value(t).getPartialDerivative(1), 1.0e-20);
         Assert.assertEquals(2, derivative.value(t).getValue(), 1.0e-20);
         function.setX(2);
-        Assert.assertEquals(4, derivative.value(t).getPartialDerivative(1), 1.0e-20);
-        Assert.assertEquals(3, derivative.value(t).getValue(), 1.0e-20);
+        PartialFunction.setA(5.0);
+        Assert.assertEquals(12, derivative.value(t).getPartialDerivative(1), 1.0e-20);
+        Assert.assertEquals(11, derivative.value(t).getValue(), 1.0e-20);
     }
 
-    public class PartialFunction implements UnivariateFunction {
+    public static class PartialFunction implements UnivariateFunction {
         private double x;
+        private static double a = 1.0;
         public PartialFunction(double x) {
             this.x = x;
         }
         public void setX(double x) {
             this.x = x;
         }
+        public static void setA(double newA) {
+            a = newA;
+        }
         public double getX() {
             return x;
         }
         public double value(double y) {
-            return x * y + y * y;
+            return x * y * a + y * y;
         }
     }