1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.nabla.forward.instructions;
18
19 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
20 import org.apache.commons.nabla.DifferentiationException;
21 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
22 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
23 import org.objectweb.asm.Opcodes;
24 import org.objectweb.asm.Type;
25 import org.objectweb.asm.tree.AbstractInsnNode;
26 import org.objectweb.asm.tree.InsnList;
27 import org.objectweb.asm.tree.InsnNode;
28 import org.objectweb.asm.tree.LdcInsnNode;
29 import org.objectweb.asm.tree.MethodInsnNode;
30 import org.objectweb.asm.tree.TypeInsnNode;
31 import org.objectweb.asm.tree.VarInsnNode;
32
33
34
35
36
37 public class WideningTransformer implements InstructionsTransformer {
38
39
40
41 public WideningTransformer() {
42 }
43
44
45 public InsnList getReplacement(final AbstractInsnNode insn,
46 final MethodDifferentiator methodDifferentiator)
47 throws DifferentiationException {
48
49 final InsnList list = new InsnList();
50
51
52 if (insn.getOpcode() == Opcodes.LDC) {
53 list.add(new LdcInsnNode(((LdcInsnNode) insn).cst));
54 } else {
55 list.add(new InsnNode(insn.getOpcode()));
56 }
57
58
59 list.add(new TypeInsnNode(Opcodes.NEW,
60 Type.getInternalName(DerivativeStructure.class)));
61 list.add(new InsnNode(Opcodes.DUP_X2));
62 list.add(new InsnNode(Opcodes.DUP_X2));
63 list.add(new InsnNode(Opcodes.POP));
64 list.add(new VarInsnNode(Opcodes.ALOAD, methodDifferentiator.getInputDSIndex()));
65 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
66 Type.getInternalName(DerivativeStructure.class),
67 "getFreeParameters",
68 Type.getMethodDescriptor(Type.INT_TYPE)));
69 list.add(new VarInsnNode(Opcodes.ALOAD, 1));
70 list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
71 Type.getInternalName(DerivativeStructure.class),
72 "getOrder",
73 Type.getMethodDescriptor(Type.INT_TYPE)));
74 list.add(new InsnNode(Opcodes.DUP2_X2));
75 list.add(new InsnNode(Opcodes.POP2));
76 list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
77 Type.getInternalName(DerivativeStructure.class),
78 "<init>",
79 Type.getMethodDescriptor(Type.VOID_TYPE,
80 Type.INT_TYPE,
81 Type.INT_TYPE,
82 Type.DOUBLE_TYPE)));
83
84 return list;
85
86 }
87
88 }