1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.nabla.forward.arithmetic;
18
19 import org.apache.commons.nabla.DifferentiationException;
20 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
21 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
22 import org.objectweb.asm.Opcodes;
23 import org.objectweb.asm.Type;
24 import org.objectweb.asm.tree.AbstractInsnNode;
25 import org.objectweb.asm.tree.InsnList;
26 import org.objectweb.asm.tree.InsnNode;
27 import org.objectweb.asm.tree.MethodInsnNode;
28
29
30
31
32 public class DSubTransformer implements InstructionsTransformer {
33
34
35 private static final String SUBTRACT_METHOD = "subtract";
36
37
38 private static final String NEGATE_METHOD = "negate";
39
40
41 private final boolean stack0Converted;
42
43
44 private final boolean stack1Converted;
45
46
47
48
49
50 public DSubTransformer(final boolean stack0Converted, final boolean stack1Converted) {
51 this.stack0Converted = stack0Converted;
52 this.stack1Converted = stack1Converted;
53 }
54
55
56 public InsnList getReplacement(final AbstractInsnNode insn,
57 final MethodDifferentiator methodDifferentiator)
58 throws DifferentiationException {
59
60 final InsnList list = new InsnList();
61
62 if (stack1Converted) {
63 if (stack0Converted) {
64 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
65 SUBTRACT_METHOD,
66 Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
67 } else {
68 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
69 SUBTRACT_METHOD,
70 Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
71 }
72 } else {
73 list.add(new InsnNode(Opcodes.DUP_X2));
74 list.add(new InsnNode(Opcodes.POP));
75 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
76 SUBTRACT_METHOD,
77 Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
78 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
79 NEGATE_METHOD,
80 Type.getMethodDescriptor(DS_TYPE)));
81 }
82
83 return list;
84
85 }
86
87 }