use of suite.primitive.adt.map.IntIntMap in project suite by stupidsing.
the class Amd64Interpret method interpret.
public int interpret(List<Instruction> instructions, Bytes code, Bytes input) {
mem.position(positionCode0);
mem.put(code.bs);
eip = positionCode0;
regs[esp] = baseStackx - 16;
IntIntMap labels = new IntIntMap();
for (int i = 0; i < instructions.size(); i++) {
int i_ = i;
Instruction instruction = instructions.get(i_);
if (instruction.insn == Insn.LABEL)
labels.update((int) ((OpImm) instruction.op0).imm, i0 -> i_ + 1);
}
while (true) {
Instruction instruction = instructions.get(eip++);
if (Boolean.FALSE)
LogUtil.info(state(instruction));
try {
Operand op0 = instruction.op0;
Operand op1 = instruction.op1;
int source0, source1;
IntSink assign;
if (op0 instanceof OpImm) {
source0 = (int) ((OpImm) op0).imm;
assign = null;
} else if (op0 instanceof OpMem) {
int index = index(address((OpMem) op0));
source0 = mem.getInt(index);
assign = i -> mem.putInt(index, i);
} else if (op0 instanceof OpReg) {
int reg = ((OpReg) op0).reg;
source0 = regs[reg];
assign = i -> {
regs[reg] = i;
};
} else {
source0 = 0;
assign = null;
}
if (op1 instanceof OpImm)
source1 = (int) ((OpImm) op1).imm;
else if (op1 instanceof OpMem)
source1 = mem.getInt(index(address((OpMem) op1)));
else if (op1 instanceof OpReg)
source1 = regs[((OpReg) op1).reg];
else
source1 = 0;
switch(instruction.insn) {
case ADD:
assign.sink(source0 + source1);
break;
case CALL:
push(eip);
eip = labels.get(source0);
break;
case CMP:
c = Integer.compare(source0, source1);
break;
case DEC:
assign.sink(source0 - 1);
break;
case INC:
assign.sink(source0 + 1);
break;
case INT:
if (source0 == -128)
if (regs[eax] == 1)
return regs[ebx];
else if (regs[eax] == 3) {
int length = min(regs[edx], input.size());
int di = index(regs[ecx]);
for (int i = 0; i < length; i++) mem.put(di++, input.get(i));
input = input.range(length);
regs[eax] = length;
} else if (regs[eax] == 4) {
int length = regs[edx];
int si = index(regs[ecx]);
byte[] bs = new byte[length];
for (int i = 0; i < length; i++) bs[i] = mem.get(si++);
output.sink(Bytes.of(bs));
} else
Fail.t();
else
Fail.t();
break;
case JE:
if (c == 0)
eip = labels.get(source0);
break;
case JMP:
eip = labels.get(source0);
break;
case JG:
if (0 < c)
eip = labels.get(source0);
break;
case JGE:
if (0 <= c)
eip = labels.get(source0);
break;
case JL:
if (c < 0)
eip = labels.get(source0);
break;
case JLE:
if (c <= 0)
eip = labels.get(source0);
break;
case JNE:
if (c != 0)
eip = labels.get(source0);
break;
case LABEL:
break;
case LEA:
assign.sink(address((OpMem) op1));
break;
case MOV:
assign.sink(source1);
break;
case POP:
assign.sink(pop());
break;
case PUSH:
push(source0);
break;
case RET:
eip = pop();
break;
case SUB:
assign.sink(source0 - source1);
break;
case XOR:
assign.sink(source0 ^ source1);
break;
default:
Fail.t();
}
} catch (Exception ex) {
LogUtil.info(state(instruction));
throw ex;
}
}
}
use of suite.primitive.adt.map.IntIntMap in project suite by stupidsing.
the class IntIntMapTest method test.
@Test
public void test() {
IntIntMap map = new IntIntMap();
map.put(1, 2);
map.put(3, 4);
map.put(5, 6);
assertEquals(2, map.get(1));
assertEquals(4, map.get(3));
assertEquals(6, map.get(5));
Set<String> expected = new HashSet<>();
expected.add("1:2");
expected.add("3:4");
expected.add("5:6");
Set<String> actual = new HashSet<>();
IntIntSource source = map.source();
IntIntPair pair = IntIntPair.of(0, 0);
while (source.source2(pair)) actual.add(pair.t0 + ":" + pair.t1);
assertEquals(expected, actual);
}
Aggregations