Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package eu.bibl.tools.debugger;
- import java.util.ArrayList;
- 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.InsnList;
- import org.objectweb.asm.tree.InsnNode;
- import org.objectweb.asm.tree.LdcInsnNode;
- import org.objectweb.asm.tree.MethodInsnNode;
- import org.objectweb.asm.tree.MethodNode;
- import org.objectweb.asm.tree.VarInsnNode;
- import eu.bibl.tools.analysis.instruction.OpcodeInfo;
- import eu.bibl.tools.debugger.stack.ConstantValue;
- import eu.bibl.tools.debugger.stack.FieldValue;
- import eu.bibl.tools.debugger.stack.LocalIndex;
- import eu.bibl.tools.debugger.stack.LocalParameter;
- import eu.bibl.tools.debugger.stack.MethodInvokation;
- import eu.bibl.tools.debugger.stack.MethodValue;
- import eu.bibl.tools.debugger.stack.NumberOperation;
- import eu.bibl.tools.debugger.stack.NumberOperationValue;
- import eu.bibl.tools.debugger.stack.StackException;
- import eu.bibl.tools.debugger.stack.StackOverflowException;
- import eu.bibl.tools.debugger.stack.StackReturn;
- import eu.bibl.tools.debugger.stack.ThisReference;
- import eu.bibl.tools.info.Access;
- /**
- * Print out the contents of the local execution stack of a method at runtime. <br>
- * @author Bibl
- *
- */
- public class StackEmulator implements Opcodes{
- public static final ArrayList<String> NUMBER_OPERATIONS = new ArrayList<String>();
- static{
- for(String name : "ADD SUB MUL DIV XOR OR AND REM SHL SHR".split(" "))
- NUMBER_OPERATIONS.add(name);
- }
- private boolean autoGenerateStack;
- private boolean isStatic;
- private ArrayList<Integer> breakpoints;
- private InsnList insns;
- private String desc;
- private int maxStack;
- private int maxLocals;
- private LocalIndex[] localStoreIndecies;
- private Object[] stack;
- private int stackPointer;
- public StackEmulator(MethodNode m) throws StackException{
- this(m, m.desc, false);
- }
- public StackEmulator(MethodNode m, String desc, boolean autoGenerateStack) throws StackException{
- this(m.instructions, desc, Access.isStatic(m.access), m.maxStack, m.maxLocals, autoGenerateStack);
- }
- public StackEmulator(InsnList insns, String desc, boolean isStatic, int maxStack, int maxLocals) throws StackException{
- this(insns, desc, isStatic, maxStack, maxLocals, false);
- }
- public StackEmulator(InsnList insns, String desc, boolean isStatic, int maxStack, int maxLocals, boolean autoGenerateStack) throws StackException{
- this.insns = insns;
- this.desc = desc;
- this.isStatic = isStatic;
- this.maxStack = maxStack;
- this.maxLocals = maxLocals;
- this.autoGenerateStack = autoGenerateStack;
- init();
- }
- private void init() throws StackException{
- stackPointer = 0;
- localStoreIndecies = new LocalIndex[maxLocals];
- stack = new Object[maxStack];
- breakpoints = new ArrayList<Integer>();
- int localIndex = 0;
- if(!isStatic)
- localStoreIndecies[localIndex++] = new ThisReference();
- Type[] args = Type.getArgumentTypes(desc);
- for(int i=0; i < args.length; i++){
- localStoreIndecies[localIndex++] = new LocalParameter(localIndex - 1, args[i].toString());
- }
- if(autoGenerateStack)
- generateStack();
- }
- public void addBreakpoint(int bp){
- breakpoints.add(bp);
- }
- public void removeBreakpoint(int bp){
- breakpoints.remove(bp);
- }
- public boolean breakpointExists(int bp){
- return breakpoints.contains(bp);
- }
- public void step(AbstractInsnNode ain) throws StackException{
- String name = OpcodeInfo.OPCODES.get(ain.getOpcode());
- if(ain instanceof LdcInsnNode){
- stack[stackPointer] = new ConstantValue(((LdcInsnNode) ain).cst);
- }else if(ain instanceof MethodInsnNode){
- MethodInsnNode min = (MethodInsnNode) ain;
- MethodInvokation invoke = new MethodInvokation(min.getOpcode(), min.owner, min.name, min.desc);
- stack[stackPointer] = invoke;
- }else if(ain instanceof FieldInsnNode){
- FieldInsnNode fin = (FieldInsnNode) ain;
- FieldValue val = new FieldValue(fin.owner, fin.name, fin.desc);
- stack[stackPointer] = val;
- }else if(NUMBER_OPERATIONS.contains(name)){
- NumberOperation op = new NumberOperation(ain.getOpcode());
- stack[stackPointer] = op;
- }else if(ain instanceof VarInsnNode){
- VarInsnNode vin = (VarInsnNode) ain;
- if(name.contains("STORE")){
- LocalIndex li = new LocalIndex(vin.var, stack[stackPointer--]);
- localStoreIndecies[li.getIndex()] = li;
- }else if(name.contains("LOAD")){
- stack[stackPointer] = localStoreIndecies[vin.var];
- }
- }else if(name.endsWith("RETURN")){
- StackReturn ret = new StackReturn(ain.getOpcode());
- stack[stackPointer] = ret;
- }
- if(stackPointer >= maxStack)
- throw new StackOverflowException(stackPointer, maxStack);
- }
- public void finishStep(AbstractInsnNode ain) throws StackException{
- Object lastValue = stack[stackPointer];
- if(lastValue == null){
- }else if(lastValue instanceof MethodInvokation){
- MethodInvokation invoke = (MethodInvokation) lastValue;
- for(int i=0; i < (invoke.getArgsSize() + 1); i++){
- stack[stackPointer--] = null;
- }
- if(invoke.getOpcode() != INVOKESTATIC){
- stack[stackPointer--] = null;
- }
- if(invoke.leaveOnStack()){
- stack[stackPointer--] = new MethodValue(invoke);
- }
- }else if(lastValue instanceof NumberOperation){
- NumberOperation op = (NumberOperation) lastValue;
- stack[stackPointer] = new NumberOperationValue(op.getOpcode(), stack[stackPointer--], stack[stackPointer--]);
- }
- stackPointer++;
- }
- public void generateStack() throws StackException{
- for(int i=0; i < insns.size(); i++){
- AbstractInsnNode ain = insns.get(i);
- if(breakpointExists(i)){
- }else{
- step(ain);
- printStack();
- finishStep(ain);
- printStack();
- }
- }
- }
- public void printStack(){
- System.out.println("#SP : SItem");
- for(int i=0; i < stack.length; i++){
- System.out.println("#" + (i + 1) + " : " + stack[i]);
- }
- }
- public Object[] getStack(){
- return stack;
- }
- public LocalIndex[] getLocalIndecies(){
- return localStoreIndecies;
- }
- public static void main(String[] args) throws StackException{
- //Test unit
- InsnList insns = new InsnList();
- // insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
- // insns.add(new LdcInsnNode("Sweg"));
- // insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
- // insns.add(new LdcInsnNode("Sweg25"));
- // insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
- // insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
- // insns.add(new InsnNode(RETURN));
- insns.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
- insns.add(new VarInsnNode(ALOAD, 1));
- insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
- insns.add(new InsnNode(RETURN));
- StackEmulator emulator = new StackEmulator(insns, "(Ljava/lang/String;)V", false, 3, 2);
- emulator.generateStack();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement