public LocalVariableState updateMerged(int pos, StackEntry frame) { List<StackEntry> newContents = new ArrayList<StackEntry>(contents); newContents.remove(pos); newContents.add(pos, frame); return new LocalVariableState(newContents, constPool); } }
/** * marks the value in potition initializedValueStackPosition as initialized. This also pops this value and everything above * it */ public StackFrame constructorCall(int initializedValueStackPosition) { StackEntry entry = stackState.getContents().get(stackState.getContents().size() - 1 - initializedValueStackPosition); StackState ns = stackState.constructorCall(initializedValueStackPosition, entry); LocalVariableState locals = localVariableState.constructorCall(entry); return new StackFrame(ns, locals, StackFrameType.FULL_FRAME); }
private void updateMaxValues() { if (getStack().getContents().size() > maxStackDepth) { maxStackDepth = getStack().getContents().size(); } if (getLocalVars().getContents().size() > maxLocals) { maxLocals = getLocalVars().getContents().size(); } }
public void fload(int no) { LocalVariableState locals = getLocalVars(); if (locals.size() <= no) { throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString()); } StackEntry entry = locals.get(no); if (entry.getType() != StackEntryType.FLOAT) { throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables " + locals.toString()); } if (no > 0xFF) { // wide version writeByte(Opcode.WIDE); writeByte(Opcode.FLOAD); writeShort(no); currentOffset += 4; } else if (no >= 0 && no < 4) { writeByte(Opcode.FLOAD_0 + no); currentOffset++; } else { writeByte(Opcode.FLOAD); writeByte(no); currentOffset += 2; } advanceFrame(currentFrame.push(entry)); }
/** * Store the variable on top of the stack into a local variable, poping the variable from the stack. Wide types are handled * automatically */ public StackFrame store(int no) { StackEntry top = stackState.top(); StackState ns; LocalVariableState ls; if(top.getType() == StackEntryType.TOP) { //wide type StackEntry type = stackState.top_1(); ns = stackState.pop(2); ls = localVariableState.storeWide(no, type); } else { StackEntry type = stackState.top(); ns = stackState.pop(1); ls = localVariableState.store(no, type); } return new StackFrame(ns, ls, StackFrameType.FULL_FRAME); }
public void iinc(int local, int amount) { if (getLocalVars().get(local).getType() != StackEntryType.INT) { throw new InvalidBytecodeException("iinc requires int at local variable position " + local + " " + getLocalVars().toString()); } if (local > 0xFF || amount > 0xFF) { writeByte(Opcode.WIDE); writeByte(Opcode.IINC); writeShort(local); writeShort(amount); currentOffset += 6; } else { writeByte(Opcode.IINC); writeByte(local); writeByte(amount); currentOffset += 3; } duplicateFrame(); }
public LocalVariableState constructorCall(StackEntry entry) { List<StackEntry> newContents = new ArrayList<StackEntry>(contents.size()); if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT && stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else { throw new InvalidBytecodeException("entry is not an unitialized object. " + toString()); } } }
if (currentLocalVariableState.size() < mergeLocalVariableState.size()) { throw new InvalidBytecodeException( "Cannot merge stack frames, merge location has less locals than current location"); for (int i = 0; i < mergeLocalVariableState.size(); ++i) { StackEntry currentEntry = currentLocalVariableState.getContents().get(i); StackEntry mergeEntry = mergeLocalVariableState.getContents().get(i); if (mergeEntry.getType() == currentEntry.getType()) { if (mergeEntry.getType() == StackEntryType.OBJECT) {
public StackFrame mergeLocals(int pos, StackEntry frame) { LocalVariableState locals = localVariableState.updateMerged(pos, frame); return new StackFrame(stackState, locals, StackFrameType.FULL_FRAME); } public StackFrameType getType() {
public void dload(int no) { LocalVariableState locals = getLocalVars(); if (locals.size() <= no) { throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString()); } StackEntry entry = locals.get(no); if (entry.getType() != StackEntryType.DOUBLE) { throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables " + locals.toString()); } if (no > 0xFF) { // wide version writeByte(Opcode.WIDE); writeByte(Opcode.DLOAD); writeShort(no); currentOffset += 4; } else if (no >= 0 && no < 4) { writeByte(Opcode.DLOAD_0 + no); currentOffset++; } else { writeByte(Opcode.DLOAD); writeByte(no); currentOffset += 2; } advanceFrame(currentFrame.push(entry)); }
/** * Store the variable on top of the stack into a local variable, poping the variable from the stack. Wide types are handled * automatically */ public StackFrame store(int no) { StackEntry top = stackState.top(); StackState ns; LocalVariableState ls; if(top.getType() == StackEntryType.TOP) { //wide type StackEntry type = stackState.top_1(); ns = stackState.pop(2); ls = localVariableState.storeWide(no, type); } else { StackEntry type = stackState.top(); ns = stackState.pop(1); ls = localVariableState.store(no, type); } return new StackFrame(ns, ls, StackFrameType.FULL_FRAME); }
public void iinc(int local, int amount) { if (getLocalVars().get(local).getType() != StackEntryType.INT) { throw new InvalidBytecodeException("iinc requires int at local variable position " + local + " " + getLocalVars().toString()); } if (local > 0xFF || amount > 0xFF) { writeByte(Opcode.WIDE); writeByte(Opcode.IINC); writeShort(local); writeShort(amount); currentOffset += 6; } else { writeByte(Opcode.IINC); writeByte(local); writeByte(amount); currentOffset += 3; } duplicateFrame(); }
public LocalVariableState constructorCall(StackEntry entry) { List<StackEntry> newContents = new ArrayList<StackEntry>(contents.size()); if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT && stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else { throw new InvalidBytecodeException("entry is not an unitialized object. " + toString()); } }
if (currentLocalVariableState.size() < mergeLocalVariableState.size()) { throw new InvalidBytecodeException( "Cannot merge stack frames, merge location has less locals than current location " + currentFrame + " " + stackFrame); for (int i = 0; i < mergeLocalVariableState.size(); ++i) { StackEntry currentEntry = currentLocalVariableState.getContents().get(i); StackEntry mergeEntry = mergeLocalVariableState.getContents().get(i); if (mergeEntry.getType() == currentEntry.getType()) { if (mergeEntry.getType() == StackEntryType.OBJECT) {
public StackFrame mergeLocals(int pos, StackEntry frame) { LocalVariableState locals = localVariableState.updateMerged(pos, frame); return new StackFrame(stackState, locals, StackFrameType.FULL_FRAME); } public StackFrameType getType() {
public void iload(int no) { LocalVariableState locals = getLocalVars(); if (locals.size() <= no) { throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString()); } StackEntry entry = locals.get(no); if (entry.getType() != StackEntryType.INT) { throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables " + locals.toString()); } if (no > 0xFF) { // wide version writeByte(Opcode.WIDE); writeByte(Opcode.ILOAD); writeShort(no); currentOffset += 4; } else if (no >= 0 && no < 4) { writeByte(Opcode.ILOAD_0 + no); currentOffset++; } else { writeByte(Opcode.ILOAD); writeByte(no); currentOffset += 2; } advanceFrame(currentFrame.push(entry)); }
public LocalVariableState updateMerged(int pos, StackEntry frame) { List<StackEntry> newContents = new ArrayList<StackEntry>(contents); newContents.remove(pos); newContents.add(pos, frame); return new LocalVariableState(newContents, constPool); } }
/** * Store the variable on top of the stack into a local variable, poping the variable from the stack. Wide types are handled * automatically */ public StackFrame store(int no) { StackEntry top = stackState.top(); StackState ns; LocalVariableState ls; if(top.getType() == StackEntryType.TOP) { //wide type StackEntry type = stackState.top_1(); ns = stackState.pop(2); ls = localVariableState.storeWide(no, type); } else { StackEntry type = stackState.top(); ns = stackState.pop(1); ls = localVariableState.store(no, type); } return new StackFrame(ns, ls, StackFrameType.FULL_FRAME); }
public void iinc(int local, int amount) { if (getLocalVars().get(local).getType() != StackEntryType.INT) { throw new InvalidBytecodeException("iinc requires int at local variable position " + local + " " + getLocalVars().toString()); } if (local > 0xFF || amount > 0xFF) { writeByte(Opcode.WIDE); writeByte(Opcode.IINC); writeShort(local); writeShort(amount); currentOffset += 6; } else { writeByte(Opcode.IINC); writeByte(local); writeByte(amount); currentOffset += 3; } duplicateFrame(); }
public LocalVariableState constructorCall(StackEntry entry) { List<StackEntry> newContents = new ArrayList<StackEntry>(contents.size()); if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT && stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else { throw new InvalidBytecodeException("entry is not an unitialized object. " + toString()); } }