public static int GetJump(Stack <int> st, byte[] codes, int ip) { bool res = false; int addr = QDVMhlp.GetJmpAddr(codes[ip], codes[ip + 1]); switch (codes[ip - 1]) { case QDVMoc.VM_JEQ: res = st.Pop() == st.Pop(); break; case QDVMoc.VM_JGE: res = st.Pop() >= st.Pop(); break; case QDVMoc.VM_JGR: res = st.Pop() > st.Pop(); break; case QDVMoc.VM_JLE: res = st.Pop() <= st.Pop(); break; case QDVMoc.VM_JLS: res = st.Pop() < st.Pop(); break; case QDVMoc.VM_JMP: res = true; break; case QDVMoc.VM_JNE: res = st.Pop() != st.Pop(); break; case QDVMoc.VM_JZ: res = st.Pop() == 0; break; case QDVMoc.VM_JNZ: res = st.Pop() != 0; break; } if (!res) { addr = ip + 2; } if (addr > codes.Length || addr < 0) { throw new Exception(String.Format("Jump {0} outside the code", addr)); } return(addr); }
public static void LDi(Stack <int> st, byte[] data, int addr) { CheckFullStack(st, 1); byte[] ib = new byte[4]; for (int i = 0; i < 4; i++) { ib[i] = data[addr + i]; } st.Push(QDVMhlp.ConvertLittleEndian(ib)); }
void Executor(QDVMthread thr) { byte[] opcodes; opcodes = thr.code; try { switch (opcodes[thr.ip++]) { case QDVMoc.VM_NOP: break; case QDVMoc.VM_LDB: QDVMoc.LDb(thr.st, opcodes, opcodes[thr.ip++]); break; case QDVMoc.VM_LDI: QDVMoc.LDi(thr.st, opcodes, opcodes[thr.ip++]); break; case QDVMoc.VM_LSB: thr.st.Push(opcodes[thr.ip++]); break; case QDVMoc.VM_LSI: QDVMoc.LDi(thr.st, opcodes, thr.ip); thr.ip += 4; break; case QDVMoc.VM_LDV: QDVMoc.LDv(thr.st, thr.vars, opcodes[thr.ip++]); break; case QDVMoc.VM_STV: QDVMoc.STv(thr.st, thr.vars, opcodes[thr.ip++]); break; case QDVMoc.VM_ADD: QDVMoc.Add(thr.st); break; case QDVMoc.VM_SUB: QDVMoc.Sub(thr.st); break; case QDVMoc.VM_MUL: QDVMoc.Mul(thr.st); break; case QDVMoc.VM_DIV: QDVMoc.Div(thr.st); break; case QDVMoc.VM_MOD: QDVMoc.Mod(thr.st); break; case QDVMoc.VM_INC: thr.st.Push(1); QDVMoc.Add(thr.st); break; case QDVMoc.VM_DEC: thr.st.Push(1); QDVMoc.Sub(thr.st); break; case QDVMoc.VM_JEQ: case QDVMoc.VM_JNE: case QDVMoc.VM_JGE: case QDVMoc.VM_JGR: case QDVMoc.VM_JLE: case QDVMoc.VM_JLS: case QDVMoc.VM_JMP: case QDVMoc.VM_JZ: case QDVMoc.VM_JNZ: thr.ip = QDVMoc.GetJump(thr.st, opcodes, thr.ip); break; case QDVMoc.VM_RND: QDVMoc.GetRandom(thr.st); break; case QDVMoc.VM_CLK: thr.st.Push((int)(DateTime.Now.ToFileTime() / 10000L)); break; case QDVMoc.VM_HLT: thr.state = QDThrState.FROZEN; break; case QDVMoc.VM_POP: thr.st.Pop(); break; case QDVMoc.VM_DUP: thr.st.Push(thr.st.Peek()); break; case QDVMoc.VM_SWP: int a, b; a = thr.st.Pop(); b = thr.st.Pop(); thr.st.Push(a); thr.st.Push(b); break; case QDVMoc.VM_SCL: thr.st.Push(Syscalls[opcodes[thr.ip++]](thr)); break; case QDVMoc.VM_CAL: int addr = QDVMhlp.GetJmpAddr(opcodes[thr.ip], opcodes[thr.ip + 1]); thr.rs.Push(thr.ip + 2); thr.ip = addr; break; case QDVMoc.VM_RET: if (thr.rs.Count > 0) { thr.ip = thr.rs.Pop(); } else { if (thr.state == QDThrState.NEW) { thr.state = QDThrState.FROZEN; } else { thr.state = QDThrState.DEAD; } } break; default: throw new Exception(String.Format("Opcode {0} not implemented", opcodes[thr.ip - 1])); } } catch (Exception ex) { //Console.Out.WriteLine(ex.StackTrace); throw new Exception(String.Format("{0} at [{1}]:{2}", ex.Message, ThrId, thr.ip - 1)); } if (thr.state == QDThrState.DEAD) { Threads[ThrId] = null; } }