use of suite.primitive.IntPrimitives.IntSink 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.IntPrimitives.IntSink in project suite by stupidsing.
the class IntOutlet method sink.
public void sink(IntSink sink0) {
IntSink sink1 = sink0.rethrow();
int c;
while ((c = next()) != IntFunUtil.EMPTYVALUE) sink1.sink(c);
}
use of suite.primitive.IntPrimitives.IntSink in project suite by stupidsing.
the class DevMain method text.
private Text text(IRopeList<Character> text) {
IntsBuilder starts = new IntsBuilder();
IntsBuilder ends = new IntsBuilder();
IntMutable p0 = IntMutable.of(-1);
int size = text.size();
IntSink lf = px -> {
starts.append(p0.get() + 1);
ends.append(px);
p0.update(px);
};
for (int p = 0; p < size; p++) {
char ch = text.get(p);
if (ch == '\n' || wrapSize < p - p0.get())
lf.sink(p);
}
if (1 < size - p0.get())
lf.sink(size);
return new Text(text, starts.toInts().toArray(), ends.toInts().toArray());
}
use of suite.primitive.IntPrimitives.IntSink in project suite by stupidsing.
the class IntFunUtil method suck.
/**
* Sucks data from a sink and produce into a source.
*/
public static IntSource suck(Sink<IntSink> fun) {
NullableSyncQueue<Integer> queue = new NullableSyncQueue<>();
IntSink enqueue = c -> enqueue(queue, c);
Thread thread = Thread_.startThread(() -> {
try {
fun.sink(enqueue);
} finally {
enqueue(queue, EMPTYVALUE);
}
});
return () -> {
try {
return queue.take();
} catch (InterruptedException ex) {
thread.interrupt();
return Fail.t(ex);
}
};
}
Aggregations