Advertisement
Guest User

Untitled

a guest
Apr 16th, 2014
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.12 KB | None | 0 0
  1. package eu.bibl.tools.debugger;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. import org.objectweb.asm.Opcodes;
  6. import org.objectweb.asm.Type;
  7. import org.objectweb.asm.tree.AbstractInsnNode;
  8. import org.objectweb.asm.tree.FieldInsnNode;
  9. import org.objectweb.asm.tree.InsnList;
  10. import org.objectweb.asm.tree.InsnNode;
  11. import org.objectweb.asm.tree.LdcInsnNode;
  12. import org.objectweb.asm.tree.MethodInsnNode;
  13. import org.objectweb.asm.tree.MethodNode;
  14. import org.objectweb.asm.tree.VarInsnNode;
  15.  
  16. import eu.bibl.tools.analysis.instruction.OpcodeInfo;
  17. import eu.bibl.tools.debugger.stack.ConstantValue;
  18. import eu.bibl.tools.debugger.stack.FieldValue;
  19. import eu.bibl.tools.debugger.stack.LocalIndex;
  20. import eu.bibl.tools.debugger.stack.LocalParameter;
  21. import eu.bibl.tools.debugger.stack.MethodInvokation;
  22. import eu.bibl.tools.debugger.stack.MethodValue;
  23. import eu.bibl.tools.debugger.stack.NumberOperation;
  24. import eu.bibl.tools.debugger.stack.NumberOperationValue;
  25. import eu.bibl.tools.debugger.stack.StackException;
  26. import eu.bibl.tools.debugger.stack.StackOverflowException;
  27. import eu.bibl.tools.debugger.stack.StackReturn;
  28. import eu.bibl.tools.debugger.stack.ThisReference;
  29. import eu.bibl.tools.info.Access;
  30.  
  31. /**
  32. * Print out the contents of the local execution stack of a method at runtime. <br>
  33. * @author Bibl
  34. *
  35. */
  36. public class StackEmulator implements Opcodes{
  37.  
  38. public static final ArrayList<String> NUMBER_OPERATIONS = new ArrayList<String>();
  39.  
  40. static{
  41. for(String name : "ADD SUB MUL DIV XOR OR AND REM SHL SHR".split(" "))
  42. NUMBER_OPERATIONS.add(name);
  43. }
  44.  
  45. private boolean autoGenerateStack;
  46.  
  47. private boolean isStatic;
  48. private ArrayList<Integer> breakpoints;
  49.  
  50. private InsnList insns;
  51. private String desc;
  52.  
  53. private int maxStack;
  54. private int maxLocals;
  55.  
  56. private LocalIndex[] localStoreIndecies;
  57. private Object[] stack;
  58. private int stackPointer;
  59.  
  60. public StackEmulator(MethodNode m) throws StackException{
  61. this(m, m.desc, false);
  62. }
  63.  
  64. public StackEmulator(MethodNode m, String desc, boolean autoGenerateStack) throws StackException{
  65. this(m.instructions, desc, Access.isStatic(m.access), m.maxStack, m.maxLocals, autoGenerateStack);
  66. }
  67.  
  68. public StackEmulator(InsnList insns, String desc, boolean isStatic, int maxStack, int maxLocals) throws StackException{
  69. this(insns, desc, isStatic, maxStack, maxLocals, false);
  70. }
  71.  
  72. public StackEmulator(InsnList insns, String desc, boolean isStatic, int maxStack, int maxLocals, boolean autoGenerateStack) throws StackException{
  73. this.insns = insns;
  74. this.desc = desc;
  75. this.isStatic = isStatic;
  76. this.maxStack = maxStack;
  77. this.maxLocals = maxLocals;
  78. this.autoGenerateStack = autoGenerateStack;
  79. init();
  80. }
  81.  
  82. private void init() throws StackException{
  83. stackPointer = 0;
  84. localStoreIndecies = new LocalIndex[maxLocals];
  85. stack = new Object[maxStack];
  86. breakpoints = new ArrayList<Integer>();
  87.  
  88. int localIndex = 0;
  89. if(!isStatic)
  90. localStoreIndecies[localIndex++] = new ThisReference();
  91.  
  92. Type[] args = Type.getArgumentTypes(desc);
  93. for(int i=0; i < args.length; i++){
  94. localStoreIndecies[localIndex++] = new LocalParameter(localIndex - 1, args[i].toString());
  95. }
  96.  
  97. if(autoGenerateStack)
  98. generateStack();
  99. }
  100.  
  101. public void addBreakpoint(int bp){
  102. breakpoints.add(bp);
  103. }
  104.  
  105. public void removeBreakpoint(int bp){
  106. breakpoints.remove(bp);
  107. }
  108.  
  109. public boolean breakpointExists(int bp){
  110. return breakpoints.contains(bp);
  111. }
  112.  
  113. public void step(AbstractInsnNode ain) throws StackException{
  114. String name = OpcodeInfo.OPCODES.get(ain.getOpcode());
  115. if(ain instanceof LdcInsnNode){
  116. stack[stackPointer] = new ConstantValue(((LdcInsnNode) ain).cst);
  117. }else if(ain instanceof MethodInsnNode){
  118. MethodInsnNode min = (MethodInsnNode) ain;
  119. MethodInvokation invoke = new MethodInvokation(min.getOpcode(), min.owner, min.name, min.desc);
  120. stack[stackPointer] = invoke;
  121. }else if(ain instanceof FieldInsnNode){
  122. FieldInsnNode fin = (FieldInsnNode) ain;
  123. FieldValue val = new FieldValue(fin.owner, fin.name, fin.desc);
  124. stack[stackPointer] = val;
  125. }else if(NUMBER_OPERATIONS.contains(name)){
  126. NumberOperation op = new NumberOperation(ain.getOpcode());
  127. stack[stackPointer] = op;
  128. }else if(ain instanceof VarInsnNode){
  129. VarInsnNode vin = (VarInsnNode) ain;
  130. if(name.contains("STORE")){
  131. LocalIndex li = new LocalIndex(vin.var, stack[stackPointer--]);
  132. localStoreIndecies[li.getIndex()] = li;
  133. }else if(name.contains("LOAD")){
  134. stack[stackPointer] = localStoreIndecies[vin.var];
  135. }
  136. }else if(name.endsWith("RETURN")){
  137. StackReturn ret = new StackReturn(ain.getOpcode());
  138. stack[stackPointer] = ret;
  139. }
  140.  
  141. if(stackPointer >= maxStack)
  142. throw new StackOverflowException(stackPointer, maxStack);
  143. }
  144.  
  145. public void finishStep(AbstractInsnNode ain) throws StackException{
  146. Object lastValue = stack[stackPointer];
  147. if(lastValue == null){
  148.  
  149. }else if(lastValue instanceof MethodInvokation){
  150. MethodInvokation invoke = (MethodInvokation) lastValue;
  151. for(int i=0; i < (invoke.getArgsSize() + 1); i++){
  152. stack[stackPointer--] = null;
  153. }
  154. if(invoke.getOpcode() != INVOKESTATIC){
  155. stack[stackPointer--] = null;
  156. }
  157. if(invoke.leaveOnStack()){
  158. stack[stackPointer--] = new MethodValue(invoke);
  159. }
  160. }else if(lastValue instanceof NumberOperation){
  161. NumberOperation op = (NumberOperation) lastValue;
  162. stack[stackPointer] = new NumberOperationValue(op.getOpcode(), stack[stackPointer--], stack[stackPointer--]);
  163. }
  164. stackPointer++;
  165. }
  166.  
  167. public void generateStack() throws StackException{
  168. for(int i=0; i < insns.size(); i++){
  169. AbstractInsnNode ain = insns.get(i);
  170. if(breakpointExists(i)){
  171.  
  172. }else{
  173. step(ain);
  174. printStack();
  175. finishStep(ain);
  176. printStack();
  177. }
  178. }
  179. }
  180.  
  181. public void printStack(){
  182. System.out.println("#SP : SItem");
  183. for(int i=0; i < stack.length; i++){
  184. System.out.println("#" + (i + 1) + " : " + stack[i]);
  185. }
  186. }
  187.  
  188. public Object[] getStack(){
  189. return stack;
  190. }
  191.  
  192. public LocalIndex[] getLocalIndecies(){
  193. return localStoreIndecies;
  194. }
  195.  
  196. public static void main(String[] args) throws StackException{
  197. //Test unit
  198. InsnList insns = new InsnList();
  199. // insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
  200. // insns.add(new LdcInsnNode("Sweg"));
  201. // insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
  202. // insns.add(new LdcInsnNode("Sweg25"));
  203. // insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
  204. // insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
  205. // insns.add(new InsnNode(RETURN));
  206.  
  207. insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
  208. insns.add(new VarInsnNode(ALOAD, 1));
  209. insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
  210. insns.add(new InsnNode(RETURN));
  211.  
  212. StackEmulator emulator = new StackEmulator(insns, "(Ljava/lang/String;)V", false, 3, 2);
  213. emulator.generateStack();
  214. }
  215. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement