diff options
Diffstat (limited to 'src/virtualmachine/VirtualMachine.cpp')
| -rw-r--r-- | src/virtualmachine/VirtualMachine.cpp | 405 |
1 files changed, 0 insertions, 405 deletions
diff --git a/src/virtualmachine/VirtualMachine.cpp b/src/virtualmachine/VirtualMachine.cpp deleted file mode 100644 index a657f3c..0000000 --- a/src/virtualmachine/VirtualMachine.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include <string> -#include <cstring> -#include <stdio.h> -#include <stdlib.h> -#include "VirtualMachine.h" - -namespace vm -{ - - VirtualMachine::VirtualMachine(int hunkMbytes): - bigEndian(false), - hunk(NULL), - hunkSize(1048576), - hunkFree(0), - rom(NULL), - romSize(0), - ram(NULL), - ramSize(0), - dataStack(0), - returnStack(0), - DP(0), /* Datastack pointer. */ - RP(0), /* Return stack pointer. */ - PC(0), - cm(0), - cycles(0), - sim(NULL), - ren(NULL) - { - hunk = new char[hunkSize]; - std::fill(hunk, hunk+hunkSize, 0); - } - - VirtualMachine::~VirtualMachine() - { - delete[] hunk; - } - - #define DEBUGTRACE(args, ...) printf(args); - - int VirtualMachine::opcodeParameterSize(int opcode) - { - #define OP(n) OP##n - switch (opcode) - { - case OP(ENTER): - case OP(LEAVE): - case OP(LOCAL): - case OP(EQ): - case OP(NE): - case OP(LTI): - case OP(LEI): - case OP(GTI): - case OP(GEI): - case OP(LTU): - case OP(LEU): - case OP(GTU): - case OP(GEU): - case OP(EQF): - case OP(NEF): - case OP(LTF): - case OP(LEF): - case OP(GTF): - case OP(GEF): - case OP(CONST): - case OP(BLOCK_COPY): - return sizeof(uint4_t); - break; - case OP(ARG): - return sizeof(uint1_t); - break; - } - return 0; - #undef OP - } - - /* Read one octet from file. */ - int VirtualMachine::readByte(std::istream & input) - { - int o; - o = input.get(); - if (o < 0) o = 0; /* EOF (hack) */ - return o; - } - - /* Read little-endian 32-bit integer from file. */ - int VirtualMachine::readInt(std::istream & input) - { - int a, b, c, d, n; - - a = readByte(input); - b = readByte(input); - c = readByte(input); - d = readByte(input); - n = (a) | (b << 8) | (c << 16) | (d << 24); - return n; - } - - int VirtualMachine::readProgram(std::istream & input) - { - qvm_header_t qvminfo; - int i, n; - uint1_t x[4]; - word w; - - DEBUGTRACE("Loading file...\n"); - qvminfo.magic = readInt(input); /* magic. */ - if (qvminfo.magic != QVM_MAGIC) - { - DEBUGTRACE("Invalid magic"); - throw InvalidProgramException(); - //q3vm_error("Does not appear to be a QVM file."); - /* XXX: option to force continue. */ - return 0; - } - DEBUGTRACE("Magic OK\n"); - /* variable-length instructions mean instruction count != code length */ - qvminfo.inscount = readInt(input); - qvminfo.codeoff = readInt(input); - qvminfo.codelen = readInt(input); - qvminfo.dataoff = readInt(input); - qvminfo.datalen = readInt(input); - qvminfo.litlen = readInt(input); - qvminfo.bsslen = readInt(input); - - /* Code segment should follow... */ - /* XXX: use fseek with SEEK_CUR? */ - DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, input.tellg()); - - // rom = (q3vm_rom_t*)(hunk); /* ROM-in-hunk */ - rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0])); - while (input.tellg() < qvminfo.codeoff) - readByte(input); - while (romSize < qvminfo.inscount) - { - n = readByte(input); - w.int4 = 0; - if ((i = opcodeParameterSize(n))) - { - x[0] = x[1] = x[2] = x[3] = 0; - input.readsome((char*)x, i); - w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); - } - rom[romSize].Operation = n; - rom[romSize].Parameter = w; - romSize++; - } - DEBUGTRACE("After loading code: at %d, should be %d\n", input.tellg(), qvminfo.codeoff + qvminfo.codelen); - - /* Then data segment. */ - // ram = hunk + ((romlen + 3) & ~3); /* RAM-in-hunk */ - ram = hunk; - DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, input.tellg()); - while (input.tellg() < qvminfo.dataoff) - readByte(input); - for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++) - { - i = input.readsome((char*)x, sizeof(x)); - w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); - *((word*)(ram + ramSize)) = w; - ramSize += sizeof(word); - } - - /* lit segment follows data segment. */ - /* Assembler should have already padded properly. */ - DEBUGTRACE("Loading .lit\n"); - for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++) - { - i = input.readsome((char*)x, sizeof(x)); - memcpy(&(w.uint1), &x, sizeof(x)); /* no byte-swapping. */ - *((word*)(ram + ramSize)) = w; - ramSize += sizeof(word); - } - /* bss segment. */ - DEBUGTRACE("Allocating .bss %d (%X) bytes\n", qvminfo.bsslen, qvminfo.bsslen); - /* huge empty chunk. */ - ramSize += qvminfo.bsslen; - - hunkFree = hunkSize - ((ramSize * sizeof(uint1_t)) + 4); - - DEBUGTRACE("VM hunk has %d of %d bytes free (RAM = %d B).\n", hunkFree, hunkSize, ramSize); - if (ramSize > hunkSize) - { - throw OutOfMemoryException(); - return 0; - } - - /* set up stack. */ - { - int stacksize = 0x10000; - dataStack = ramSize - (stacksize / 2); - returnStack = ramSize; - //returnStack = dataStack+4; - RP = returnStack; - DP = dataStack; - } - - /* set up PC for return-to-termination. */ - PC = romSize + 1; - - ramMask = ramSize; - - return 1; - } - - int VirtualMachine::LoadProgram(std::vector<char> data) - { - /*class vectorwrapbuf : public std::basic_streambuf<char, std::char_traits<char> > - { - public: - vectorwrapbuf(std::vector<char> &vec) { - setg(vec.data(), vec.data(), vec.data() + vec.size()); - } - }; - vectorwrapbuf databuf(data); - std::istream is(&databuf); - return readProgram(is);*/ - std::stringstream ss(std::string(data.begin(), data.end())); - return readProgram((std::istream &)ss); - } - - int VirtualMachine::LoadProgram(char * filename) - { - /*FILE * qvmfile = fopen(filename, "rb"); - qvm_header_t qvminfo; - int i, n; - uint1_t x[4]; - word w; - - DEBUGTRACE("Loading file...\n"); - qvminfo.magic = readInt(qvmfile); - if (qvminfo.magic != QVM_MAGIC) - { - DEBUGTRACE("Invalid magic"); - return 0; - } - DEBUGTRACE("Magic OK\n"); - - qvminfo.inscount = readInt(qvmfile); - qvminfo.codeoff = readInt(qvmfile); - qvminfo.codelen = readInt(qvmfile); - qvminfo.dataoff = readInt(qvmfile); - qvminfo.datalen = readInt(qvmfile); - qvminfo.litlen = readInt(qvmfile); - qvminfo.bsslen = readInt(qvmfile); - - - DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, ftell(qvmfile)); - - rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0])); - while (ftell(qvmfile) < qvminfo.codeoff) - readByte(qvmfile); - while (romSize < qvminfo.inscount) - { - n = readByte(qvmfile); - w.int4 = 0; - if ((i = opcodeParameterSize(n))) - { - x[0] = x[1] = x[2] = x[3] = 0; - fread(&x, 1, i, qvmfile); - w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); - } - rom[romSize].Operation = n; - rom[romSize].Parameter = w; - romSize++; - } - DEBUGTRACE("After loading code: at %d, should be %d\n", ftell(qvmfile), qvminfo.codeoff + qvminfo.codelen); - - - ram = hunk; - DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, ftell(qvmfile)); - while (ftell(qvmfile) < qvminfo.dataoff) - readByte(qvmfile); - for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++) - { - i = fread(&x, 1, sizeof(x), qvmfile); - w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); - *((word*)(ram + ramSize)) = w; - ramSize += sizeof(word); - } - - - DEBUGTRACE("Loading .lit\n"); - for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++) - { - i = fread(&x, 1, sizeof(x), qvmfile); - memcpy(&(w.uint1), &x, sizeof(x)); - *((word*)(ram + ramSize)) = w; - ramSize += sizeof(word); - } - - DEBUGTRACE("Allocating .bss %d (%X) bytes\n", qvminfo.bsslen, qvminfo.bsslen); - ramSize += qvminfo.bsslen; - - hunkFree = hunkSize - ((ramSize * sizeof(uint1_t)) + 4); - - DEBUGTRACE("VM hunk has %d of %d bytes free (RAM = %d B).\n", hunkFree, hunkSize, ramSize); - if (ramSize > hunkSize) - { - throw OutOfMemoryException(); - return 0; - } - - - { - int stacksize = 0x10000; - dataStack = ramSize - (stacksize / 2); - //returnStack = ramSize; - returnStack = dataStack+4; - RP = returnStack; - DP = dataStack; - } - - - PC = romSize + 1; - - ramMask = ramSize; - - return 1;*/ - return 0; //temporary, something has to be returned for now - } - - void VirtualMachine::End() - { - PC = romSize+1; - } - - int VirtualMachine::CallInterpreted(int address) - { - word w; - int i, argCount = 0; - - /* Set up call. */ - OpPUSH(w); - DEBUGTRACE("Starting with PC=%d, DP=%d, RP=%d to %d\n", PC, DP, RP, address); - w.int4 = (argCount + 2) * sizeof(word); - OpENTER(w); - i = 8; - /**w.int4 = arg0; Marshal(i, w); i += 4; - w.int4 = arg1; Marshal(i, w); i += 4; - w.int4 = arg2; Marshal(i, w); i += 4; - w.int4 = arg3; Marshal(i, w); i += 4; - w.int4 = arg4; Marshal(i, w); i += 4; - w.int4 = arg5; Marshal(i, w); i += 4; - w.int4 = arg6; Marshal(i, w); i += 4; - w.int4 = arg7; Marshal(i, w); i += 4; - w.int4 = arg8; Marshal(i, w); i += 4; - w.int4 = arg9; Marshal(i, w); i += 4; - w.int4 = arg10; Marshal(i, w); i += 4; - w.int4 = arg11; Marshal(i, w); i += 4; - w.int4 = arg12; Marshal(i, w); i += 4;*/ - w.int4 = address; - Push(w); - OpCALL(w); - DEBUGTRACE("Upon running PC=%d, DP=%d, RP=%d\n", PC, DP, RP); - Run(); - DEBUGTRACE("At finish PC=%d, DP=%d, RP=%d\n", PC, DP, RP); - w.int4 = (argCount + 2) * sizeof(word); - OpLEAVE(w); - OpPOP(w); - PC = romSize + 1; - return 0; - } - - int VirtualMachine::Run() - { - bool running = true; - int operation; - word parameter; - while(running) - { - cycles++; - if(PC > romSize) - { - running = false; - continue; - } - if (PC < 0) - { - syscall(PC); - continue; - } - operation = rom[PC].Operation; - parameter = rom[PC].Parameter; - PC++; - (this->*operations[operation])(parameter); - } - return 1; - } - - - - int VirtualMachine::syscall(int trap) - { - PC = Pop<int4_t>(); - - switch (trap) - { - #define TRAPDEF(n, f) case n: trap##f(); break; - #include "Syscalls.inl" - #undef TRAPDEF - } - - return 1; - } -} |
