summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cat/LuaScriptInterface.cpp99
-rw-r--r--src/cat/LuaScriptInterface.h11
-rw-r--r--src/pim/Generator.cpp518
-rw-r--r--src/pim/Generator.h178
-rw-r--r--src/pim/Machine.cpp637
-rw-r--r--src/pim/Machine.h120
-rw-r--r--src/pim/Opcodes.h12
-rw-r--r--src/pim/Opcodes.inl28
-rw-r--r--src/pim/Parser.cpp653
-rw-r--r--src/pim/Parser.h79
-rw-r--r--src/pim/Scanner.cpp199
-rw-r--r--src/pim/Scanner.h22
-rw-r--r--src/pim/Token.cpp51
-rw-r--r--src/pim/Token.h83
-rw-r--r--src/tests/PowderInteractionMachine.cpp21
-rw-r--r--src/tests/VirtualMachineTest.cpp16
-rw-r--r--src/tests/test.qvmbin2340 -> 0 bytes
-rw-r--r--src/virtualmachine/Exceptions.h100
-rw-r--r--src/virtualmachine/JustInTime.cpp1144
-rw-r--r--src/virtualmachine/Operations.cpp356
-rw-r--r--src/virtualmachine/Operations.inl60
-rw-r--r--src/virtualmachine/Syscalls.cpp99
-rw-r--r--src/virtualmachine/Syscalls.inl14
-rw-r--r--src/virtualmachine/VirtualMachine.cpp405
-rw-r--r--src/virtualmachine/VirtualMachine.h282
25 files changed, 0 insertions, 5187 deletions
diff --git a/src/cat/LuaScriptInterface.cpp b/src/cat/LuaScriptInterface.cpp
index d1319f7..d7f6835 100644
--- a/src/cat/LuaScriptInterface.cpp
+++ b/src/cat/LuaScriptInterface.cpp
@@ -23,10 +23,6 @@
#include "client/HTTP.h"
#include "PowderToy.h"
-//#include "virtualmachine/VirtualMachine.h"
-#include "pim/Parser.h"
-#include "pim/Machine.h"
-
#include "LuaBit.h"
#include "LuaWindow.h"
@@ -118,7 +114,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
initInterfaceAPI();
initRendererAPI();
initElementsAPI();
- initVirtualMachineAPI();
initGraphicsAPI();
initFileSystemAPI();
@@ -1873,49 +1868,6 @@ void LuaScriptInterface::initElementsAPI()
}
}
-pim::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM];
-
-int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
-{
- pim::VirtualMachine * machine = updateVirtualMachines[parts[i].type];
-
- machine->CSPush(i);
- machine->CSPush(x);
- machine->CSPush(y);
- machine->Call(0);
-
-
- /*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
-
- vm::word w;
- int argAddr = 0, argCount = 5;
- vMachine->sim = sim;
-
- vMachine->OpPUSH(w); //Pointless null in stack
- w.int4 = (argCount + 2) * sizeof(vm::word);
- vMachine->OpENTER(w);
- argAddr = 8;
-
- //Arguments
- w.int4 = i; vMachine->Marshal(argAddr, w); argAddr += 4;
- w.int4 = x; vMachine->Marshal(argAddr, w); argAddr += 4;
- w.int4 = y; vMachine->Marshal(argAddr, w); argAddr += 4;
- w.int4 = nt; vMachine->Marshal(argAddr, w); argAddr += 4;
- w.int4 = surround_space; vMachine->Marshal(argAddr, w); argAddr += 4;
-
- w.int4 = 0;
- vMachine->Push(w);
-
- vMachine->OpCALL(w);
- vMachine->Run();
- w.int4 = (argCount + 2) * sizeof(vm::word);
- vMachine->OpLEAVE(w);
- vMachine->OpPOP(w); //Pop pointless null
- vMachine->End();*/
-
- return 0;
-}
-
int LuaScriptInterface::elements_loadDefault(lua_State * l)
{
int args = lua_gettop(l);
@@ -2238,11 +2190,6 @@ int LuaScriptInterface::elements_property(lua_State * l)
else
lua_el_mode[id] = 1;
}
- else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA)
- {
- updateVirtualMachines[id] = (pim::VirtualMachine*)lua_touserdata(l, 3);
- luacon_sim->elements[id].Update = &updateVM;
- }
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
{
lua_el_func[id] = 0;
@@ -2347,52 +2294,6 @@ int LuaScriptInterface::elements_free(lua_State * l)
return 0;
}
-void LuaScriptInterface::initVirtualMachineAPI()
-{
- //Methods
- struct luaL_reg vmAPIMethods [] = {
- {"loadProgram", virtualMachine_loadProgram},
- {NULL, NULL}
- };
- luaL_register(l, "virtualMachine", vmAPIMethods);
-
- //elem shortcut
- lua_getglobal(l, "virtualMachine");
- lua_setglobal(l, "vm");
-}
-
-int LuaScriptInterface::virtualMachine_loadProgram(lua_State * l)
-{
- /*luaL_checktype(l, 1, LUA_TSTRING);
-
- vm::VirtualMachine * newVM = new vm::VirtualMachine(1);
- try
- {
- const char * tempString = lua_tostring(l, 1);
- int tempStringLength = lua_strlen(l, 1);
- std::vector<char> programData(tempString, tempString+tempStringLength);
- newVM->LoadProgram(programData);
- }
- catch(std::exception & e)
- {
- return luaL_error(l, "Unable to load program");
- }
- lua_pushlightuserdata(l, newVM);*/
- std::string programSource(lua_tostring(l, 1));
- std::stringstream input(programSource);
-
-
- pim::compiler::Parser * parser = new pim::compiler::Parser(input);
-
- std::vector<unsigned char> programData = parser->Compile();
-
- pim::VirtualMachine * machine = new pim::VirtualMachine(luacon_sim);
- machine->LoadProgram(programData);
-
- lua_pushlightuserdata(l, machine);
- return 1;
-}
-
void LuaScriptInterface::initGraphicsAPI()
{
//Methods
diff --git a/src/cat/LuaScriptInterface.h b/src/cat/LuaScriptInterface.h
index eda6832..a443a9d 100644
--- a/src/cat/LuaScriptInterface.h
+++ b/src/cat/LuaScriptInterface.h
@@ -16,10 +16,6 @@ namespace ui
class Window;
}
-namespace pim
-{
- class VirtualMachine;
-}
class Tool;
//Because lua only has bindings for C, we're going to have to go outside "outside" the LuaScriptInterface, this means we can only have one instance :(
@@ -115,9 +111,6 @@ class LuaScriptInterface: public CommandInterface
static int renderer_debugHUD(lua_State * l);
//Elements
- static pim::VirtualMachine * updateVirtualMachines[PT_NUM];
- static int updateVM(UPDATE_FUNC_ARGS);
- //
void initElementsAPI();
static int elements_allocate(lua_State * l);
static int elements_element(lua_State * l);
@@ -132,10 +125,6 @@ class LuaScriptInterface: public CommandInterface
static int interface_addComponent(lua_State * l);
static int interface_removeComponent(lua_State * l);
- //VM
- void initVirtualMachineAPI();
- static int virtualMachine_loadProgram(lua_State * l);
-
void initGraphicsAPI();
static int graphics_textSize(lua_State * l);
static int graphics_drawText(lua_State * l);
diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp
deleted file mode 100644
index 3292c8a..0000000
--- a/src/pim/Generator.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-//Code generator for bytecode
-#include <sstream>
-#include <fstream>
-#include "Format.h"
-#include "Generator.h"
-#include "Opcodes.h"
-namespace pim
-{
- namespace compiler
- {
- Generator::Generator() :
- output(std::cout),
- labelCounter(0),
- programCounter(0)
- {
-
- }
-
- void Generator::defineLabel(std::string label)
- {
- Label newLabel;
- newLabel.Name = label;
- newLabel.Position = programCounter;//program.size();
- labelPositions.push_back(newLabel);
- }
-
- void Generator::writeOpcode(int opcode)
- {
- programCounter++;
- program.push_back(opcode);
- }
-
- void Generator::writeConstant(std::string constant)
- {
- writeConstant(format::StringToNumber<int>(constant));
- }
-
- void Generator::writeConstant(int constant)
- {
- program.push_back(constant & 0xFF);
- program.push_back((constant>>8) & 0xFF);
- program.push_back((constant>>16) & 0xFF);
- program.push_back((constant>>24) & 0xFF);
- }
-
- void Generator::writeConstantPlaceholder(std::string label)
- {
- placeholders.push_back(Placeholder(program.size(), label));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantPlaceholder(int * value)
- {
- valuePlaceholders.push_back(ValuePlaceholder(program.size(), value));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantPropertyPlaceholder(std::string property)
- {
- propertyPlaceholders.push_back(PropertyPlaceholder(program.size(), property));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- void Generator::writeConstantMacroPlaceholder(std::string macro)
- {
- macroPlaceholders.push_back(MacroPlaceholder(program.size(), macro));
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- program.push_back(0);
- }
-
- std::vector<unsigned char> Generator::Finish()
- {
- //All compile time labels, macros, etc
- for(std::vector<Placeholder>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
- {
- bool found = false;
- Placeholder cPosition = *iter;
- for(std::vector<Label>::iterator iter2 = labelPositions.begin(), end2 = labelPositions.end(); iter2 != end2; ++iter2)
- {
- Label cLabel = *iter2;
- if(cPosition.second == cLabel.Name)
- {
- std::cout << "Setting placeholder at " << cPosition.first << " with " << cLabel.Position << " for" << cPosition.second << std::endl;
- found = true;
- program[cPosition.first] = cLabel.Position & 0xFF;
- program[cPosition.first+1] = (cLabel.Position >> 8) & 0xFF;
- program[cPosition.first+2] = (cLabel.Position >> 16) & 0xFF;
- program[cPosition.first+3] = (cLabel.Position >> 24) & 0xFF;
- break;
- }
- }
- if(!found)
- throw SymbolNotFoundException(cPosition.second);
- }
-
- for(std::vector<ValuePlaceholder>::iterator iter = valuePlaceholders.begin(), end = valuePlaceholders.end(); iter != end; ++iter)
- {
- ValuePlaceholder cPosition = *iter;
- int value = *cPosition.second;
-
- std::cout << "Setting value placeholder at " << cPosition.first << " with " << value << std::endl;
-
-
- program[cPosition.first] = value & 0xFF;
- program[cPosition.first+1] = (value >> 8) & 0xFF;
- program[cPosition.first+2] = (value >> 16) & 0xFF;
- program[cPosition.first+3] = (value >> 24) & 0xFF;
- }
-
- //Build file
- int macroSizePos, propSizePos, codeSizePos, macroSize = 0, propSize = 0, codeSize = program.size();
- std::vector<unsigned char> file;
- file.push_back('P');
- file.push_back('V');
- file.push_back('M');
- file.push_back('1');
-
-
- macroSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- propSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- codeSizePos = file.size();
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
- file.push_back(0);
-
- //Macros
- for(std::vector<MacroPlaceholder>::iterator iter = macroPlaceholders.begin(), end = macroPlaceholders.end(); iter != end; ++iter)
- {
- MacroPlaceholder cPosition = *iter;
- int position = cPosition.first;
-
- file.push_back(position & 0xFF);
- file.push_back((position >> 8) & 0xFF);
- file.push_back((position >> 16) & 0xFF);
- file.push_back((position >> 24) & 0xFF);
- macroSize += 4;
-
- file.push_back(cPosition.second.length());
- macroSize += 1;
- file.insert(file.end(), cPosition.second.begin(), cPosition.second.end());
- macroSize += cPosition.second.length();
- }
-
- file[macroSizePos] = macroSize & 0xFF;
- file[macroSizePos+1] = (macroSize >> 8) & 0xFF;
- file[macroSizePos+2] = (macroSize >> 16) & 0xFF;
- file[macroSizePos+3] = (macroSize >> 24) & 0xFF;
-
-
- //Macros
- for(std::vector<PropertyPlaceholder>::iterator iter = propertyPlaceholders.begin(), end = propertyPlaceholders.end(); iter != end; ++iter)
- {
- PropertyPlaceholder cPosition = *iter;
- int position = cPosition.first;
-
- file.push_back(position & 0xFF);
- file.push_back((position >> 8) & 0xFF);
- file.push_back((position >> 16) & 0xFF);
- file.push_back((position >> 24) & 0xFF);
- propSize += 4;
-
- file.push_back(cPosition.second.length());
- propSize += 1;
- file.insert(file.end(), cPosition.second.begin(), cPosition.second.end());
- propSize += cPosition.second.length();
- }
-
- file[propSizePos] = propSize & 0xFF;
- file[propSizePos+1] = (propSize >> 8) & 0xFF;
- file[propSizePos+2] = (propSize >> 16) & 0xFF;
- file[propSizePos+3] = (propSize >> 24) & 0xFF;
-
- file.insert(file.end(), program.begin(), program.end());
-
- file[codeSizePos] = codeSize & 0xFF;
- file[codeSizePos+1] = (codeSize >> 8) & 0xFF;
- file[codeSizePos+2] = (codeSize >> 16) & 0xFF;
- file[codeSizePos+3] = (codeSize >> 24) & 0xFF;
-
- std::ofstream newFile("test.pvm");
- for(std::vector<unsigned char>::iterator iter = file.begin(), end = file.end(); iter != end; ++iter)
- {
- newFile.put(*iter);
- }
- newFile.close();
-
- return file;
- }
-
- std::string Generator::UniqueLabel(std::string prefix)
- {
- std::stringstream label;
- label << prefix;
- label << "_";
- label << labelCounter;
- label << "_";
- return label.str();
- }
-
- void Generator::PushScope(std::string label)
- {
- scopes.push(currentScope);
- Scope * prevScope = currentScope;
- currentScope = new Scope();
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::PushLocalScope(std::string label)
- {
- scopes.push(currentScope);
- Scope * prevScope = currentScope;
- currentScope = new Scope();
- currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end());
- currentScope->FrameSize = prevScope->FrameSize;
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::PopScope()
- {
-
- writeOpcode(Opcode::Return);
- writeConstant(currentScope->LocalFrameSize);
-
- output << "return " << currentScope->LocalFrameSize << std::endl;
-
- currentScope = scopes.top();
- scopes.pop();
- }
-
- void Generator::ScopeLabel(std::string label)
- {
- //defineLabelwriteOpcode("." << label);
- defineLabel(label);
-
- output << "." << label << std::endl;
- }
-
- void Generator::LocalEnter()
- {
- writeOpcode(Opcode::LocalEnter);
- writeConstantPlaceholder(&(currentScope->LocalFrameSize));
-
- output << "enter " << "#" << std::endl;
- }
-
- void Generator::ScopeVariableType(int type)
- {
- variableType = type;
- }
-
- void Generator::ScopeVariable(std::string label)
- {
- currentScope->Definitions.push_back(Definition(label, variableType, currentScope->FrameSize));
- currentScope->FrameSize += 4;
- currentScope->LocalFrameSize += 4;
-
- output << "#declare " << label << " " << currentScope->FrameSize-4 << std::endl;
- }
-
- void Generator::PushVariableAddress(std::string label)
- {
- //writeOpcode("address"); << " " << currentScope->GetDefinition(label).StackPosition
- }
-
- void Generator::LoadVariable(std::string label)
- {
- writeOpcode(Opcode::Load);
- writeConstant(currentScope->GetDefinition(label).StackPosition);
-
- output << "load " << label << std::endl;
- }
-
- void Generator::StoreVariable(std::string label)
- {
- writeOpcode(Opcode::Store);
- writeConstant(currentScope->GetDefinition(label).StackPosition);
-
- output << "store " << label << std::endl;
- }
-
- void Generator::RTConstant(std::string name)
- {
- writeOpcode(Opcode::Constant);
- writeConstantMacroPlaceholder(name);
-
- output << "const " << name << std::endl;
- }
-
- void Generator::Constant(std::string constant)
- {
- writeOpcode(Opcode::Constant);
- writeConstant(constant);
-
- output << "const " << constant << std::endl;
-
- }
-
- void Generator::Increment(std::string constant)
- {
- writeOpcode(Opcode::Increment);
- writeConstant(constant);
-
- output << "inc " << constant << std::endl;
- }
-
- void Generator::Discard()
- {
- writeOpcode(Opcode::Discard);
-
- output << "discard" << std::endl;
- }
-
- void Generator::Duplicate()
- {
- writeOpcode(Opcode::Duplicate);
-
- output << "duplicate" << std::endl;
- }
-
- void Generator::Add()
- {
- writeOpcode(Opcode::Add);
-
- output << "add" << std::endl;
- }
-
- void Generator::Subtract()
- {
- writeOpcode(Opcode::Subtract);
-
- output << "sub" << std::endl;
- }
-
- void Generator::Multiply()
- {
- writeOpcode(Opcode::Multiply);
-
- output << "mul" << std::endl;
- }
-
- void Generator::Divide()
- {
- writeOpcode(Opcode::Divide);
-
- output << "div" << std::endl;
- }
-
- void Generator::Modulus()
- {
- writeOpcode(Opcode::Modulus);
-
- output << "add" << std::endl;
- }
-
- void Generator::Negate()
- {
- writeOpcode(Opcode::Negate);
-
- output << "neg" << std::endl;
- }
-
- void Generator::CreateParticle()
- {
- writeOpcode(Opcode::Create);
-
- output << "create" << std::endl;
- }
-
- void Generator::TransformParticle()
- {
- writeOpcode(Opcode::Transform);
-
- output << "transform" << std::endl;
- }
-
- void Generator::GetParticle()
- {
- writeOpcode(Opcode::Get);
-
- output << "getpart" << std::endl;
- }
-
- void Generator::GetPosition()
- {
- writeOpcode(Opcode::Position);
-
- output << "getpos" << std::endl;
- }
-
- void Generator::KillParticle()
- {
- writeOpcode(Opcode::Kill);
-
- output << "kill" << std::endl;
- }
-
- void Generator::LoadProperty(std::string property)
- {
- writeOpcode(Opcode::LoadProperty);
- writeConstantPropertyPlaceholder(property);
-
- output << "loadprop " << property << std::endl;
- }
-
- void Generator::StoreProperty(std::string property)
- {
- writeOpcode(Opcode::StoreProperty);
- writeConstantPropertyPlaceholder(property);
-
- output << "storeprop " << property << std::endl;
- }
-
- void Generator::IntegerToDecimal()
- {
-
- }
-
- void Generator::DecimalToInteger()
- {
-
- }
-
-
- void Generator::JumpEqual(std::string label)
- {
- writeOpcode(Opcode::JumpEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpe " << label << std::endl;
- }
-
- void Generator::JumpNotEqual(std::string label)
- {
- writeOpcode(Opcode::JumpNotEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpne " << label << std::endl;
- }
-
- void Generator::JumpGreater(std::string label)
- {
- writeOpcode(Opcode::JumpGreater);
- writeConstantPlaceholder(label);
-
- output << "jumpg " << label << std::endl;
- }
-
- void Generator::JumpGreaterEqual(std::string label)
- {
- writeOpcode(Opcode::JumpGreaterEqual);
- writeConstantPlaceholder(label);
-
- output << "jumpge " << label << std::endl;
- }
-
- void Generator::JumpLess(std::string label)
- {
- writeOpcode(Opcode::JumpLess);
- writeConstantPlaceholder(label);
-
- output << "jumpl " << label << std::endl;
- }
-
- void Generator::JumpLessEqual(std::string label)
- {
- writeOpcode(Opcode::JumpLessEqual);
- writeConstantPlaceholder(label);
-
- output << "jumple " << label << std::endl;
- }
-
- void Generator::Jump(std::string label)
- {
- writeOpcode(Opcode::Jump);
- writeConstantPlaceholder(label);
-
- output << "jump " << label << std::endl;
- }
-
-
- void Generator::Call(int arguments, std::string label)
- {
-
- }
-
- void Generator::Return()
- {
-
- }
-
- }
-}
diff --git a/src/pim/Generator.h b/src/pim/Generator.h
deleted file mode 100644
index 4dd2cfe..0000000
--- a/src/pim/Generator.h
+++ /dev/null
@@ -1,178 +0,0 @@
-#pragma once
-
-#include <cstring>
-#include <vector>
-#include <stack>
-#include <iostream>
-#include "Token.h"
-namespace pim
-{
- namespace compiler
- {
- class VariableNotFoundException: public std::exception
- {
- char * error;
- public:
- VariableNotFoundException(std::string variable) {
- error = strdup(std::string("Could not find the variable \""+variable+"\" in the current scope").c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~VariableNotFoundException() throw() {};
- };
-
- class SymbolNotFoundException: public std::exception
- {
- char * error;
- public:
- SymbolNotFoundException(std::string variable) {
- error = strdup(std::string("Could not find the symbol \""+variable+"\".").c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~SymbolNotFoundException() throw() {};
- };
- class Type
- {
- enum { Integer = Token::IntegerSymbol, Decimal = Token::DecimalSymbol };
- };
- class Definition
- {
- public:
- std::string Name;
- int Type;
- int StackPosition;
- Definition(std::string name, int type, int position) :
- Type(type),
- Name(name),
- StackPosition(position)
- {
-
- }
- };
-
- struct Label
- {
- std::string Name;
- int Position;
- };
-
- class Scope
- {
- public:
- std::vector<Definition> Definitions;
- std::vector<Label> Labels;
- int FrameSize;
- int LocalFrameSize;
- Scope():
- FrameSize(0),
- LocalFrameSize(0)
- {
-
- }
- Definition GetDefinition(std::string name)
- {
- for(std::vector<Definition>::iterator iter = Definitions.begin(), end = Definitions.end(); iter != end; ++iter)
- {
- if((*iter).Name == name)
- return *iter;
- }
- throw VariableNotFoundException(name);
- }
- };
-
- class Generator
- {
- int variableType;
- std::stack<Scope*> scopes;
- Scope * currentScope;
- std::ostream & output;
- int labelCounter;
- int programCounter;
-
- typedef std::pair<int, std::string> Placeholder;
- std::vector<Placeholder> placeholders;
-
- typedef std::pair<int, int*> ValuePlaceholder;
- std::vector<ValuePlaceholder> valuePlaceholders;
-
- typedef std::pair<int, std::string> PropertyPlaceholder;
- std::vector<PropertyPlaceholder> propertyPlaceholders;
-
- typedef std::pair<int, std::string> MacroPlaceholder;
- std::vector<MacroPlaceholder> macroPlaceholders;
-
- std::vector<Label> labelPositions;
-
- std::vector<unsigned char> program;
-
- void defineLabel(std::string label);
- void writeOpcode(int opcode);
- void writeConstant(std::string constant);
- void writeConstant(int constant);
- void writeConstantPlaceholder(std::string label);
- void writeConstantPlaceholder(int * value);
- void writeConstantMacroPlaceholder(std::string macro);
- void writeConstantPropertyPlaceholder(std::string property);
-
- public:
- Generator();
-
- std::vector<unsigned char> Finish();
-
- std::string UniqueLabel(std::string prefix);
-
- void PushScope(std::string label);
- void PushLocalScope(std::string label);
- void LocalEnter();
- void PopScope();
-
- void ScopeLabel(std::string label);
- void ScopeVariableType(int type);
- void ScopeVariable(std::string label);
-
- void PushVariableAddress(std::string label);
-// void Store();
- void LoadVariable(std::string label);
- void StoreVariable(std::string label);
-
- void Duplicate();
- void Discard();
- void RTConstant(std::string name);
- void Constant(std::string constant);
- void Increment(std::string constant);
- void Add();
- void Subtract();
- void Multiply();
- void Divide();
- void Modulus();
- void Negate();
-
- void TransformParticle();
- void CreateParticle();
- void GetParticle();
- void GetPosition();
- void KillParticle();
- void LoadProperty(std::string property);
- void StoreProperty(std::string property);
-
- void IntegerToDecimal();
- void DecimalToInteger();
-
- void JumpEqual(std::string label);
- void JumpNotEqual(std::string label);
- void JumpGreater(std::string label);
- void JumpGreaterEqual(std::string label);
- void JumpLess(std::string label);
- void JumpLessEqual(std::string label);
- void Jump(std::string label);
-
- void Call(int arguments, std::string label);
- void Return();
- };
- }
-}
diff --git a/src/pim/Machine.cpp b/src/pim/Machine.cpp
deleted file mode 100644
index a954d31..0000000
--- a/src/pim/Machine.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-//Virtual machine
-
-#include <iostream>
-#include "Machine.h"
-#include "Opcodes.h"
-#include "simulation/Simulation.h"
-namespace pim
-{
- /*unsigned char * rom;
- int romSize;
- int romMask;
-
- unsigned char * ram;
- int ramSize;
- int ramMask;
-
- int programStack;
- int callStack;*/
-
- VirtualMachine::VirtualMachine(Simulation * simulation) :
- rom(NULL),
- ram(NULL),
- sim(simulation)
- {
-
- }
-
- void VirtualMachine::LoadProgram(std::vector<unsigned char> fileData)
- {
- int lastBit = 0;
-
- if(!(fileData[0] == 'P' && fileData[1] == 'V' && fileData[2] == 'M' && fileData[3] == '1' && fileData.size() >= 16))
- {
- throw InvalidProgramException();
- }
-
- int macroSize = 0, propSize = 0, codeSize = 0;
- macroSize = fileData[4];
- macroSize |= fileData[5] << 8;
- macroSize |= fileData[6] << 16;
- macroSize |= fileData[7] << 24;
-
- propSize = fileData[8];
- propSize |= fileData[9] << 8;
- propSize |= fileData[10] << 16;
- propSize |= fileData[11] << 24;
-
- codeSize = fileData[12];
- codeSize |= fileData[13] << 8;
- codeSize |= fileData[14] << 16;
- codeSize |= fileData[15] << 24;
-
- if(fileData.size() < 16 + macroSize + propSize + codeSize)
- {
- throw InvalidProgramException();
- }
-
- //std::vector<std::pair<int, int> > insertions;
-
- int macroOffset = 16;
- int propOffset = macroOffset+macroSize;
- int codeOffset = propOffset+propSize;
-
-
- int filePosition = macroOffset;
- while(filePosition + 4 < macroSize + macroOffset)
- {
- std::string macro;
- int macroPosition;
- int macroValue;
-
- macroPosition = fileData[filePosition++];
- macroPosition |= fileData[filePosition++] << 8;
- macroPosition |= fileData[filePosition++] << 16;
- macroPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > macroSize + macroOffset)
- {
- throw InvalidProgramException();
- }
-
- macro.insert(macro.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
- for(int i = 0; i < PT_NUM; i++)
- {
- if(sim->elements[i].Enabled && sim->elements[i].Identifier == macro)
- {
- macroValue = i;
- resolved = true;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(macro);
- }
-
- if(macroPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Macro insertion [" << macro << "] at " << macroPosition << " with " << macroValue << std::endl;
-
- fileData[codeOffset+macroPosition] = macroValue & 0xFF;
- fileData[codeOffset+macroPosition+1] = (macroValue >> 8) & 0xFF;
- fileData[codeOffset+macroPosition+2] = (macroValue >> 16) & 0xFF;
- fileData[codeOffset+macroPosition+3] = (macroValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- filePosition = propOffset;
- while(filePosition + 4 < propSize + propOffset)
- {
- std::string prop;
- int propPosition;
- int propValue;
-
- propPosition = fileData[filePosition++];
- propPosition |= fileData[filePosition++] << 8;
- propPosition |= fileData[filePosition++] << 16;
- propPosition |= fileData[filePosition++] << 24;
-
- int stringLength = fileData[filePosition++];
- if(filePosition + stringLength > propSize + propOffset)
- {
- throw InvalidProgramException();
- }
-
- prop.insert(prop.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength);
- filePosition += stringLength;
-
- bool resolved = false;
-
- std::vector<StructProperty> properties = Particle::GetProperties();
- for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
- {
- StructProperty property = *iter;
- std::cout << property.Offset << std::endl;
- if(property.Name == prop &&
- (property.Type == StructProperty::ParticleType ||
- property.Type == StructProperty::Colour ||
- property.Type == StructProperty::Integer ||
- property.Type == StructProperty::UInteger ||
- property.Type == StructProperty::Float)
- )
- {
- propValue = property.Offset;
- resolved = true;
- break;
- }
- }
- if(!resolved)
- {
- throw UnresolvedValueException(prop);
- }
-
- if(propPosition + 3 >= codeSize)
- {
- throw InvalidProgramException();
- }
-
- std::cout << "Property insertion [" << prop << "] at " << propPosition << " with " << propValue << std::endl;
-
- fileData[codeOffset+propPosition] = propValue & 0xFF;
- fileData[codeOffset+propPosition+1] = (propValue >> 8) & 0xFF;
- fileData[codeOffset+propPosition+2] = (propValue >> 16) & 0xFF;
- fileData[codeOffset+propPosition+3] = (propValue >> 24) & 0xFF;
- //insertions.push_back(std::pair<int, int>(macroPosition, macroValue));
- }
-
- std::vector<unsigned char> programData;
- programData.insert(programData.begin(), fileData.begin()+codeOffset, fileData.begin()+codeOffset+codeSize);
-
- romSize = programData.size();
-
- for (lastBit = 0; romSize > (1 << lastBit); lastBit++ ) { }
- romSize = 1 << lastBit;
- romMask = romSize - 1;
-
- rom = new Instruction[romSize];
-
- int pc = 0;
- int programPosition = 0;
-
- while(programPosition < programData.size())
- {
- int argSize = 0;
- Instruction instruction;
- instruction.Opcode = programData[programPosition++];
- if(argSize = OpcodeArgSize(instruction.Opcode))
- {
- if(argSize == 4 && programPosition+3 < programData.size())
- {
- int tempInt = 0;
- tempInt |= programData[programPosition];
- tempInt |= programData[programPosition+1] << 8;
- tempInt |= programData[programPosition+2] << 16;
- tempInt |= programData[programPosition+3] << 24;
-
-
- std::cout << "Got integer " << tempInt << std::endl;
-
- if(instruction.Opcode == Opcode::LoadProperty || instruction.Opcode == Opcode::StoreProperty)
- {
- if(tempInt > offsetof(Particle, dcolour))
- throw InvalidProgramException();
- }
-
- instruction.Parameter.Integer = tempInt;
-
- programPosition += 4;
- }
- }
- else
- {
- instruction.Parameter.Integer = 0;
- }
- rom[pc++] = instruction;
- }
- romSize = pc;
-
- ramSize = 1024;
- ramMask = ramSize - 1;
-
- ram = new unsigned char[ramSize];
- programStack = ramSize-1;
- callStack = ramSize-260;
-
- framePointer = callStack;
- callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
- }
-
- int VirtualMachine::OpcodeArgSize(int opcode)
- {
- switch(opcode)
- {
- case Opcode::Load:
- case Opcode::Store:
- case Opcode::Constant:
- case Opcode::Increment:
- case Opcode::JumpEqual:
- case Opcode::JumpNotEqual:
- case Opcode::JumpGreater:
- case Opcode::JumpGreaterEqual:
- case Opcode::JumpLess:
- case Opcode::JumpLessEqual:
- case Opcode::Jump:
- case Opcode::Return:
- case Opcode::LocalEnter:
- case Opcode::LoadProperty:
- case Opcode::StoreProperty:
- return 4;
- case Opcode::Discard:
- case Opcode::Duplicate:
- case Opcode::Add:
- case Opcode::Subtract:
- case Opcode::Multiply:
- case Opcode::Divide:
- case Opcode::Modulus:
- case Opcode::Negate:
- case Opcode::Create:
- case Opcode::Transform:
- case Opcode::Get:
- case Opcode::Position:
- case Opcode::Kill:
- return 0;
- }
- }
-
- void VirtualMachine::Run()
- {
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- //std::string names[] = { "Load", "Store", "Constant", "Increment", "Discard", "Duplicate", "Add", "Subtract", "Multiply", "Divide", "Modulus", "Negate", "Create", "Transform", "Get", "Position", "Kill", "JumpEqual", "JumpNotEqual", "JumpGreater", "JumpGreaterEqual", "JumpLess", "JumpLessEqual", "Jump", "Return", "LocalEnter"};
-
- Word temp1;
- Word temp2;
- Word temp3;
- Word temp4;
- int temp;
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- //std::cerr << programCounter << "\t" << names[rom[programCounter].Opcode] << "\t" << argument.Integer << std::endl;//"\t";
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- PSPush(CSA(argument.Integer));
- break;
- case Opcode::Store:
- CSA(argument.Integer) = PSPop();
- break;
- case Opcode::Constant:
- PSPush(argument);
- break;
- case Opcode::Increment:
- PS().Integer += argument.Integer;
- break;
- case Opcode::Discard:
- programStack += WORDSIZE;
- break;
- case Opcode::Duplicate:
- PSPush(PS());
- break;
- case Opcode::Add:
- PSPush(PSPop().Integer + PSPop().Integer);
- break;
- case Opcode::Subtract:
- temp1 = PSPop();
- PSPush(PSPop().Integer - temp1.Integer);
- break;
- case Opcode::Multiply:
- PSPush(PSPop().Integer * PSPop().Integer);
- break;
- case Opcode::Divide:
- temp1 = PSPop();
- PSPush(PSPop().Integer / temp1.Integer);
- break;
- case Opcode::Modulus:
- temp1 = PSPop();
- PSPush(PSPop().Integer % temp1.Integer);
- break;
- case Opcode::Negate:
- PS().Integer = -PS().Integer;
- break;
- case Opcode::Create:
- temp1 = PSPop();
- temp2 = PSPop();
- temp3 = PSPop();
- PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- PSPop();
- PSPop();
- PSPush((Word)-1);
- break;
- case Opcode::Get:
- temp1 = PSPop();
- temp2 = PSPop();
- if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer]))
- {
- PSPush(-1);
- break;
- }
- PSPush(temp>>8);
- break;
- case Opcode::Position:
- temp1 = PSPop();
- if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type)
- {
- PSPush(-1);
- PSPush(-1);
- break;
- }
- PSPush((int)sim->parts[temp1.Integer].x);
- PSPush((int)sim->parts[temp1.Integer].y);
- break;
- case Opcode::Kill:
- sim->kill_part(PSPop().Integer);
- PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- temp1 = PSPop();
- PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- if(PSPop().Integer == PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpNotEqual:
- if(PSPop().Integer != PSPop().Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreater:
- temp1 = PSPop();
- if(PSPop().Integer > temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpGreaterEqual:
- temp1 = PSPop();
- if(PSPop().Integer >= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLess:
- temp1 = PSPop();
- if(PSPop().Integer < temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::JumpLessEqual:
- temp1 = PSPop();
- if(PSPop().Integer <= temp1.Integer)
- programCounter = argument.Integer-1;
- break;
- case Opcode::Jump:
- programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- callStack += argument.Integer;
- break;
- case Opcode::LocalEnter:
- callStack -= argument.Integer;
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::Compile()
- {
- while(programCounter < romSize)
- {
- Word argument = rom[programCounter].Parameter;
- switch(rom[programCounter].Opcode)
- {
- case Opcode::Load:
- emit("83 EF 04"); //sub edi 4
-
- //Load value at base stack + offset into eax
- emit("8B 85"); //mov eax [ebp+ram+offset]
- emit((intptr_t) (ram - argument.Integer));
-
- //Store value in eax onto top of program stack
- emit("89 07"); //mov [edi], eax
- emit((intptr_t) (ram));
- break;
- case Opcode::Store:
- //Load value on top of the program stack into eax
- emit("8B 07"); //mov eax [edi]
- emit((intptr_t) (ram));
-
- //Load value in eax onto top of program stack
- emit("89 85"); //mov [ebp+ram+offset], eax
- emit((intptr_t) (ram - argument.Integer));
-
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Constant:
- emit("83 EF 04"); //sub edi 4
-
- emit("C7 07"); //mov [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Increment:
- emit("81 07"); //add [edi] constant
- emit((int) (argument.Integer));
- break;
- case Opcode::Discard:
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Duplicate:
- //Copy value on stack into register
- emit("8B 07"); //mov eax [edi]
- //Adjust program stack pointer
- emit("83 EF 04"); //sub edi 4
- //Move value in eax into program stack
- emit("89 07"); //mov [edi], eax
- break;
- case Opcode::Add:
- emit("8B 07"); //mov eax [edi]
- emit("01 47 04"); //add [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Subtract:
- emit("8B 07"); //mov eax [edi]
- emit("29 47 04"); //sub [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Multiply:
- emit("8B 47 04"); //mov eax [edi+4]
- emit("F7 2F"); //imul [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Divide:
- emit("8B 47 04");//mov eax [edi+4]
- emit("99"); //cdq
- emit("F7 3F"); //idiv [edi]
- emit("89 47 04"); //mov [edi+4] eax
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Modulus:
- emit("8B 47 04"); // mov eax [edi+4]
- emit("99"); // cdq
- emit("F7 3F"); // idiv [edi]
- emit("89 57 04"); // mov [edi+4] edx
- emit("83 C7 04"); //add edi 4
- break;
- case Opcode::Negate:
- emit("F7 1F"); //neg [edi]
- break;
- case Opcode::Create:
- //temp1 = PSPop();
- //temp2 = PSPop();
- //temp3 = PSPop();
- //PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
- break;
- case Opcode::Transform:
- //PSPop();
- //PSPop();
- //PSPush((Word)-1);
- break;
- case Opcode::Get:
- //temp1 = PSPop();
- //temp2 = PSPop();
- //if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer]))
- //{
- // PSPush(-1);
- // break;
- //}
- //PSPush(temp>>8);
- break;
- case Opcode::Position:
- //temp1 = PSPop();
- //if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type)
- //{
- // PSPush(-1);
- // PSPush(-1);
- // break;
- //}
- //PSPush((int)sim->parts[temp1.Integer].x);
- //PSPush((int)sim->parts[temp1.Integer].y);
- break;
- case Opcode::Kill:
- //sim->kill_part(PSPop().Integer);
- //PSPush((Word)0);
- break;
- case Opcode::LoadProperty:
- //PSPush(PPROP(PSPop().Integer, argument.Integer));
- break;
- case Opcode::StoreProperty:
- //temp1 = PSPop();
- //PPROP(temp1.Integer, argument.Integer) = PSPop();
- break;
- case Opcode::JumpEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("75 06"); //jne +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpNotEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("74 06"); //je +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreater:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7E 06"); //jng +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpGreaterEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7C 06"); //jnge +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLess:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7D 06"); //jnl +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::JumpLessEqual:
- emit("83 C7 04"); //add edi 8
- emit("8B 47 FC"); //mov eax, dword ptr [edi-4]
- emit("3B 47 F7"); //cmp eax, dword ptr [edi-8]
- emit("7F 06"); //jnle +6
- emit("FF 25"); //jmp [0x12345678]
- emit(0);
- break;
- case Opcode::Jump:
- //programCounter = argument.Integer-1;
- break;
- case Opcode::Return:
- emit("81 C6"); //add esi constant
- emit(argument.Integer);
- break;
- case Opcode::LocalEnter:
- emit("81 EE"); //sub esi constant
- emit(argument.Integer);
- break;
- }
- //std::cout << programStack << std::endl;
- programCounter++;
- }
- //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
- }
-
- void VirtualMachine::emit(std::string opcode)
- {
-
- }
-
- void VirtualMachine::emit(int constant)
- {
-
- }
-
- void VirtualMachine::CallCompiled(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::CallCompiled(int entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(std::string entryPoint)
- {
-
- }
-
- void VirtualMachine::Call(int entryPoint)
- {
- programCounter = entryPoint;
- Run();
- }
-}
diff --git a/src/pim/Machine.h b/src/pim/Machine.h
deleted file mode 100644
index 0cbac4c..0000000
--- a/src/pim/Machine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <string>
-#include <cstring>
-
-class Simulation;
-namespace pim
-{
- union Word
- {
- int Integer;
- float Decimal;
-
- Word(int integer) : Integer(integer) {}
- Word(float decimal) : Decimal(decimal) {}
- Word() {}
- };
- struct Instruction
- {
- int Opcode;
- Word Parameter;
- };
- class InvalidProgramException: public std::exception
- {
- public:
- InvalidProgramException() { }
- const char * what() const throw()
- {
- return "Invalid program";
- }
- ~InvalidProgramException() throw() {};
- };
- class UnresolvedValueException: public std::exception
- {
- char * error;
- public:
- UnresolvedValueException(std::string value) {
- error = strdup(std::string("Unresolved value: " + value).c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~UnresolvedValueException() throw() {};
- };
- class VirtualMachine
- {
-
- #define WORDSIZE 4
-
- //#define OPDEF(name) void op##name(int parameter);
- //#include "Opcodes.inl"
- //#undef OPDEF
-
- Simulation * sim;
-
- Instruction * rom;
- int romSize;
- int romMask;
-
- unsigned char * compiledRom;
- int compiledRomSize;
-
- unsigned char * ram;
- int ramSize;
- int ramMask;
-
- #define CSA(argument) (*((Word*)&ram[framePointer-argument]))
- #define CS() (*((Word*)&ram[callStack]))
- #define PS() (*((Word*)&ram[programStack]))
- #define PPROP(index, property) (*((Word*)(((char*)&sim->parts[(index)])+property)))
-
- int programStack; //Points to the item on top of the Program Stack
- int callStack; //Points to the item on top of the call stack
- int framePointer; //Points to the bottom (first item) on the current frame of the call stack
-
- //Instruction * instructions;
-
- int programCounter;
-
- void emit(std::string opcode);
- void emit(int constant);
- public:
- VirtualMachine(Simulation * sim);
- int OpcodeArgSize(int opcode);
- void LoadProgram(std::vector<unsigned char> programData);
- void Run();
- void Compile();
- void CallCompiled(std::string entryPoint);
- void CallCompiled(int entryPoint);
- void Call(std::string entryPoint);
- void Call(int entryPoint);
- inline void PSPush(Word word)
- {
- programStack -= WORDSIZE;
- PS() = word;
- }
-
- inline Word PSPop()
- {
- Word word = PS();
- programStack += WORDSIZE;
- return word;
- }
-
- inline void CSPush(Word word)
- {
- callStack -= WORDSIZE;
- CS() = word;
- }
-
- inline Word CSPop()
- {
- Word word = CS();
- callStack += WORDSIZE;
- return word;
- }
- };
-}
diff --git a/src/pim/Opcodes.h b/src/pim/Opcodes.h
deleted file mode 100644
index a701e97..0000000
--- a/src/pim/Opcodes.h
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace pim
-{
- struct Opcode
- {
- enum
- {
- #define OPDEF(name) name,
- #include "Opcodes.inl"
- #undef OPDEF
- };
- };
-}
diff --git a/src/pim/Opcodes.inl b/src/pim/Opcodes.inl
deleted file mode 100644
index 4b28294..0000000
--- a/src/pim/Opcodes.inl
+++ /dev/null
@@ -1,28 +0,0 @@
-OPDEF(Load)
-OPDEF(Store)
-OPDEF(Constant)
-OPDEF(Increment)
-OPDEF(Discard)
-OPDEF(Duplicate)
-OPDEF(Add)
-OPDEF(Subtract)
-OPDEF(Multiply)
-OPDEF(Divide)
-OPDEF(Modulus)
-OPDEF(Negate)
-OPDEF(Create)
-OPDEF(Transform)
-OPDEF(Get)
-OPDEF(Position)
-OPDEF(Kill)
-OPDEF(LoadProperty)
-OPDEF(StoreProperty)
-OPDEF(JumpEqual)
-OPDEF(JumpNotEqual)
-OPDEF(JumpGreater)
-OPDEF(JumpGreaterEqual)
-OPDEF(JumpLess)
-OPDEF(JumpLessEqual)
-OPDEF(Jump)
-OPDEF(Return)
-OPDEF(LocalEnter) \ No newline at end of file
diff --git a/src/pim/Parser.cpp b/src/pim/Parser.cpp
deleted file mode 100644
index 0165141..0000000
--- a/src/pim/Parser.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-//Syntax analyser
-#include "Parser.h"
-#include "Format.h"
-namespace pim
-{
- namespace compiler
- {
- Parser::Parser(std::stringstream & source_) :
- source(source_)
- {
- scanner = new Scanner(source);
- generator = new Generator();
-
- token = scanner->NextToken();
-
- }
-
- std::vector<unsigned char> Parser::Compile()
- {
- program();
- return generator->Finish();
- }
-
- /*
- <program> ::= <function list>
- */
- void Parser::program()
- {
- functionList();
- }
-
- /*
- <function list> ::= <function> | <function> <function list>
- */
- void Parser::functionList()
- {
- function();
- while(look(Token::FunctionSymbol))
- function();
- }
-
- /*
- <function> ::= function identifier ( <declaration list> ) <block> end
- */
- void Parser::function()
- {
- std::string functionName;
-
- expect(Token::FunctionSymbol);
-
- functionName = token.Source;
- //generator->ScopeLabel(functionName); //Function name
- generator->PushScope(functionName);
- expect(Token::Identifier);
-
- expect(Token::LeftBracket);
- if(!accept(Token::RightBracket))
- {
- argumentList();
- expect(Token::RightBracket);
- }
- block();
- expect(Token::EndSymbol);
- generator->Return();
-
- generator->PopScope();
- }
-
- /*
- <function call> ::= identifier ( <expression list> )
- */
- void Parser::functionCall()
- {
- std::string functionName;
-
- functionName = token.Source;
- expect(Token::Identifier);
- expect(Token::LeftBracket);
- expressionList();
- expect(Token::RightBracket);
- //generator->Call(functionName);
- }
-
- /*
- <block> ::= <declaration list> <statement list>
- */
- void Parser::block()
- {
- if(look(Token::IntegerSymbol) || look(Token::DecimalSymbol) || look(Token::ParticleSymbol))
- declarationList();
- statementList();
- }
-
- /*
- <argument list> ::= <argument> | <argument> , <argument list>
- */
- void Parser::argumentList()
- {
- argument();
- while(accept(Token::CommaSymbol))
- argument();
- }
-
- /*
- <argument> ::= integer identifier | decimal identifier | particle identifier
- */
- void Parser::argument()
- {
- generator->ScopeVariableType(token.Symbol);
- if(!accept(Token::IntegerSymbol))
- if(!accept(Token::DecimalSymbol))
- if(!accept(Token::ParticleSymbol))
- throw ParserExpectException(token, "type name");
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- }
-
- /*
- <declaration list> ::= <declaration> | <declaration> , <declaration list>
- */
- void Parser::declarationList()
- {
- declaration();
- while(accept(Token::CommaSymbol))
- declaration();
- }
-
- /*
- <declaration> ::= integer <identifier list> | decimal <identifier list> | particle <identifier list>
- */
- void Parser::declaration()
- {
- generator->ScopeVariableType(token.Symbol);
- if(!accept(Token::IntegerSymbol))
- if(!accept(Token::DecimalSymbol))
- if(!accept(Token::ParticleSymbol))
- throw ParserExpectException(token, "type name");
- identifierList();
- }
-
- /*
- <identifier list> ::= identifier | identifier , <identifier list>
- */
- void Parser::identifierList()
- {
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- while(accept(Token::CommaSymbol))
- {
- generator->ScopeVariable(token.Source);
- expect(Token::Identifier);
- }
- }
-
- /*
- <statement list> ::= <statement> | <statement> <statement list>
- */
- void Parser::statementList()
- {
- statement();
- while(!look(Token::EndSymbol) && !look(Token::ElseIfSymbol))
- statement();
- }
-
- /*
- <statement> ::= <neighbour statement> | <if statement> | <assignment statement> | <function call> | <particle action> | break | continue
- */
- void Parser::statement()
- {
- //generator->Begin(NonTerminal::Statement);
- if(look(Token::NeighbourSymbol))
- {
- neighbourStatement();
- }
- else if(look(Token::IfSymbol))
- {
- ifStatement();
- }
- else if(look(Token::CreateSymbol) || look(Token::KillSymbol) || look(Token::GetSymbol) || look(Token::TransformSymbol))
- {
- particleAction();
- generator->Discard();
- }
- else if(look(Token::BreakSymbol))
- {
- expect(Token::BreakSymbol);
- generator->Jump(breakLabel);
- }
- else if(look(Token::ContinueSymbol))
- {
- expect(Token::ContinueSymbol);
- generator->Jump(continueLabel);
- }
- else if(look(Token::Identifier))
- {
- assigmentStatement();
- }
- //generator->End(NonTerminal::Statement);
- }
-
- /*
- <particle action> ::= <kill statement> | <create statement> | <transform statement>
- */
- void Parser::particleAction()
- {
- if(look(Token::KillSymbol))
- {
- killStatement();
- }
- else if(look(Token::CreateSymbol))
- {
- createStatement();
- }
- else if(look(Token::TransformSymbol))
- {
- transformStatement();
- }
-
- }
-
- /*
- <kill statement> ::= kill ( <expression> )
- */
- void Parser::killStatement()
- {
- expect(Token::KillSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::RightBracket);
- generator->KillParticle();
- }
-
- /*
- <create statement> ::= create ( <expression>, <expression>, <expression>, <expression> )
- */
- void Parser::createStatement()
- {
- expect(Token::CreateSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->CreateParticle();
- }
-
- /*
- <transform statement> ::= transform ( <expression>, <expression> )
- */
- void Parser::transformStatement()
- {
- expect(Token::TransformSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->TransformParticle();
- }
-
- /*
- <get statement> ::= get ( <expression>, <expression> )
- */
- void Parser::getStatement()
- {
- expect(Token::GetSymbol);
- expect(Token::LeftBracket);
- expression();
- expect(Token::CommaSymbol);
- expression();
- expect(Token::RightBracket);
- generator->GetParticle();
- }
-
- /*
- <neighbour statement> ::= neighbour identifier for <expression> do <block> end | neighbour identifier for <expression>, <expression> do <block> end
- */
- void Parser::neighbourStatement()
- {
- std::string neighbourVariable;
- std::string loopLabel = generator->UniqueLabel("neighbour");
- std::string xVar = loopLabel+"X";
- std::string xMin = loopLabel+"minX";
- std::string xMax = loopLabel+"maxX";
- std::string yVar = loopLabel+"Y";
- std::string yMax = loopLabel+"maxY";
- breakLabel = loopLabel+"End";
- continueLabel = loopLabel+"Next";
-
- expect(Token::NeighbourSymbol);
-
- generator->PushLocalScope(loopLabel+"Start");
- neighbourVariable = token.Source;
- expect(Token::Identifier);
- generator->ScopeVariableType(Token::IntegerConstant);
- generator->ScopeVariable(neighbourVariable);
- generator->ScopeVariable(xVar);
- generator->ScopeVariable(yVar);
- generator->ScopeVariable(xMin);
- generator->ScopeVariable(xMax);
- generator->ScopeVariable(yMax);
-
- generator->LocalEnter();
-
- expect(Token::OfSymbol);
-
- //Initialise position
- expression();
- generator->GetPosition();
- generator->Duplicate();
- generator->Increment("-1");
- generator->StoreVariable(yVar);
- generator->Increment("1");
- generator->StoreVariable(yMax);
-
- generator->Duplicate();
- generator->Increment("-1");
- generator->Duplicate();
- generator->StoreVariable(xVar);
- generator->StoreVariable(xMin);
- generator->Increment("1");
- generator->StoreVariable(xMax);
-
- //if(accept(Token::CommaSymbol))
- // expression();
- expect(Token::DoSymbol);
-
- generator->ScopeLabel(loopLabel+"Next");
-
-
-
-
-
- //Check X
- generator->LoadVariable(xVar);
- generator->LoadVariable(xMax);
- //generator->Duplicate(); //Duplicate xvar so it can be used for incrementing
-
- generator->JumpLessEqual(loopLabel+"Begin");
- //if(xVar > xMax) {
-
- //Reset X, increment Y
- generator->LoadVariable(xMin);
- generator->StoreVariable(xVar);
-
- generator->LoadVariable(yVar);
- generator->Increment("1");
- generator->Duplicate();
- generator->StoreVariable(yVar);
-
-
- //Check Y
- generator->LoadVariable(yMax);
- generator->JumpGreater(loopLabel+"End");
-
- //}
-
- //Start of loop
- generator->ScopeLabel(loopLabel+"Begin");
-
- generator->LoadVariable(xVar);
- generator->LoadVariable(yVar);
- generator->GetParticle();
- generator->StoreVariable(neighbourVariable);
-
- block();
-
- //Increment X
- generator->LoadVariable(xVar);
- generator->Increment("1");
- generator->StoreVariable(xVar);
-
- //Next element
- generator->Jump(loopLabel+"Next");
-
- generator->ScopeLabel(loopLabel+"End");
- generator->Return();
- generator->PopScope();
- expect(Token::EndSymbol);
- }
-
- /*
- <if statement> ::= if <condition> then <block> end
- */
- void Parser::ifStatement()
- {
- std::string label = generator->UniqueLabel("if");
- int blockNum = 0;
- expect(Token::IfSymbol);
- condition(label+format::NumberToString<int>(blockNum));
- expect(Token::ThenSymbol);
- block();
- while(accept(Token::ElseIfSymbol))
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- condition(label+format::NumberToString<int>(blockNum));
- expect(Token::ThenSymbol);
- block();
- }
- if(accept(Token::ElseSymbol))
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- block();
- }
- else
- {
- generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
- }
- expect(Token::EndSymbol);
- //generator->End(NonTerminal::IfStatement);
- }
-
- /*
- <condition> ::= <expression> <conditional operator> <expression>
- */
- void Parser::condition(std::string jumpLabel)
- {
- expression();
-
- Token token = forward();
-
- expression();
-
- if(token.Symbol == Token::GreaterSymbol)
- {
- generator->JumpLessEqual(jumpLabel);
- }
- else if(token.Symbol == Token::GreaterEqualSymbol)
- {
- generator->JumpLess(jumpLabel);
- }
- else if(token.Symbol == Token::EqualSymbol)
- {
- generator->JumpNotEqual(jumpLabel);
- }
- else if(token.Symbol == Token::NotEqualSymbol)
- {
- generator->JumpEqual(jumpLabel);
- }
- else if(token.Symbol == Token::LessSymbol)
- {
- generator->JumpGreaterEqual(jumpLabel);
- }
- else if(token.Symbol == Token::LessEqualSymbol)
- {
- generator->JumpGreater(jumpLabel);
- }
- else
- throw ParserExpectException(token, "conditional operator");
- }
-
- /*
- <assigment statement> ::= identifier = <expression> | identifier.property = <expression>
- */
- void Parser::assigmentStatement()
- {
- std::string variable = token.Source;
- expect(Token::Identifier);
- if(accept(Token::AssignSymbol))
- {
- expression();
- generator->StoreVariable(variable);
- }
- else if(accept(Token::DotSymbol))
- {
- std::string property = token.Source;
- expect(Token::Identifier);
- expect(Token::AssignSymbol);
- expression();
- generator->LoadVariable(variable);
- generator->StoreProperty(property);
- }
- }
-
- /*
- <expression list> ::= <expression> | <expression> , <expression list>
- */
- void Parser::expressionList()
- {
- //generator->Begin(NonTerminal::ExpressionList);
- expression();
- while(accept(Token::CommaSymbol))
- expression();
- //generator->End(NonTerminal::ExpressionList);
- }
-
- /*
- <expression> ::= <term> | <expression> + <term> | <expression> - <term>
- */
- void Parser::expression()
- {
- term();
- int as = token.Symbol;
- while(accept(Token::PlusSymbol) || accept(Token::MinusSymbol))
- {
- term();
- if(as == Token::PlusSymbol)
- generator->Add();
- else if(as == Token::MinusSymbol)
- generator->Subtract();
- }
- //generator->End(NonTerminal::Expression);
- }
-
- /*
- <term> ::= <factor> | <term> * <factor> | <term> / <factor>
- */
- void Parser::term()
- {
- //generator->Begin(NonTerminal::Term);
- factor();
- int md = token.Symbol;
- while(accept(Token::MultiplySymbol) || accept(Token::DivideSymbol))
- {
- factor();
- if(md == Token::MultiplySymbol)
- generator->Multiply();
- else if(md == Token::DivideSymbol)
- generator->Divide();
- }
- //generator->End(NonTerminal::Term);
- }
-
- /*
- <factor> ::= <variable value> | - <variable value> | numberConstant | - numberConstant | ( <expression> ) | - ( <expression> )
- */
- void Parser::factor()
- {
- bool doNegate = false;
- std::string factor = token.Source;
- if(accept(Token::MinusSymbol))
- {
- factor = token.Source;
- doNegate = true;
- }
- if(accept(Token::IntegerConstant) || accept(Token::DecimalConstant))
- {
- if(doNegate)
- {
- doNegate = false;
- generator->Constant("-" + factor);
- }
- else
- generator->Constant(factor);
- }
- else if(accept(Token::LeftBracket))
- {
- expression();
- expect(Token::RightBracket);
- }
- else
- {
- variableValue();
- }
- if(doNegate)
- generator->Negate();
- }
-
- /*
- <variable value> ::= <function call> | identifier | identifier.property | rtmacro | <particle action>
- */
- void Parser::variableValue()
- {
- std::string variable = token.Source;
- if(accept(Token::Identifier))
- {
- if(look(Token::LeftBracket))
- {
- back();
- functionCall();
- }
- else
- {
- if(accept(Token::DotSymbol))
- {
- std::string property = token.Source;
- expect(Token::Identifier);
- generator->LoadVariable(variable);
- generator->LoadProperty(property);
- }
- else
- {
- generator->LoadVariable(variable);
- }
- }
- }
- else if(accept(Token::RTMacro))
- {
- generator->RTConstant(variable);
- }
- else
- {
- particleAction();
- }
- }
-
- bool Parser::accept(int symbol)
- {
- if(symbol == token.Symbol)
- {
- lastToken = token;
- if(previousTokens.size())
- {
- token = previousTokens.top();
- previousTokens.pop();
- }
- else
- token = scanner->NextToken();
- //std::cout << "Symbol " << Token::SymbolNames[symbol] << " " << lastToken.Source << std::endl;
- return true;
- }
- //std::cout << "Bad Symbol " << Token::SymbolNames[symbol] << " " << token.Source << " (" << token.GetName() << ")" << std::endl;
- return false;
- }
-
-
- bool Parser::look(int symbol)
- {
- if(symbol == token.Symbol)
- return true;
- return false;
- }
-
- void Parser::back()
- {
- previousTokens.push(token);
- token = lastToken;
- }
-
- Token Parser::forward()
- {
- lastToken = token;
- if(previousTokens.size())
- {
- token = previousTokens.top();
- previousTokens.pop();
- }
- else
- token = scanner->NextToken();
- return lastToken;
- }
-
- void Parser::expect(int symbol)
- {
- if(!accept(symbol))
- throw ParserExpectException(token, symbol);
- }
- }
-}
diff --git a/src/pim/Parser.h b/src/pim/Parser.h
deleted file mode 100644
index 19a2835..0000000
--- a/src/pim/Parser.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <string>
-#include <cstring>
-#include <sstream>
-#include "Scanner.h"
-#include "Generator.h"
-#include "Token.h"
-namespace pim
-{
- namespace compiler
- {
- class ParserExpectException: public std::exception
- {
- char * error;
- public:
- ParserExpectException(Token token, int expectingSymbol) {
- error = strdup(std::string("Expecting " + Token::SymbolNames[expectingSymbol] + " got " + token.Source).c_str());
- }
- ParserExpectException(Token token, std::string expectingString) {
- error = strdup(std::string("Expecting " + expectingString + " got " + token.Source).c_str());
- }
- const char * what() const throw()
- {
- return error;
- }
- ~ParserExpectException() throw() {};
- };
- class Parser
- {
- std::stringstream & source;
- Generator * generator;
- Scanner * scanner;
- Token token;
- Token lastToken;
- std::string breakLabel;
- std::string continueLabel;
- std::stack<Token> previousTokens;
-
- void program();
- void functionList();
- void function();
- void functionCall();
- void block();
- void argumentList();
- void argument();
- void declarationList();
- void declaration();
- void identifierList();
- void statementList();
- void statement();
- void neighbourStatement();
- void ifStatement();
- void condition(std::string jumpLabel);
- void assigmentStatement();
- void particleAction();
- void killStatement();
- void getStatement();
- void createStatement();
- void transformStatement();
- void expressionList();
-
- void expression();
- void term();
- void factor();
- void variableValue();
-
- Token forward();
- bool accept(int symbol);
- bool look(int symbol);
- void back();
- void expect(int symbol);
- public:
- Parser(std::stringstream & source_);
-
- std::vector<unsigned char> Compile();
- };
- }
-}
diff --git a/src/pim/Scanner.cpp b/src/pim/Scanner.cpp
deleted file mode 100644
index 4ceb942..0000000
--- a/src/pim/Scanner.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//Lexical analyser
-#include <algorithm>
-#include <cctype>
-#include "Scanner.h"
-
-namespace pim
-{
- namespace compiler
- {
- Scanner::Scanner(std::stringstream & source_) :
- source(source_)
- {
- nextCharacter();
- }
-
- Token Scanner::NextToken()
- {
- //Read whitespace, newlines and comments
- while(
- cChar == ' ' || cChar == '\t' ||
- cChar == '\r' || cChar == '\n' ||
- cChar == '/')
- {
- if(cChar == '/')
- {
- nextCharacter();
- if(cChar == '/')
- {
- while(cChar != '\n' && cChar != '\r')
- nextCharacter();
- }
- else
- return Token(Token::DivideSymbol, "/", cLine);
- }
-
- if(cChar == '\r')
- {
- nextCharacter();
- if(cChar == '\n')
- cLine++;
- else
- continue;
- }
- else if(cChar == '\n')
- cLine++;
-
- nextCharacter();
- }
-
- if(std::isalpha(cChar)) //Read alphanumeric symbols
- {
- cToken.clear();
- while(std::isalpha(cChar) || std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
-
- std::transform(cToken.begin(), cToken.end(), cToken.begin(), ::tolower);
-
- for(int i = 0; i < Token::SymbolNumber; i++)
- if(Token::SymbolNames[i] == cToken)
- return Token(i, cToken, cLine);
- return Token(Token::Identifier, cToken, cLine);
- }
- else if(std::isdigit(cChar)) //Read numeric constants
- {
- bool decimal = false;
- cToken.clear();
- while(std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- if(cChar == '.')
- {
- decimal = true;
- cToken.push_back(cChar);
- nextCharacter();
- while(std::isdigit(cChar))
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- }
- if(decimal)
- return Token(Token::DecimalConstant, cToken, cLine);
- return Token(Token::IntegerConstant, cToken, cLine);
- }
- else if(cChar == '[')
- {
- cToken.clear();
- nextCharacter();
- while(std::isalpha(cChar) || std::isdigit(cChar) || cChar == '_' || cChar == '-')
- {
- cToken.push_back(cChar);
- nextCharacter();
- }
- nextCharacter();
-
- std::transform(cToken.begin(), cToken.end(), cToken.begin(), ::toupper);
-
- return Token(Token::RTMacro, cToken, cLine);
- }
- else if(cChar == '=')
- {
- nextCharacter();
- if(cChar == '=')
- {
- nextCharacter();
- return Token(Token::EqualSymbol, "==", cLine);
- }
- return Token(Token::AssignSymbol, "=", cLine);
- }
- else if(cChar == '!')
- {
- nextCharacter();
- if(cChar == '=')
- return Token(Token::NotEqualSymbol, "==", cLine);
- }
- else if(cChar == '(')
- {
- nextCharacter();
- return Token(Token::LeftBracket, "(", cLine);
- }
- else if(cChar == ')')
- {
- nextCharacter();
- return Token(Token::RightBracket, ")", cLine);
- }
- else if(cChar == '/')
- {
- nextCharacter();
- return Token(Token::DivideSymbol, "/", cLine);
- }
- else if(cChar == '*')
- {
- nextCharacter();
- return Token(Token::MultiplySymbol, "*", cLine);
- }
- else if(cChar == '+')
- {
- nextCharacter();
- return Token(Token::PlusSymbol, "+", cLine);
- }
- else if(cChar == '-')
- {
- nextCharacter();
- return Token(Token::MinusSymbol, "-", cLine);
- }
- else if(cChar == '%')
- {
- nextCharacter();
- return Token(Token::ModuloSymbol, "%", cLine);
- }
- else if(cChar == '<')
- {
- nextCharacter();
- if(cChar == '=')
- {
- return Token(Token::LessEqualSymbol, "<=", cLine);
- }
- return Token(Token::LessSymbol, "<", cLine);
- }
- else if(cChar == '>')
- {
- nextCharacter();
- if(cChar == '=')
- {
- return Token(Token::GreaterEqualSymbol, ">=", cLine);
- }
- return Token(Token::GreaterSymbol, ">", cLine);
- }
- else if(cChar == ',')
- {
- nextCharacter();
- return Token(Token::CommaSymbol, ",", cLine);
- }
- else if(cChar == '.')
- {
- nextCharacter();
- return Token(Token::DotSymbol, ".", cLine);
- }
- else
- {
- nextCharacter();
- return Token(Token::InvalidSymbol, std::string(1, cChar), cLine);
- }
- }
-
- void Scanner::nextCharacter()
- {
- if(source.good())
- cChar = source.get();
- else
- cChar = 0;
- }
- }
-}
diff --git a/src/pim/Scanner.h b/src/pim/Scanner.h
deleted file mode 100644
index 70e02ac..0000000
--- a/src/pim/Scanner.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <string>
-#include <sstream>
-#include "Token.h"
-namespace pim
-{
- namespace compiler
- {
- class Scanner
- {
- char cChar;
- int cLine;
- std::string cToken;
- std::stringstream & source;
- void nextCharacter();
- public:
- Scanner(std::stringstream & source_);
- Token NextToken();
- };
- }
-}
diff --git a/src/pim/Token.cpp b/src/pim/Token.cpp
deleted file mode 100644
index 62931ac..0000000
--- a/src/pim/Token.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "Token.h"
-
-namespace pim
-{
- namespace compiler
- {
- std::string Token::SymbolNames[] = {
- "=",
- "function",
- "(",
- ")",
- "/",
- "*",
- "+",
- "-",
- "%",
- "INTEGER",
- "DECIMAL",
- "PARTICLE",
- "integer",
- "decimal",
- "particle",
- "is",
- "<",
- "<=",
- ">",
- ">=",
- "==",
- "!=",
- "neighbour",
- "do",
- "of",
- "break",
- "continue",
- "if",
- "else",
- "elseif",
- "then",
- "end",
- "kill",
- "create",
- "transform",
- "get",
- "RUNTIMEMACRO",
- "IDENTIFIER",
- ",",
- ".",
- "INVALID SYMBOL"
- };
- }
-}
diff --git a/src/pim/Token.h b/src/pim/Token.h
deleted file mode 100644
index 95d3f08..0000000
--- a/src/pim/Token.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-#include <string>
-namespace pim
-{
- namespace compiler
- {
- class Token
- {
- public:
- static std::string SymbolNames[];
-
- enum
- {
- AssignSymbol = 0,
- FunctionSymbol,
-
- LeftBracket,
- RightBracket,
- DivideSymbol,
- MultiplySymbol,
- PlusSymbol,
- MinusSymbol,
- ModuloSymbol,
-
- IntegerConstant,
- DecimalConstant,
- ParticleConstant,
-
- IntegerSymbol,
- DecimalSymbol,
- ParticleSymbol,
-
- IsSymbol,
- LessSymbol,
- LessEqualSymbol,
- GreaterSymbol,
- GreaterEqualSymbol,
- NotEqualSymbol,
- EqualSymbol,
-
- NeighbourSymbol,
- DoSymbol,
- OfSymbol,
- BreakSymbol,
- ContinueSymbol,
- IfSymbol,
- ElseSymbol,
- ElseIfSymbol,
- ThenSymbol,
- EndSymbol,
-
- KillSymbol,
- CreateSymbol,
- TransformSymbol,
- GetSymbol,
-
- RTMacro,
- Identifier,
-
- CommaSymbol,
- DotSymbol,
-
- InvalidSymbol,
-
- SymbolNumber
- };
- int Symbol;
- int LineNumber;
- std::string Source;
-
- Token(int symbol = InvalidSymbol, std::string source = "HERP DERP", int lineNumber = 0) :
- Symbol(symbol),
- Source(source),
- LineNumber(lineNumber) {}
-
- std::string GetName()
- {
- return SymbolNames[Symbol];
- }
- };
- }
-}
diff --git a/src/tests/PowderInteractionMachine.cpp b/src/tests/PowderInteractionMachine.cpp
deleted file mode 100644
index 329cfd7..0000000
--- a/src/tests/PowderInteractionMachine.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifdef TEST
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include "pim/Parser.h"
-
-int main(int argc, char * argv[])
-{
- std::ifstream file("test.p");
-
- std::stringstream buffer;
-
- buffer << file.rdbuf();
- file.close();
-
- pim::compiler::Parser * parser = new pim::compiler::Parser(buffer);
-
- parser->Compile();
-}
-#endif
diff --git a/src/tests/VirtualMachineTest.cpp b/src/tests/VirtualMachineTest.cpp
deleted file mode 100644
index 1f8a52d..0000000
--- a/src/tests/VirtualMachineTest.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifdef TEST
-
-#include <iostream>
-#include "virtualmachine/VirtualMachine.h"
-
-int main(int argc, char * argv[])
-{
- vm::VirtualMachine * vm = new vm::VirtualMachine(2);
- vm->LoadProgram("test.qvm");
- while(true)
- {
- vm->Call(0/*, 0, 88, 12*/);
- std::cout << "Return value: " << vm->Pop<vm::uint4_t>() << std::endl;
- }
-}
-#endif
diff --git a/src/tests/test.qvm b/src/tests/test.qvm
deleted file mode 100644
index 22b99b2..0000000
--- a/src/tests/test.qvm
+++ /dev/null
Binary files differ
diff --git a/src/virtualmachine/Exceptions.h b/src/virtualmachine/Exceptions.h
deleted file mode 100644
index 3a25e87..0000000
--- a/src/virtualmachine/Exceptions.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#pragma once
-#include <stdexcept>
-#include <cstring>
-#include "Format.h"
-
-namespace vm
-{
- class RuntimeException: public std::exception
- {
- char * error;
- public:
- RuntimeException() : error(NULL) {}
- RuntimeException(char * message) : error(strdup(message)) {}
- const char * what() const throw()
- {
- if(error)
- return error;
- else
- return "VirtualMachine runtime exception";
- }
- ~RuntimeException() throw() {};
- };
-
- class StackOverflowException: public RuntimeException
- {
- public:
- StackOverflowException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Stack overflow";
- }
- ~StackOverflowException() throw() {};
- };
-
- class StackUnderflowException: public RuntimeException
- {
- public:
- StackUnderflowException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Stack underflow";
- }
- ~StackUnderflowException() throw() {};
- };
-
- class AccessViolationException: public RuntimeException
- {
- int address;
- char * _what;
- public:
- AccessViolationException(int address = 0) : address(address)
- {
- _what = strdup(std::string("VirtualMachine Access violation at "+format::NumberToString<int>(address)).c_str());
- }
- const char * what() const throw()
- {
- if(address)
- return _what;
- return "VirtualMachine Access violation";
- }
- ~AccessViolationException() throw() {};
- };
-
- class JITException: public RuntimeException
- {
- char * _what;
- public:
- JITException(const char * what2)
- {
- _what = strdup(what2);
- }
- const char * what() const throw()
- {
- return _what;
- }
- ~JITException() throw() {};
- };
-
- class OutOfMemoryException: public RuntimeException
- {
- public:
- OutOfMemoryException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Out of memory";
- }
- ~OutOfMemoryException() throw() {};
- };
-
- class InvalidProgramException: public RuntimeException
- {
- public:
- InvalidProgramException() {}
- const char * what() const throw()
- {
- return "Could not load program";
- }
- ~InvalidProgramException() throw() {};
- };
-}
diff --git a/src/virtualmachine/JustInTime.cpp b/src/virtualmachine/JustInTime.cpp
deleted file mode 100644
index 9f6fe57..0000000
--- a/src/virtualmachine/JustInTime.cpp
+++ /dev/null
@@ -1,1144 +0,0 @@
-#ifdef VMJIT
-
-#include <cstdio>
-#include "VirtualMachine.h"
-
-#ifdef WIN32
-#include "Windows.h"
-#endif
-
-namespace vm
-{
- #define OP(n) OP##n
- /*
-
- eax scratch
- ebx scratch
- ecx scratch (required for shifts)
- edx scratch (required for divisions)
- esi RP
- edi DP
-
- */
-
- // TTimo: initialised the statics, this fixes a crash when entering a compiled VM
- static unsigned char *buf = NULL;
- static unsigned char *jused = NULL;
- static int compiledOfs = 0;
- static int pc = 0;
-
- //static int callMask = 0; // bk001213 - init
- static int eDP;
- static int eRP;
- static int instruction, pass;
- static int lastConst = 0;
- static int oc0, oc1, pop0, pop1;
-
- static int eRamMask = 0;
- static int eRomMask = 0;
- static int * eInstructionPointers = NULL;
-
- static int eSyscallNum;
- static void * eRam = NULL;
- static VirtualMachine * eVM = NULL;
-
- static int callFromCompiledPtr = (int)VirtualMachine::callFromCompiled;
- static int callSyscallPtr = (int)VirtualMachine::callSyscall;
-
- typedef enum
- {
- LAST_COMMAND_NONE = 0,
- LAST_COMMAND_MOV_EDI_EAX,
- LAST_COMMAND_SUB_DI_4,
- LAST_COMMAND_SUB_DI_8,
- } ELastCommand;
-
- static ELastCommand LastCommand;
-
- void VirtualMachine::callSyscall()
- {
- //throw RuntimeException("Turd");
-
- /*VirtualMachine * savedVM;
- int * callOpStack2;
-
- savedVM = eVM;
- callOpStack2 = (int*)eOpStack;
-
- // save the stack to allow recursive VM entry
- eVM->DP = eDP - 4;
- *(int *)((byte *)eVM->ram + eDP + 4) = eSyscallNum;
- //VM_LogSyscalls( (int *)((byte *)currentVM->dataBase + programStack + 4) );
- *(callOpStack2+1) = eVM->syscall( *(int *)((unsigned char *)eVM->ram + eDP + 4) );
-
- eVM = savedVM;*/
- }
-
- void VirtualMachine::callFromCompiled()
- {
- /*__asm__("doAsmCall: \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " subl $4,%%edi \n\t" \
- " orl %%eax,%%eax \n\t" \
- " jl systemCall \n\t" \
- " shll $2,%%eax \n\t" \
- " addl %3,%%eax \n\t" \
- " call *(%%eax) \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " andl %5, %%eax \n\t" \
- " jmp doret \n\t" \
- "systemCall: \n\t" \
- " negl %%eax \n\t" \
- " decl %%eax \n\t" \
- " movl %%eax,%0 \n\t" \
- " movl %%esi,%1 \n\t" \
- " movl %%edi,%2 \n\t" \
- " pushl %%ecx \n\t" \
- " pushl %%esi \n\t" \
- " pushl %%edi \n\t" \
- " call *%4 \n\t" \
- " popl %%edi \n\t" \
- " popl %%esi \n\t" \
- " popl %%ecx \n\t" \
- " addl $4,%%edi \n\t" \
- "doret: \n\t" \
- " ret \n\t" \
- : "=rm" (eSyscallNum), "=rm" (eDP), "=rm" (eOpStack) \
- : "rm" (eInstructionPointers), "r" (callSyscall), "m" (eRomMask) \
- : "ax", "di", "si", "cx" \
- );*/
- //" call *%4 \n\t"
-
- //" negl %%eax \n\t"
- // " decl %%eax \n\t"
- __asm__ volatile ("doAsmCall: \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " subl $4,%%edi \n\t" \
- " orl %%eax,%%eax \n\t" \
- " jl systemCall \n\t" \
- " shll $2,%%eax \n\t" \
- " addl %3,%%eax \n\t" \
- " call *(%%eax) \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " andl %5, %%eax \n\t" \
- " ret \n\t" \
- "systemCall: \n\t" \
- " movl %%eax,%0 \n\t" \
- " movl %%esi,%1 \n\t" \
- " movl %%edi,%2 \n\t" \
- " pushl %%ecx \n\t" \
- " pushl %%esi \n\t" \
- " pushl %%edi \n\t" \
- : "=rm" (eSyscallNum), "=rm" (eRP), "=rm" (eDP) \
- : "rm" (eInstructionPointers), "r" (callSyscall), "m" (eRomMask) \
- : "ax", "di", "si", "cx" \
- );
- //printf("Syscall: %d\n", eSyscallNum);
- //throw RuntimeException("Turd");
-
- eVM->DP = eDP-((int)eRam);
- eVM->syscall(eSyscallNum);
- eDP = eVM->DP+((int)eRam)-4;
-
- //" addl $4,%edi \n\t"
- // " ret \n\t"
- __asm__ volatile ("popl %edi \n\t" \
- " popl %esi \n\t" \
- " popl %ecx \n\t" \
- "doret: \n\t" \
- );
- }
-
- int VirtualMachine::CallCompiled(int address)
- {
- //int stack[1024];
- //int stack[100];
- int programStack;
- int stackOnEntry;
- unsigned char * image;
- void * entryPoint;
- int * oldInstructionPointers;
- void * oldDataStack;
-
- oldDataStack = eRam;
- oldInstructionPointers = eInstructionPointers;
-
- eVM = this;
- eInstructionPointers = instructionPointers;
-
- eRomMask = romMask;
- eRamMask = ramMask;
-
- // we might be called recursively, so this might not be the very top
- eDP = ((int)ram)+DP;
- stackOnEntry = DP;
-
- // set up the stack frame
- image = (unsigned char *)ram;//vm->dataBase;
-
- eDP -= 48;
-
- //*(int *)&image[ programStack + 44] = args[9];
- //*(int *)&image[ programStack + 40] = args[8];
- //*(int *)&image[ programStack + 36] = args[7];
- //*(int *)&image[ programStack + 32] = args[6];
- //*(int *)&image[ programStack + 28] = args[5];
- //*(int *)&image[ programStack + 24] = args[4];
- //*(int *)&image[ programStack + 20] = args[3];
- //*(int *)&image[ programStack + 16] = args[2];
- //*(int *)&image[ programStack + 12] = args[1];
- //*(int *)&image[ programStack + 8 ] = args[0];
- //*(int *)&image[ programStack + 4 ] = 0; // return stack
- //*(int *)&image[ programStack ] = -1; // will terminate the loop on return
-
- // off we go into generated code...
- entryPoint = compiledRom;//0;//vm->codeBase;
- eRam = ram+dataStack;
-
- #if defined(_MSC_VER)
- __asm {
- pushad
- mov esi, DP;
- mov edi, opStack
- call entryPoint
- mov DP, esi
- mov opStack, edi
- popad
- }
- #else
- {
- static int memDP;
- static int memRP;
- static void *memEntryPoint;
-
- memDP = DP+((int)ram);
- memRP = RP;
- memEntryPoint = entryPoint;
-
- __asm__(" pushal \r\n" \
- " movl %0,%%esi \r\n" \
- " movl %1,%%edi \r\n" \
- " call *%2 \r\n" \
- " movl %%esi,%0 \r\n" \
- " movl %%edi,%1 \r\n" \
- " popal \r\n" \
- : "=m" (memRP), "=m" (memDP) \
- : "m" (memEntryPoint), "0" (memRP), "1" (memDP) \
- : "si", "di" \
- );
-
- DP = memDP-((int)ram);
- RP = memRP;
- }
- #endif
-
- if ( eRam != ram+dataStack ) {
- throw RuntimeException("opStack corrupted in compiled code");
- }
- if ( DP != stackOnEntry+4 ) {
- printf("DP: %d, stackOnEntry: %d\n", DP, stackOnEntry);
- throw RuntimeException("programStack corrupted in compiled code");
- }
-
- DP = stackOnEntry;
-
- // in case we were recursively called by another vm
- eInstructionPointers = oldInstructionPointers;
- eRam = oldDataStack;
-
- return 0;//*(int *)eOpStack;
- }
-
- bool VirtualMachine::Compile()
- {
- Instruction op;
- int maxLength;
- int v;
- int i;
- bool opt;
-
- // allocate a very large temp buffer, we will shrink it later
- maxLength = romSize * 8;
- buf = new unsigned char[maxLength];
- jused = new unsigned char[romSize + 2];
- instructionPointers = new int[romSize];
- std::fill(jused, jused+romSize+2, 0);
-
- for(pass=0; pass<2; pass++) {
- oc0 = -23423;
- oc1 = -234354;
- pop0 = -43435;
- pop1 = -545455;
-
- // translate all instructions
- pc = 0;
- instruction = 0;
- compiledOfs = 0;
-
- LastCommand = LAST_COMMAND_NONE;
-
- while (instruction < romSize)
- {
- if (compiledOfs > maxLength - 16)
- {
- throw JITException("Compile: maxLength exceeded");
- }
-
- instructionPointers[instruction] = compiledOfs;
- instruction++;
-
- if (pc > romSize)
- {
- throw JITException("Compile: program counter run off the edge");
- }
-
- op = rom[pc];
- pc++;
- switch ( op.Operation )
- {
- case 0:
- break;
- case OP(BREAK):
- emitInstruction( "CC" ); // int 3
- break;
- case OP(ENTER):
- //emitInstruction( "CC" ); // int 3
- emitInstruction( "81 EE" ); // sub esi, 0x12345678
- emit4( constant4() );
- break;
- case OP(CONST):
- if (rom[pc].Operation == OP(LOAD4))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "8B 03" ); // mov eax, dword ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(LOAD2))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "0F B7 03" ); // movzx eax, word ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(LOAD1))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "0F B6 03" ); // movzx eax, byte ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE4))
- {
- opt = emitMovEBXEDI((ramMask & ~3));
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~3 );
- // }
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE2))
- {
- opt = emitMovEBXEDI((ramMask & ~1));
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~1 );
- // }
- emitInstruction( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE1))
- {
- opt = emitMovEBXEDI(ramMask);
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask );
- // }
- emitInstruction( "88 83" ); // mov byte ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(ADD))
- {
- emitInstruction( "81 07" ); // add dword ptr [edi], 0x1234567
- emit4( constant4() );
- pc++; // OP(ADD)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(SUB))
- {
- emitInstruction( "81 2F" ); // sub dword ptr [edi], 0x1234567
- emit4( constant4() );
- pc++; // OP(ADD)
- instruction += 1;
- break;
- }
- emitAddEDI4();
- emitInstruction( "C7 07" ); // mov dword ptr [edi], 0x12345678
- lastConst = constant4();
- emit4( lastConst );
- if (rom[pc].Operation == OP(JUMP))
- {
- jused[lastConst] = 1;
- }
- break;
- case OP(LOCAL):
- emitAddEDI4();
- emitInstruction( "8D 86" ); // lea eax, [0x12345678 + esi]
- oc0 = oc1;
- oc1 = constant4();
- emit4( oc1 );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(ARG):
- emitMovEAXEDI(); // mov eax,dword ptr [edi]
- emitInstruction( "89 86" ); // mov dword ptr [esi+ram],eax
- // FIXME: range check
- emit4( constant1() + (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(CALL):
- emitInstruction("C7 86"); // mov dword ptr [esi+ram],0x12345678
- emit4((int)ram);
- emit4(pc);
- emitInstruction("FF 15"); // call callFromCompiled
- emit4((int)&callFromCompiledPtr);
- break;
- case OP(PUSH):
- emitAddEDI4();
- break;
- case OP(POP):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(LEAVE):
- v = constant4();
- emitInstruction( "81 C6" ); // add esi, 0x12345678
- emit4( v );
- emitInstruction( "C3" ); // ret
- break;
- case OP(LOAD4):
- if (rom[pc].Operation == OP(CONST) && rom[pc+1].Operation == OP(ADD) && rom[pc+2].Operation == OP(STORE4))
- {
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- compiledOfs -= 11;
- instructionPointers[ instruction-1 ] = compiledOfs;
- }
- pc++; // OP(CONST)
- v = constant4();
- emitMovEBXEDI(ramMask);
- if (v == 1 && oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "FF 83"); // inc dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- }
- else
- {
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitInstruction( "05" ); // add eax, const
- emit4( v );
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- else
- {
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- }
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(ADD)
- pc++; // OP(STORE)
- instruction += 3;
- break;
- }
-
- if (rom[pc].Operation == OP(CONST) && rom[pc+1].Operation == OP(SUB) && rom[pc+2].Operation == OP(STORE4))
- {
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL)) {
- compiledOfs -= 11;
- instructionPointers[ instruction-1 ] = compiledOfs;
- }
- emitMovEBXEDI(ramMask);
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- pc++; // OP(CONST)
- v = constant4();
- if (v == 1 && oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "FF 8B"); // dec dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- }
- else
- {
- emitInstruction( "2D" ); // sub eax, const
- emit4( v );
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- else
- {
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- }
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(SUB)
- pc++; // OP(STORE)
- instruction += 3;
- break;
- }
-
- if (buf[compiledOfs-2] == 0x89 && buf[compiledOfs-1] == 0x07)
- {
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "8B 80"); // mov eax, dword ptr [eax + 0x1234567]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- }
- emitMovEBXEDI(ramMask);
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(LOAD2):
- emitMovEBXEDI(ramMask);
- emitInstruction( "0F B7 83" ); // movzx eax, word ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(LOAD1):
- emitMovEBXEDI(ramMask);
- emitInstruction( "0F B6 83" ); // movzx eax, byte ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(STORE4):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // if (pop1 != OP(CALL)) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~3 );
- // }
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
- case OP(STORE2):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~1 );
- emitInstruction( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
- case OP(STORE1):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask );
- emitInstruction( "88 83" ); // mov byte ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
-
- case OP(EQ):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NE):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7D 06" ); // jnl +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7F 06" ); // jnle +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7E 06" ); // jng +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7C 06" ); // jnge +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "73 06" ); // jnb +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "77 06" ); // jnbe +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "76 06" ); // jna +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "72 06" ); // jnae +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(EQF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 40" ); // test ah,0x40
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 40" ); // test ah,0x40
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 01" ); // test ah,0x01
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 41" ); // test ah,0x41
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 41" ); // test ah,0x41
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 01" ); // test ah,0x01
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NEGI):
- emitInstruction( "F7 1F" ); // neg dword ptr [edi]
- break;
- case OP(ADD):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "01 47 FC" ); // add dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(SUB):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "29 47 FC" ); // sub dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(DIVI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "99" ); // cdq
- emitInstruction( "F7 3F" ); // idiv dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(DIVU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "33 D2" ); // xor edx, edx
- emitInstruction( "F7 37" ); // div dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MODI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "99" ); // cdq
- emitInstruction( "F7 3F" ); // idiv dword ptr [edi]
- emitInstruction( "89 57 FC" ); // mov dword ptr [edi-4],edx
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MODU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "33 D2" ); // xor edx, edx
- emitInstruction( "F7 37" ); // div dword ptr [edi]
- emitInstruction( "89 57 FC" ); // mov dword ptr [edi-4],edx
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MULI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "F7 2F" ); // imul dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MULU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "F7 27" ); // mul dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BAND):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "21 47 FC" ); // and dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BOR):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "09 47 FC" ); // or dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BXOR):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "31 47 FC" ); // xor dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BCOM):
- emitInstruction( "F7 17" ); // not dword ptr [edi]
- break;
- case OP(LSH):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 67 FC" ); // shl dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(RSHI):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 7F FC" ); // sar dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(RSHU):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 6F FC" ); // shr dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(NEGF):
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D9 E0" ); // fchs
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(ADDF):
- emitInstruction( "D9 47 FC" ); // fld dword ptr [edi-4]
- emitInstruction( "D8 07" ); // fadd dword ptr [edi]
- emitInstruction( "D9 5F FC" ); // fstp dword ptr [edi-4]
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(SUBF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 67 04" ); // fsub dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(DIVF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 77 04" ); // fdiv dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(MULF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 4f 04" ); // fmul dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(CVIF):
- emitInstruction( "DB 07" ); // fild dword ptr [edi]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(CVFI):
- #ifndef FTOL_PTR // WHENHELLISFROZENOVER // bk001213 - was used in 1.17
- // not IEEE complient, but simple and fast
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "DB 1F" ); // fistp dword ptr [edi]
- #else // FTOL_PTR
- // call the library conversion function
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "FF 15" ); // call ftolPtr
- emit4( (int)&ftolPtr );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- #endif
- break;
- case OP(SEX8):
- emitInstruction( "0F BE 07" ); // movsx eax, byte ptr [edi]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(SEX16):
- emitInstruction( "0F BF 07" ); // movsx eax, word ptr [edi]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
-
- case OP(BLOCK_COPY):
- // FIXME: range check
- emitInstruction( "56" ); // push esi
- emitInstruction( "57" ); // push edi
- emitInstruction( "8B 37" ); // mov esi,[edi]
- emitInstruction( "8B 7F FC" ); // mov edi,[edi-4]
- emitInstruction( "B9" ); // mov ecx,0x12345678
- emit4( constant4() >> 2 );
- emitInstruction( "B8" ); // mov eax, ramMask
- emit4( ramMask );
- emitInstruction( "BB" ); // mov ebx, ram
- emit4( (int)ram );
- emitInstruction( "23 F0" ); // and esi, eax
- emitInstruction( "03 F3" ); // add esi, ebx
- emitInstruction( "23 F8" ); // and edi, eax
- emitInstruction( "03 FB" ); // add edi, ebx
- emitInstruction( "F3 A5" ); // rep movsd
- emitInstruction( "5F" ); // pop edi
- emitInstruction( "5E" ); // pop esi
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
-
- case OP(JUMP):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 47 04" ); // mov eax,dword ptr [edi+4]
- // FIXME: range check
- emitInstruction( "FF 24 85" ); // jmp dword ptr [instructionPointers + eax * 4]
- emit4( (int)instructionPointers );
- break;
- default:
- throw JITException("Compile: bad opcode");
- }
- pop0 = pop1;
- pop1 = op.Operation;
- }
- }
-
- // copy to an exact size buffer on the hunk
- //codeLength = compiledOfs;
- //codeBase = Hunk_Alloc( compiledOfs, h_low );
-
- //Com_Memcpy( codeBase, buf, compiledOfs );
-
- compiledRom = new char[compiledOfs];
- std::copy(buf, buf+compiledOfs, compiledRom);
- compiledRomSize = compiledOfs;
- compiledRomMask = compiledOfs;
-
- delete[] buf;
- delete[] jused;
-
- //printf( "VM file %s compiled to %i bytes of code\n", name, compiledOfs);
-
- // offset all the instruction pointers for the new location
- for ( i = 0 ; i < /*header->instructionCount*/ romSize ; i++ ) {
- instructionPointers[i] += (int)rom;
- }
-
-#ifdef WIN32
- VirtualProtect(compiledRom, compiledRomSize, PAGE_EXECUTE, NULL);
-#endif
- #if 0 // ndef _WIN32
- // Must make the newly generated code executable
- {
- int r;
- unsigned long addr;
- int psize = getpagesize();
-
- addr = ((int)codeBase & ~(psize-1)) - psize;
-
- r = mprotect((char*)addr, codeLength + (int)codeBase - addr + psize,
- PROT_READ | PROT_WRITE | PROT_EXEC );
-
- if (r < 0)
- Com_Error( ERR_FATAL, "mprotect failed to change PROT_EXEC" );
- }
- #endif
- return true;
-
- }
-
- int VirtualMachine::constant4()
- {
- int v;
-
- v = rom[pc-1].Parameter.int4;// | (rom[pc-1].Parameter<<8) | (rom[pc-1].Parameter<<16) | (rom[pc-1].Parameter<<24);
- return v;
- }
-
- int VirtualMachine::constant1()
- {
- int v;
-
- v = rom[pc-1].Parameter.uint1;
- return v;
- }
-
- void VirtualMachine::emit1(int v)
- {
- buf[compiledOfs] = v;
- compiledOfs++;
-
- LastCommand = LAST_COMMAND_NONE;
- }
-
- void VirtualMachine::emit4(int v)
- {
- emit1(v & 255);
- emit1((v >> 8) & 255);
- emit1((v >> 16) & 255);
- emit1((v >> 24) & 255);
- }
-
- void VirtualMachine::emitInstruction(const char *string)
- {
- int c1, c2;
- int v;
-
- while (true)
- {
- c1 = string[0];
- c2 = string[1];
-
- v = (hex( c1 ) << 4) | hex(c2);
- emit1( v );
-
- if (!string[2])
- {
- break;
- }
- string += 3;
- }
- }
-
- void VirtualMachine::emitCommand(int command_)
- {
- ELastCommand command = (ELastCommand)command_;
- switch(command)
- {
- case LAST_COMMAND_MOV_EDI_EAX:
- emitInstruction( "89 07" ); // mov dword ptr [edi], eax
- break;
- case LAST_COMMAND_SUB_DI_4:
- emitInstruction( "83 EF 04" ); // sub edi, 4
- break;
- case LAST_COMMAND_SUB_DI_8:
- emitInstruction( "83 EF 08" ); // sub edi, 8
- break;
- default:
- break;
- }
- LastCommand = command;
- }
-
- void VirtualMachine::emitAddEDI4()
- {
- if (LastCommand == LAST_COMMAND_SUB_DI_4 && jused[instruction-1] == 0)
- { // sub di,4
- compiledOfs -= 3;
- instructionPointers[ instruction-1 ] = compiledOfs;
- return;
- }
- if (LastCommand == LAST_COMMAND_SUB_DI_8 && jused[instruction-1] == 0)
- { // sub di,8
- compiledOfs -= 3;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "83 EF 04" ); // sub edi,4
- return;
- }
- emitInstruction( "83 C7 04" ); // add edi,4
- }
-
- void VirtualMachine::emitMovEAXEDI()
- {
- if (LastCommand == LAST_COMMAND_MOV_EDI_EAX)
- { // mov [edi], eax
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- return;
- }
- if (pop1 == OP(DIVI) || pop1 == OP(DIVU) || pop1 == OP(MULI) || pop1 == OP(MULU) || pop1 == OP(STORE4) || pop1 == OP(STORE2) || pop1 == OP(STORE1) )
- {
- return;
- }
- if (pop1 == OP(CONST) && buf[compiledOfs-6] == 0xC7 && buf[compiledOfs-5] == 0x07)
- { // mov edi, 0x123456
- compiledOfs -= 6;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( lastConst );
- return;
- }
- emitInstruction( "8B 07" ); // mov eax, dword ptr [edi]
- }
-
- bool VirtualMachine::emitMovEBXEDI(int andit)
- {
- if (LastCommand == LAST_COMMAND_MOV_EDI_EAX)
- { // mov [edi], eax
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "8B D8"); // mov bx, eax
- return false;
- }
- if (pop1 == OP(DIVI) || pop1 == OP(DIVU) || pop1 == OP(MULI) || pop1 == OP(MULU) || pop1 == OP(STORE4) || pop1 == OP(STORE2) || pop1 == OP(STORE1) )
- {
- emitInstruction( "8B D8"); // mov bx, eax
- return false;
- }
- if (pop1 == OP(CONST) && buf[compiledOfs-6] == 0xC7 && buf[compiledOfs-5] == 0x07 )
- { // mov edi, 0x123456
- compiledOfs -= 6;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- if (andit) {
- emit4( lastConst & andit );
- } else {
- emit4( lastConst );
- }
- return true;
- }
-
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- return false;
- }
-
- int VirtualMachine::hex(int c)
- {
- if (c >= 'a' && c <= 'f')
- return 10 + c - 'a';
- if (c >= 'A' && c <= 'F')
- return 10 + c - 'A';
- if (c >= '0' && c <= '9')
- return c - '0';
-
- throw JITException("hex: bad character");
-
- return 0;
- }
-
- #undef OP
-}
-
-#endif
diff --git a/src/virtualmachine/Operations.cpp b/src/virtualmachine/Operations.cpp
deleted file mode 100644
index 0c998a8..0000000
--- a/src/virtualmachine/Operations.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-#include "VirtualMachine.h"
-
-namespace vm
-{
- #define OPDEF(n) &VirtualMachine::Op##n,
- OperationFunction VirtualMachine::operations[] =
- {
- #include "Operations.inl"
- };
- #undef OPDEF
-
- #define OPDEF(n) int VirtualMachine::Op##n(word parameter)
-
- #define R0 (r[0])
- #define R1 (r[1])
- #define R2 (r[2])
-
-
- OPDEF(UNDEF)
- {
- /* Die horribly. */
- throw RuntimeException();
- return -1;
- }
-
- OPDEF(IGNORE)
- {
- /* NOP */
- throw RuntimeException();
- return 0;
- }
-
- OPDEF(BREAK)
- {
- /* Usage never spotted. */
- /* Die horribly? */
- throw RuntimeException();
- return -1;
- }
-
- /*
- Stack on entering...
-
- no locals: ENTER 8
- 1 words locals: ENTER 16
- 2 words locals: ENTER 20
- 3 words locals: ENTER 24
- etc.
-
- address of argument:
- ADDRFP4 v => OP_LOCAL (16 + currentLocals + currentArgs + v)
- address of local:
- ADDRLP4 v => OP_LOCAL (8 + currentArgs + v)
-
- RP [ ] ??? (oldPC?)
- [ ] ???
- [ ] \
- ... > locals (args marshalling)
- [ ] /
- [ ] \
- ... > locals
- [ ] / (ADDRLP4 v => OP_LOCAL (8 + currentArgs + v))
- (oldRP?) [ ] ???
- [ ] ???
- [ ] (my args?)
- ...
- [ ]
- */
-
- OPDEF(ENTER) /* ??? */
- {
- while (parameter.int4 > (2 * sizeof(word)))
- {
- RPush<int4_t>(0); /* init zero */
- parameter.int4 -= sizeof(word);
- }
- RPush(Pop()); //Program Counter
- RPush<int4_t>(0); //Unknown
- return 0;
- }
-
- OPDEF(LEAVE) /* ??? */
- {
- RPop(); //Unknown
- parameter.int4 -= sizeof(word);
- PC = RPop<int4_t>(); //Program counter
- parameter.int4 -= sizeof(word);
- while (parameter.int4 > 0)
- {
- RPop();
- parameter.int4 -= sizeof(word);
- }
- return 0;
- }
-
- OPDEF(CALL) /* Call subroutine. */
- {
- R0 = Pop();
- Push<int4_t>(PC);
- PC = R0.int4;
- return 0;
- }
-
- OPDEF(PUSH) /* [DP] <- 0; DP++ */
- {
- Push(0);
- return 0;
- }
-
- OPDEF(POP) /* DP-- */
- {
- Pop();
- return 0;
- }
-
- OPDEF(CONST) /* [DP] <- parm; DP++ */
- {
- Push(parameter);
- return 0;
- }
-
- OPDEF(LOCAL) /* [DP] <- [RP-n] */
- {
- Push<int4_t>(RP + parameter.int4);
- return 0;
- }
-
- OPDEF(JUMP) /* PC <- [DP] */
- {
- PC = Pop<int4_t>();
- return 0;
- }
-
- #define CMP(type, op) \
- { \
- R0 = Pop(); \
- cm = (Pop<type##_t>() op R0.type); \
- if (cm) \
- PC = parameter.uint4; \
- return 0; \
- }
-
- OPDEF(EQ) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, ==)
-
- OPDEF(NE) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, !=)
-
- OPDEF(LTI) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, <)
-
- OPDEF(LEI) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, <=)
-
- OPDEF(GTI) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, >)
-
- OPDEF(GEI) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, >=)
-
- OPDEF(LTU) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, <)
-
- OPDEF(LEU) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, <=)
-
- OPDEF(GTU) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, >)
-
- OPDEF(GEU) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, >=)
-
- OPDEF(EQF) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, ==)
-
- OPDEF(NEF) /* if [DP] != [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, !=)
-
- OPDEF(LTF) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, <)
-
- OPDEF(LEF) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, <=)
-
- OPDEF(GTF) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, >)
-
- OPDEF(GEF) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, >=)
-
-
- OPDEF(LOAD1) /* [DP] <- [[DP]] */
- {
- Push<uint1_t>(Get<uint1_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(LOAD2) /* [DP] <- [[DP]] */
- {
- Push<uint2_t>(Get<uint2_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(LOAD4) /* [DP] <- [[DP]] */
- {
- Push<uint4_t>(Get<uint4_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(STORE1) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint1_t>(Pop<uint4_t>(), Pop<uint1_t>());
- return 0;
- }
-
- OPDEF(STORE2) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint2_t>(Pop<uint4_t>(), Pop<uint2_t>());
- return 0;
- }
-
- OPDEF(STORE4) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint4_t>(Pop<uint4_t>(), Pop<uint4_t>());
- return 0;
- }
-
- OPDEF(ARG) /* Marshal TOS to to-call argument list */
- {
- Marshal(parameter.uint1, Pop());
- return 0;
- }
-
- OPDEF(BLOCK_COPY) /* XXX */
- {
- R1 = Pop();
- R0 = Pop();
- if(R0.int4 >= 0 && R0.int4 + parameter.int4 < ramSize && R1.int4 >= 0 && R1.int4 + parameter.int4 < ramSize)
- memcpy(ram + R0.int4, ram + R1.int4, parameter.int4);
- else
- throw AccessViolationException();
- return -1;
- }
-
- OPDEF(SEX8) /* Sign-extend 8-bit */
- {
- R0 = Pop();
- if(R0.uint4 & 0x80)
- R0.uint4 |= 0xFFFFFF80;
- Push(R0);
- return 0;
- }
-
- OPDEF(SEX16) /* Sign-extend 16-bit */
- {
- R0 = Pop();
- if(R0.uint4 & 0x8000)
- R0.uint4 |= 0xFFFF8000;
- Push(R0);
- return 0;
- }
-
- #define UNOP(type, op) \
- { \
- Push<type##_t>(op Pop<type##_t>()); \
- return 0; \
- }
-
- #define BINOP(type, op) \
- { \
- R0 = Pop(); \
- Push<type##_t>(Pop<type##_t>() op R0.type); \
- return 0; \
- }
-
- OPDEF(NEGI) /* [DP] <- -[DP] */
- UNOP(int4, -)
-
- OPDEF(ADD) /* [DP-1] <- [DP-1] + [DP]; DP <- DP-1 */
- BINOP(int4, +)
-
- OPDEF(SUB) /* [DP-1] <- [DP-1] - [DP]; DP <- DP-1 */
- BINOP(int4, -)
-
- OPDEF(DIVI) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(int4, /)
-
- OPDEF(DIVU) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(uint4, /)
-
- OPDEF(MODI) /* [DP-1] <- [DP-1] % [DP]; DP <- DP-1 */
- BINOP(int4, %)
-
- OPDEF(MODU) /* [DP-1] <- [DP-1] % [DP]; DP <- DP-1 */
- BINOP(uint4, %)
-
- OPDEF(MULI) /* [DP-1] <- [DP-1] * [DP]; DP <- DP-1 */
- BINOP(int4, *)
-
- OPDEF(MULU) /* [DP-1] <- [DP-1] * [DP]; DP <- OP-1 */
- BINOP(uint4, *)
-
- OPDEF(BAND) /* [DP-1] <- [DP-1] & [DP]; DP <- DP-1 */
- BINOP(uint4, &)
-
- OPDEF(BOR) /* [DP-1] <- [DP-1] | [DP]; DP <- DP-1 */
- BINOP(uint4, |)
-
- OPDEF(BXOR) /* [DP-1] <- [DP-1] ^ [DP]; DP <- DP-1 */
- BINOP(uint4, ^)
-
- OPDEF(BCOM) /* [DP] <- ~[DP] */
- UNOP(uint4, ~)
-
- OPDEF(LSH) /* [DP-1] <- [DP-1] << [DP]; DP <- DP-1 */
- BINOP(uint4, <<)
-
- OPDEF(RSHI) /* [DP-1] <- [DP-1] >> [DP]; DP <- DP-1 */
- {
- R1.int4 = Pop<int4_t>();
- R0.int4 = Pop<int4_t>();
- R2.int4 = R0.int4 >> R1.int4;
- Push(R2);
- return 0;
- }
-
- OPDEF(RSHU) /* [DP-1] <- [DP-1] >> [DP]; DP <- DP-1 */
- BINOP(uint4, >>)
-
- OPDEF(NEGF) /* [DP] <- -[DP] */
- UNOP(float4, -)
-
- OPDEF(ADDF) /* [DP-1] <- [DP-1] + [DP]; DP <- DP-1 */
- BINOP(float4, +)
-
- OPDEF(SUBF) /* [DP-1] <- [DP-1] - [DP]; DP <- DP-1 */
- BINOP(float4, -)
-
- OPDEF(DIVF) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(float4, /)
-
- OPDEF(MULF) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(float4, *)
-
- OPDEF(CVIF) /* [DP] <- [DP] */
- {
- Push<float4_t>(Pop<int4_t>());
- return 0;
- }
-
- OPDEF(CVFI) /* [DP] <- [DP] */
- {
- Push<int4_t>(Pop<float4_t>());
- return 0;
- }
-}
diff --git a/src/virtualmachine/Operations.inl b/src/virtualmachine/Operations.inl
deleted file mode 100644
index a1d4b43..0000000
--- a/src/virtualmachine/Operations.inl
+++ /dev/null
@@ -1,60 +0,0 @@
-OPDEF(UNDEF)
-OPDEF(IGNORE) /* no-op */
-OPDEF(BREAK) /* ??? */
-OPDEF(ENTER) /* Begin subroutine. */
-OPDEF(LEAVE) /* End subroutine. */
-OPDEF(CALL) /* Call subroutine. */
-OPDEF(PUSH) /* push to stack. */
-OPDEF(POP) /* discard top-of-stack. */
-OPDEF(CONST) /* load constant to stack. */
-OPDEF(LOCAL) /* get local variable. */
-OPDEF(JUMP) /* unconditional jump. */
-OPDEF(EQ) /* compare integers, jump if equal. */
-OPDEF(NE) /* compare integers, jump if not equal. */
-OPDEF(LTI) /* compare integers, jump if less-than. */
-OPDEF(LEI) /* compare integers, jump if less-than-or-equal. */
-OPDEF(GTI) /* compare integers, jump if greater-than. */
-OPDEF(GEI) /* compare integers, jump if greater-than-or-equal. */
-OPDEF(LTU) /* compare unsigned integers, jump if less-than */
-OPDEF(LEU) /* compare unsigned integers, jump if less-than-or-equal */
-OPDEF(GTU) /* compare unsigned integers, jump if greater-than */
-OPDEF(GEU) /* compare unsigned integers, jump if greater-than-or-equal */
-OPDEF(EQF) /* compare floats, jump if equal */
-OPDEF(NEF) /* compare floats, jump if not-equal */
-OPDEF(LTF) /* compare floats, jump if less-than */
-OPDEF(LEF) /* compare floats, jump if less-than-or-equal */
-OPDEF(GTF) /* compare floats, jump if greater-than */
-OPDEF(GEF) /* compare floats, jump if greater-than-or-equal */
-OPDEF(LOAD1) /* load 1-byte from memory */
-OPDEF(LOAD2) /* load 2-byte from memory */
-OPDEF(LOAD4) /* load 4-byte from memory */
-OPDEF(STORE1) /* store 1-byte to memory */
-OPDEF(STORE2) /* store 2-byte to memory */
-OPDEF(STORE4) /* store 4-byte to memory */
-OPDEF(ARG) /* marshal argument */
-OPDEF(BLOCK_COPY) /* block copy... */
-OPDEF(SEX8) /* Pedophilia */
-OPDEF(SEX16) /* Sign-Extend 16-bit */
-OPDEF(NEGI) /* Negate integer. */
-OPDEF(ADD) /* Add integers (two's complement). */
-OPDEF(SUB) /* Subtract integers (two's complement). */
-OPDEF(DIVI) /* Divide signed integers. */
-OPDEF(DIVU) /* Divide unsigned integers. */
-OPDEF(MODI) /* Modulus (signed). */
-OPDEF(MODU) /* Modulus (unsigned). */
-OPDEF(MULI) /* Multiply signed integers. */
-OPDEF(MULU) /* Multiply unsigned integers. */
-OPDEF(BAND) /* Bitwise AND */
-OPDEF(BOR) /* Bitwise OR */
-OPDEF(BXOR) /* Bitwise eXclusive-OR */
-OPDEF(BCOM) /* Bitwise COMplement */
-OPDEF(LSH) /* Left-shift */
-OPDEF(RSHI) /* Right-shift (algebraic; preserve sign) */
-OPDEF(RSHU) /* Right-shift (bitwise; ignore sign) */
-OPDEF(NEGF) /* Negate float */
-OPDEF(ADDF) /* Add floats */
-OPDEF(SUBF) /* Subtract floats */
-OPDEF(DIVF) /* Divide floats */
-OPDEF(MULF) /* Multiply floats */
-OPDEF(CVIF) /* Convert to integer from float */
-OPDEF(CVFI) /* Convert to float from integer */ \ No newline at end of file
diff --git a/src/virtualmachine/Syscalls.cpp b/src/virtualmachine/Syscalls.cpp
deleted file mode 100644
index e4ca7ca..0000000
--- a/src/virtualmachine/Syscalls.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include <cstdio>
-#include <cstdlib>
-#include <cmath>
-#include "VirtualMachine.h"
-#include "simulation/Simulation.h"
-#include "graphics/Renderer.h"
-
-namespace vm
-{
- #define ARG(n) (Get(RP + ((2 + n) * sizeof(word))))
-
- #define TRAPDEF(f) int VirtualMachine::trap##f()
-
- TRAPDEF(sin)
- {
- Push<float4_t>(sin(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(cos)
- {
- Push<float4_t>(cos(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(atan2)
- {
- Push<float4_t>(atan2(ARG(0).float4, ARG(1).float4));
- return 0;
- }
-
- TRAPDEF(sqrt)
- {
- Push<float4_t>(sqrt(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(floor)
- {
- Push<float4_t>(floor(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(ceil)
- {
- Push<float4_t>(ceil(ARG(0).float4));
- return 0;
- }
-
-
- TRAPDEF(print)
- {
- char *text;
- text = (char*)(ram) + ARG(0).int4;
- printf("%s", text);
- return 0;
- }
-
-
- TRAPDEF(error)
- {
- char *msg;
- msg = (char*)(ram) + ARG(0).int4;
- printf("%s", msg);
- End();
- return 0;
- }
-
-
- TRAPDEF(partCreate)
- {
- Push<int4_t>(sim->create_part(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4));
- return 0;
- }
-
- TRAPDEF(partChangeType)
- {
- sim->part_change_type(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4);
- return 0;
- }
-
- TRAPDEF(pmapData)
- {
- Push<int4_t>(sim->pmap[ARG(1).int4][ARG(0).int4]);
- return 0;
- }
-
- TRAPDEF(deletePart)
- {
- sim->delete_part(ARG(0).int4, ARG(1).int4);
- return 0;
- }
-
- TRAPDEF(killPart)
- {
- sim->kill_part(ARG(0).int4);
- return 0;
- }
-}
diff --git a/src/virtualmachine/Syscalls.inl b/src/virtualmachine/Syscalls.inl
deleted file mode 100644
index 75455c1..0000000
--- a/src/virtualmachine/Syscalls.inl
+++ /dev/null
@@ -1,14 +0,0 @@
-TRAPDEF(-1, sin)
-TRAPDEF(-2, cos)
-TRAPDEF(-3, atan2)
-TRAPDEF(-4, sqrt)
-TRAPDEF(-5, floor)
-TRAPDEF(-6, ceil)
-
-TRAPDEF(-7, error)
-TRAPDEF(-8, print)
-TRAPDEF(-9, partCreate)
-TRAPDEF(-10, partChangeType)
-TRAPDEF(-11, pmapData)
-TRAPDEF(-12, deletePart)
-TRAPDEF(-13, killPart)
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;
- }
-}
diff --git a/src/virtualmachine/VirtualMachine.h b/src/virtualmachine/VirtualMachine.h
deleted file mode 100644
index b295d02..0000000
--- a/src/virtualmachine/VirtualMachine.h
+++ /dev/null
@@ -1,282 +0,0 @@
-#pragma once
-
-#include "Exceptions.h"
-
-class Simulation;
-class Renderer;
-
-namespace vm
-{
-
- class VirtualMachine;
-
- typedef char ram_t;
-
-
-
- typedef unsigned int uint4_t;
- typedef signed int int4_t;
-
- typedef unsigned short uint2_t;
- typedef signed short int2_t;
-
- typedef unsigned char uint1_t;
- typedef signed char int1_t;
-
- typedef float float4_t;
-
- union word
- {
- uint4_t uint4;
- int4_t int4;
- uint2_t uint2;
- int2_t int2;
- uint1_t uint1;
- int1_t int1;
- float4_t float4;
- };
-
- typedef int (VirtualMachine::*OperationFunction)(word parameter);
-
- struct Instruction
- {
- int Operation;
- word Parameter;
- //opfunc opfunc;
- };
-
- enum
- {
- QVM_MAGIC = 0x12721444,
- };
-
- struct qvm_header_t
- {
- int magic;
- /* not-entirely-RISC ISA, so instruction count != codelen */
- int inscount; /* instruction count. */
- int codeoff; /* file offset of code segment. */
- int codelen; /* length of code segment, in octets. */
- int dataoff; /* file offset of data segment. */
- int datalen; /* length of data segment, in octets. */
- int litlen; /* length of lit segment (which is embedded in data segment). */
- int bsslen; /* length of bss segment. */
- };
-
- class VirtualMachine
- {
-
- int * instructionPointers;
-
- bool bigEndian; /* host is big-endian (requires byte-swapping). */
-
- /* Memory spaces. */
- char * hunk; /* hunk space (malloc'd). */
- int hunkSize; /* total hunk size. */
- int hunkFree; /* free pointer. */
-
- /* Read-Only Memory (code). */
- Instruction * rom;
- int romSize;
- int romMask;
-
- char * compiledRom;
- int compiledRomSize;
- int compiledRomMask;
-
- /* Random-Access Memory (data). */
- ram_t *ram;
- int ramSize;
- int ramMask;
-
- int dataStack;
- int returnStack;
-
- word r[4]; /* registers. */
- int DP; /* Datastack pointer. */
- int RP; /* Return stack pointer. */
- int PC; /* Program Counter. */
- // int AP; /* Argument pointer. (hrm...) */
-
- /* various flags. */
- int cm:1;
-
- /* Execution time */
- int cycles;
-
- #define TRAPDEF(n, f) int trap##f();
- #include "Syscalls.inl"
- #undef TRAPDEF
-
- static OperationFunction operations[];
-
-
- #define OPDEF(n) OP##n,
- enum {
- #include "Operations.inl"
- };
- #undef OPDEF
-
- int readProgram(std::istream & input);
- int readByte(std::istream & input);
- int readInt(std::istream & input);
- int opcodeParameterSize(int opcode);
- int syscall(int programCounter);
-
- //Used by the JIT
- #ifdef VMJIT
- int constant4();
- int constant1();
- void emit1(int v);
- void emit4(int v);
- void emitInstruction(const char *string);
- void emitCommand(int command);
- void emitAddEDI4();
- void emitMovEAXEDI();
- bool emitMovEBXEDI(int andit);
- static int hex(int c);
- #endif
-public:
- #ifdef VMJIT
- static void callFromCompiled();
- static void callSyscall();
- bool Compile();
- int CallCompiled(int address);
- #endif
- Simulation * sim;
- Renderer * ren;
-
- #define OPDEF(n) int Op##n(word parameter);
- #include "Operations.inl"
- #undef OPDEF
-
- VirtualMachine(int hunkMbytes);
- virtual ~VirtualMachine();
-
- int LoadProgram(char * filename);
- int LoadProgram(std::vector<char> fileData);
- int Run();
- int CallInterpreted(int address);
- void End();
- void Marshal(int address, word element)
- {
- ram_t * ptr = ram+RP+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(RP+address);
- *((word*)ptr) = element;
- }
-
- template <typename T> T Get(int address)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- return *((T*)ptr);
- }
-
- template <typename T> void Set(int address, T value)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- *((T*)ptr) = value;
- }
-
- template <typename T> T Pop ()
- {
- ram_t * ptr = ram+DP;
- if(DP + sizeof(word) < hunkSize)
- DP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((T*)ptr);
- };
-
- template <typename T> T RPop ()
- {
- ram_t * ptr = ram+RP;
- if(RP + sizeof(word) < hunkSize)
- RP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((T*)ptr);
- };
-
- template <typename T> void Push(T value)
- {
- if(DP - sizeof(word) >= 0)
- DP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+DP;
- *((T*)ptr) = value;
- };
-
- template <typename T> void RPush(T value)
- {
- if(RP - sizeof(word) >= 0)
- RP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+RP;
- *((T*)ptr) = value;
- };
-
- word Get(int address)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- return *((word*)ptr);
- }
-
- void Set(int address, word value)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- *((word*)ptr) = value;
- }
-
- word Pop()
- {
- ram_t * ptr = ram+DP;
- if(DP + sizeof(word) < hunkSize)
- DP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((word*)ptr);
- };
-
- void Push(word value)
- {
- if(DP - sizeof(word) >= 0)
- DP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+DP;
- *((word*)ptr) = value;
- };
-
- word RPop()
- {
- ram_t * ptr = ram+RP;
- if(RP + sizeof(word) < hunkSize)
- RP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((word*)ptr);
- };
-
- void RPush(word value)
- {
- if(RP - sizeof(word) >= 0)
- RP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+RP;
- *((word*)ptr) = value;
- };
- };
-
-}