Clean up VM and Lua loading functions
This commit is contained in:
parent
487647645e
commit
316e940e53
@ -950,6 +950,20 @@ void LuaScriptInterface::initElementsAPI()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pim::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM];
|
pim::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM];
|
||||||
|
NativeUpdateFunc LuaScriptInterface::updateNativeCode[PT_NUM];
|
||||||
|
int LuaScriptInterface::updateNative(UPDATE_FUNC_ARGS)
|
||||||
|
{
|
||||||
|
/*void (*nativeFunction)(int, int, int) = updateNativeCode[parts[i].type];//(void(*)(int, int, int))nativeRom;
|
||||||
|
//int arg3 = CSPop().Integer;
|
||||||
|
//int arg2 = CSPop().Integer;
|
||||||
|
//int arg1 = CSPop().Integer;
|
||||||
|
//std::cout << arg1 << std::endl;
|
||||||
|
//std::cout << arg2 << std::endl;
|
||||||
|
//std::cout << arg3 << std::endl;
|
||||||
|
nativeFunction(i, x, y);*/
|
||||||
|
updateNativeCode[parts[i].type](i, x, y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
|
int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
|
||||||
{
|
{
|
||||||
@ -959,7 +973,7 @@ int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
|
|||||||
machine->CSPush(x);
|
machine->CSPush(x);
|
||||||
machine->CSPush(y);
|
machine->CSPush(y);
|
||||||
//machine->Call(0);
|
//machine->Call(0);
|
||||||
machine->CallCompiled(0);
|
machine->Run(0);
|
||||||
|
|
||||||
|
|
||||||
/*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
|
/*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
|
||||||
@ -1318,8 +1332,16 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
|||||||
else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA)
|
else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
updateVirtualMachines[id] = (pim::VirtualMachine*)lua_touserdata(l, 3);
|
updateVirtualMachines[id] = (pim::VirtualMachine*)lua_touserdata(l, 3);
|
||||||
|
if(updateVirtualMachines[id]->IsCompiled())
|
||||||
|
{
|
||||||
|
updateNativeCode[id] = (NativeUpdateFunc)updateVirtualMachines[id]->GetNativeEntryPoint(0);
|
||||||
|
luacon_sim->elements[id].Update = &updateNative;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
luacon_sim->elements[id].Update = &updateVM;
|
luacon_sim->elements[id].Update = &updateVM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||||
{
|
{
|
||||||
lua_el_func[id] = 0;
|
lua_el_func[id] = 0;
|
||||||
@ -1467,7 +1489,10 @@ int LuaScriptInterface::virtualMachine_loadProgram(lua_State * l)
|
|||||||
|
|
||||||
pim::VirtualMachine * machine = new pim::VirtualMachine(luacon_sim);
|
pim::VirtualMachine * machine = new pim::VirtualMachine(luacon_sim);
|
||||||
machine->LoadProgram(programData);
|
machine->LoadProgram(programData);
|
||||||
|
|
||||||
|
#if defined(X86) && !defined(_64BIT)
|
||||||
machine->Compile();
|
machine->Compile();
|
||||||
|
#endif
|
||||||
|
|
||||||
lua_pushlightuserdata(l, machine);
|
lua_pushlightuserdata(l, machine);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -45,6 +45,8 @@ class Tool;
|
|||||||
#define LUACON_EL_MODIFIED_MENUS 0x4
|
#define LUACON_EL_MODIFIED_MENUS 0x4
|
||||||
|
|
||||||
class TPTScriptInterface;
|
class TPTScriptInterface;
|
||||||
|
class LuaScriptInterface;
|
||||||
|
typedef void (*NativeUpdateFunc)(int, int, int);
|
||||||
class LuaScriptInterface: public CommandInterface
|
class LuaScriptInterface: public CommandInterface
|
||||||
{
|
{
|
||||||
int luacon_mousex, luacon_mousey, luacon_mousebutton, luacon_brushx, luacon_brushy;
|
int luacon_mousex, luacon_mousey, luacon_mousebutton, luacon_brushx, luacon_brushy;
|
||||||
@ -75,6 +77,8 @@ class LuaScriptInterface: public CommandInterface
|
|||||||
|
|
||||||
//Elements
|
//Elements
|
||||||
static pim::VirtualMachine * updateVirtualMachines[PT_NUM];
|
static pim::VirtualMachine * updateVirtualMachines[PT_NUM];
|
||||||
|
static NativeUpdateFunc updateNativeCode[PT_NUM];
|
||||||
|
static int updateNative(UPDATE_FUNC_ARGS);
|
||||||
static int updateVM(UPDATE_FUNC_ARGS);
|
static int updateVM(UPDATE_FUNC_ARGS);
|
||||||
//
|
//
|
||||||
void initElementsAPI();
|
void initElementsAPI();
|
||||||
|
@ -23,7 +23,8 @@ namespace pim
|
|||||||
VirtualMachine::VirtualMachine(Simulation * simulation) :
|
VirtualMachine::VirtualMachine(Simulation * simulation) :
|
||||||
rom(NULL),
|
rom(NULL),
|
||||||
ram(NULL),
|
ram(NULL),
|
||||||
sim(simulation)
|
sim(simulation),
|
||||||
|
nativeRom(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -193,7 +194,7 @@ namespace pim
|
|||||||
int argSize = 0;
|
int argSize = 0;
|
||||||
Instruction instruction;
|
Instruction instruction;
|
||||||
instruction.Opcode = programData[programPosition++];
|
instruction.Opcode = programData[programPosition++];
|
||||||
if(argSize = OpcodeArgSize(instruction.Opcode))
|
if(argSize = opcodeArgSize(instruction.Opcode))
|
||||||
{
|
{
|
||||||
if(argSize == 4 && programPosition+3 < programData.size())
|
if(argSize == 4 && programPosition+3 < programData.size())
|
||||||
{
|
{
|
||||||
@ -236,7 +237,7 @@ namespace pim
|
|||||||
callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
|
callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
int VirtualMachine::OpcodeArgSize(int opcode)
|
int VirtualMachine::opcodeArgSize(int opcode)
|
||||||
{
|
{
|
||||||
switch(opcode)
|
switch(opcode)
|
||||||
{
|
{
|
||||||
@ -276,7 +277,7 @@ namespace pim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMachine::Run()
|
void VirtualMachine::run()
|
||||||
{
|
{
|
||||||
//std::cout << "CS: " << callStack << " PS: " << programStack << std::endl;
|
//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"};
|
//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"};
|
||||||
@ -423,43 +424,38 @@ namespace pim
|
|||||||
void VirtualMachine::Compile()
|
void VirtualMachine::Compile()
|
||||||
{
|
{
|
||||||
Native * native = new X86Native();
|
Native * native = new X86Native();
|
||||||
std::vector<unsigned char> executableCode = native->Compile(sim, rom, romSize);
|
if(nativeRom)
|
||||||
Client::Ref().WriteFile(executableCode, "code.x");
|
delete[] nativeRom;
|
||||||
|
if(nativeStack)
|
||||||
|
delete[] nativeStack;
|
||||||
|
|
||||||
unsigned char * romAddress = new unsigned char[executableCode.size()+8];
|
nativeStack = new unsigned char [1024*1024];
|
||||||
std::fill(romAddress, romAddress+executableCode.size()+8, 0x90); //Fill with NOP for debugging
|
|
||||||
std::copy(executableCode.begin(), executableCode.end(), romAddress+4);
|
std::vector<unsigned char> executableCode = native->Compile(sim, nativeStack + (1024*512), rom, romSize);
|
||||||
nativeRom = (intptr_t)romAddress;
|
nativeRom = new unsigned char[executableCode.size()];
|
||||||
printf("%p\n", romAddress);
|
|
||||||
fflush(stdout);
|
std::copy(executableCode.begin(), executableCode.end(), nativeRom);
|
||||||
|
|
||||||
delete native;
|
delete native;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMachine::CallCompiled(std::string entryPoint)
|
void * VirtualMachine::GetNativeEntryPoint(std::string entryPoint)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMachine::CallCompiled(int entryPoint)
|
void * VirtualMachine::GetNativeEntryPoint(intptr_t entryPoint)
|
||||||
{
|
{
|
||||||
void (*nativeFunction)(int, int, int) = (void(*)(int, int, int))nativeRom;
|
return nativeRom+entryPoint;
|
||||||
int arg3 = CSPop().Integer;
|
|
||||||
int arg2 = CSPop().Integer;
|
|
||||||
int arg1 = CSPop().Integer;
|
|
||||||
//std::cout << arg1 << std::endl;
|
|
||||||
//std::cout << arg2 << std::endl;
|
|
||||||
//std::cout << arg3 << std::endl;
|
|
||||||
nativeFunction(arg1, arg2, arg3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMachine::Call(std::string entryPoint)
|
void VirtualMachine::Run(std::string entryPoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualMachine::Call(int entryPoint)
|
void VirtualMachine::Run(int entryPoint)
|
||||||
{
|
{
|
||||||
programCounter = entryPoint;
|
programCounter = entryPoint;
|
||||||
Run();
|
run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,8 @@ namespace pim
|
|||||||
int romSize;
|
int romSize;
|
||||||
int romMask;
|
int romMask;
|
||||||
|
|
||||||
intptr_t nativeRom;
|
unsigned char * nativeRom;
|
||||||
|
unsigned char * nativeStack;
|
||||||
|
|
||||||
unsigned char * compiledRom;
|
unsigned char * compiledRom;
|
||||||
int compiledRomSize;
|
int compiledRomSize;
|
||||||
@ -80,16 +81,20 @@ namespace pim
|
|||||||
//Instruction * instructions;
|
//Instruction * instructions;
|
||||||
|
|
||||||
int programCounter;
|
int programCounter;
|
||||||
|
void run();
|
||||||
|
int opcodeArgSize(int opcode);
|
||||||
public:
|
public:
|
||||||
VirtualMachine(Simulation * sim);
|
VirtualMachine(Simulation * sim);
|
||||||
int OpcodeArgSize(int opcode);
|
|
||||||
void LoadProgram(std::vector<unsigned char> programData);
|
void LoadProgram(std::vector<unsigned char> programData);
|
||||||
void Run();
|
|
||||||
void Compile();
|
void Compile();
|
||||||
void CallCompiled(std::string entryPoint);
|
void * GetNativeEntryPoint(std::string entryPoint);
|
||||||
void CallCompiled(int entryPoint);
|
void * GetNativeEntryPoint(intptr_t entryPoint);
|
||||||
void Call(std::string entryPoint);
|
void Run(std::string entryPoint);
|
||||||
void Call(int entryPoint);
|
void Run(int entryPoint);
|
||||||
|
inline bool IsCompiled()
|
||||||
|
{
|
||||||
|
return nativeRom != 0;
|
||||||
|
}
|
||||||
inline void PSPush(Word word)
|
inline void PSPush(Word word)
|
||||||
{
|
{
|
||||||
programStack -= WORDSIZE;
|
programStack -= WORDSIZE;
|
||||||
|
@ -4,8 +4,49 @@ namespace pim
|
|||||||
{
|
{
|
||||||
class Native
|
class Native
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
std::vector<unsigned char> nativeRom;
|
||||||
|
void emit(std::string opcode)
|
||||||
|
{
|
||||||
|
unsigned char c1, c2;
|
||||||
|
unsigned char v;
|
||||||
|
const char * string = opcode.c_str();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
c1 = string[0];
|
||||||
|
c2 = string[1];
|
||||||
|
|
||||||
|
v = (hex( c1 ) << 4) | hex(c2);
|
||||||
|
nativeRom.push_back(v);
|
||||||
|
|
||||||
|
if (!string[2])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
string += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char hex(char 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';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual void emitConstantS(short int constant) {} //Single
|
||||||
|
virtual void emitConstantD(long int constant) {} //Double
|
||||||
|
virtual void emitConstantP(intptr_t constant) {} //Pointer
|
||||||
|
virtual void emitConstantQ(long long int constant) {} //Quad
|
||||||
|
virtual void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize) {}
|
||||||
|
virtual void emitPlaceholder(int virtualAddress) {}
|
||||||
public:
|
public:
|
||||||
Native() {}
|
Native() : nativeRom() {}
|
||||||
virtual std::vector<unsigned char> Compile(Simulation * sim, Instruction * rom, int romSize) {}
|
virtual std::vector<unsigned char> Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,19 +4,16 @@
|
|||||||
|
|
||||||
namespace pim
|
namespace pim
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> X86Native::Compile(Simulation * sim, Instruction * rom, int romSize)
|
std::vector<unsigned char> X86Native::Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize)
|
||||||
{
|
{
|
||||||
#if defined(X86) && !defined(_64BIT)
|
#if defined(X86) && !defined(_64BIT)
|
||||||
int programCounter = 0;
|
int programCounter = 0;
|
||||||
nativeRom.clear();
|
nativeRom.clear();
|
||||||
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
|
|
||||||
esi += 512;
|
|
||||||
|
|
||||||
//emit("52"); //push edx
|
for(int i = 0; i < 8; i++) { emit("90"); } //nop, helps find the code in memory with a debugger
|
||||||
//emit("56"); //push esi
|
|
||||||
|
|
||||||
emit("BE"); //mov esi, machineStack
|
emit("BE"); //mov esi, machineStack
|
||||||
emit((intptr_t)esi);
|
emitConstantP((intptr_t)machineStack);
|
||||||
|
|
||||||
while(programCounter < romSize)
|
while(programCounter < romSize)
|
||||||
{
|
{
|
||||||
@ -29,7 +26,7 @@ namespace pim
|
|||||||
//Load value at base stack + offset into eax
|
//Load value at base stack + offset into eax
|
||||||
//emit("8B 85"); //mov eax, [ebp+offset]
|
//emit("8B 85"); //mov eax, [ebp+offset]
|
||||||
emit("8B 84 24"); //mov eax, [esp+offset]
|
emit("8B 84 24"); //mov eax, [esp+offset]
|
||||||
emit((int) (argument.Integer));
|
emitConstantP(argument.Integer);
|
||||||
//Store value in eax onto top of program stack
|
//Store value in eax onto top of program stack
|
||||||
emit("89 06"); //mov [esi], eax
|
emit("89 06"); //mov [esi], eax
|
||||||
break;
|
break;
|
||||||
@ -37,23 +34,22 @@ namespace pim
|
|||||||
//Load value on top of the program stack into eax
|
//Load value on top of the program stack into eax
|
||||||
emit("8B 06"); //mov eax, [esi]
|
emit("8B 06"); //mov eax, [esi]
|
||||||
//Load value in eax into memory
|
//Load value in eax into memory
|
||||||
//emit("89 85"); //mov [ebp+offset], eax
|
|
||||||
emit("89 84 24"); //mov [esp+offset], eax
|
emit("89 84 24"); //mov [esp+offset], eax
|
||||||
emit((int) (argument.Integer));
|
emitConstantD(argument.Integer);
|
||||||
emit("83 C6 04"); //add esi, 4
|
emit("83 C6 04"); //add esi, 4
|
||||||
break;
|
break;
|
||||||
case Opcode::Constant:
|
case Opcode::Constant:
|
||||||
emit("83 EE 04"); //sub esi, 4
|
emit("83 EE 04"); //sub esi, 4
|
||||||
emit("C7 06"); //mov [esi], dword ptr constant
|
emit("C7 06"); //mov [esi], dword ptr constant
|
||||||
emit((int) (argument.Integer));
|
emitConstantD(argument.Integer);
|
||||||
break;
|
break;
|
||||||
case Opcode::Increment:
|
case Opcode::Increment:
|
||||||
if(argument.Integer > 0) {
|
if(argument.Integer > 0) {
|
||||||
emit("81 06"); //add [esi], dword ptr constant
|
emit("81 06"); //add [esi], dword ptr constant
|
||||||
emit((int) (argument.Integer));
|
emitConstantD(argument.Integer);
|
||||||
} else {
|
} else {
|
||||||
emit("81 2E"); //sub [esi], dword ptr constant
|
emit("81 2E"); //sub [esi], dword ptr constant
|
||||||
emit((int) (-argument.Integer));
|
emitConstantD(-argument.Integer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Opcode::Discard:
|
case Opcode::Discard:
|
||||||
@ -112,10 +108,6 @@ namespace pim
|
|||||||
emit("83 C6 08"); //add esi, 8
|
emit("83 C6 08"); //add esi, 8
|
||||||
emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part), 16);
|
emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part), 16);
|
||||||
emit("89 06"); //mov [esi], eax
|
emit("89 06"); //mov [esi], eax
|
||||||
//temp1 = PSPop();
|
|
||||||
//temp2 = PSPop();
|
|
||||||
//temp3 = PSPop();
|
|
||||||
//PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
|
|
||||||
break;
|
break;
|
||||||
case Opcode::Transform:
|
case Opcode::Transform:
|
||||||
//PSPop();
|
//PSPop();
|
||||||
@ -127,21 +119,19 @@ namespace pim
|
|||||||
intptr_t partsArray = (intptr_t)sim->pmap;
|
intptr_t partsArray = (intptr_t)sim->pmap;
|
||||||
emit("8B 06"); //mov eax, [esi]
|
emit("8B 06"); //mov eax, [esi]
|
||||||
emit("8B 4E 04"); //mov ecx, [esi+4]
|
emit("8B 4E 04"); //mov ecx, [esi+4]
|
||||||
|
|
||||||
emit("81 F9"); //cmp ecx, XRES
|
emit("81 F9"); //cmp ecx, XRES
|
||||||
emit((int)XRES);
|
emitConstantD((int)XRES);
|
||||||
emit("7D 22"); //|--< //jge 34
|
emit("7D 22"); //|--< //jge 34
|
||||||
emit("74 20"); //|--< //jz 32
|
emit("74 20"); //|--< //jz 32
|
||||||
emit("3D"); //| //cmp eax, YRES
|
emit("3D"); //| //cmp eax, YRES
|
||||||
emit((int)YRES); //|
|
emitConstantD((int)YRES); //|
|
||||||
emit("7D 19"); //|--< //jge 25
|
emit("7D 19"); //|--< //jge 25
|
||||||
emit("74 17"); //|--< //jz 23
|
emit("74 17"); //|--< //jz 23
|
||||||
//|
|
|
||||||
emit("69 C0"); //| //imul eax, 612
|
emit("69 C0"); //| //imul eax, 612
|
||||||
emit((int)XRES); //|
|
emitConstantD((int)XRES); //|
|
||||||
emit("01 C8"); //| //add eax, ecx
|
emit("01 C8"); //| //add eax, ecx
|
||||||
emit("8B 04 85"); //| //mov eax, [eax*4+pmap]
|
emit("8B 04 85"); //| //mov eax, [eax*4+pmap]
|
||||||
emit((int)partsArray); //|
|
emitConstantP((int)partsArray); //|
|
||||||
emit("C1 F8 08"); //| //sar eax, 8
|
emit("C1 F8 08"); //| //sar eax, 8
|
||||||
emit("89 46 04"); //| //mov [esi+4], eax #Copy eax onto stack
|
emit("89 46 04"); //| //mov [esi+4], eax #Copy eax onto stack
|
||||||
emit("EB 07"); //| |-< //jmp +7
|
emit("EB 07"); //| |-< //jmp +7
|
||||||
@ -153,26 +143,20 @@ namespace pim
|
|||||||
{
|
{
|
||||||
intptr_t partsArray = (intptr_t)sim->parts;
|
intptr_t partsArray = (intptr_t)sim->parts;
|
||||||
emit("8B 06"); //mov eax, [esi] #Load index from stack
|
emit("8B 06"); //mov eax, [esi] #Load index from stack
|
||||||
|
|
||||||
emit("3D"); //cmp eax, NPART
|
emit("3D"); //cmp eax, NPART
|
||||||
emit((int)NPART);
|
emitConstantD((int)NPART);
|
||||||
emit("7D 23"); //|--< //jge 31
|
emit("7D 23"); //|--< //jge 31
|
||||||
emit("74 21"); //|--< //jz 29
|
emit("74 21"); //|--< //jz 29
|
||||||
//|
|
|
||||||
emit("C1 E0 03"); //| //sal eax, 3 #Shift index left (multiply by 8)
|
emit("C1 E0 03"); //| //sal eax, 3 #Shift index left (multiply by 8)
|
||||||
emit("8D 14 C5 00 00 00 00"); //| //lea edx, [eax*8] #Mutiply by 8 again and copy into edx //Size of 56 is represented by (1*(8^2))-(1*8)
|
emit("8D 14 C5 00 00 00 00"); //| //lea edx, [eax*8] #Mutiply by 8 again and copy into edx //Size of 56 is represented by (1*(8^2))-(1*8)
|
||||||
emit("89 D1"); //| //mov ecx, edx
|
emit("89 D1"); //| //mov ecx, edx
|
||||||
emit("29 C1"); //| //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
|
emit("29 C1"); //| //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
|
||||||
//emit("8B 81"); //| //mov eax, [ecx+xOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
|
|
||||||
emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
|
emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
|
||||||
emit(partsArray+offsetof(Particle, x));
|
emitConstantP(partsArray+offsetof(Particle, x));
|
||||||
emit("DB 1E"); //| //fistp [esi]
|
emit("DB 1E"); //| //fistp [esi]
|
||||||
//emit("89 06"); //| //mov [esi], eax #Copy eax onto stack
|
|
||||||
//emit("89 81"); //| //mov eax, [ecx+yOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
|
|
||||||
emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
|
emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
|
||||||
emit(partsArray+offsetof(Particle, y));
|
emitConstantP(partsArray+offsetof(Particle, y));
|
||||||
emit("DB 5E FC"); //| //fistp [esi-4], eax #Copy eax onto stack
|
emit("DB 5E FC"); //| //fistp [esi-4], eax #Copy eax onto stack
|
||||||
//emit("89 46 FC"); //| //mov [esi-4], eax #Copy eax onto stack
|
|
||||||
emit("EB 0D"); //| |-< //jmp +13
|
emit("EB 0D"); //| |-< //jmp +13
|
||||||
emit("C7 06 FF FF FF FF"); //L-+-> //mov [esi], -1
|
emit("C7 06 FF FF FF FF"); //L-+-> //mov [esi], -1
|
||||||
emit("C7 46 FC FF FF FF FF"); // | //mov [esi-4] -1
|
emit("C7 46 FC FF FF FF FF"); // | //mov [esi-4] -1
|
||||||
@ -193,7 +177,7 @@ namespace pim
|
|||||||
emit("89 D1"); //mov ecx, edx
|
emit("89 D1"); //mov ecx, edx
|
||||||
emit("29 C1"); //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
|
emit("29 C1"); //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
|
||||||
emit("8B 81"); //mov eax, [ecx+propertyOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
|
emit("8B 81"); //mov eax, [ecx+propertyOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
|
||||||
emit(partsArray+propertyOffset);
|
emitConstantP(partsArray+propertyOffset);
|
||||||
emit("89 06"); //mov [esi], eax #Copy eax onto stack
|
emit("89 06"); //mov [esi], eax #Copy eax onto stack
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -208,7 +192,7 @@ namespace pim
|
|||||||
emit("29 C1"); //sub ecx, eax
|
emit("29 C1"); //sub ecx, eax
|
||||||
emit("8B 46 04"); //mov eax, [esi+4]
|
emit("8B 46 04"); //mov eax, [esi+4]
|
||||||
emit("89 81"); //mov [ecx+propertyOffset+partsArray], eax
|
emit("89 81"); //mov [ecx+propertyOffset+partsArray], eax
|
||||||
emit(partsArray+propertyOffset);
|
emitConstantP(partsArray+propertyOffset);
|
||||||
emit("83 C6 08"); //add esi, 8
|
emit("83 C6 08"); //add esi, 8
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -273,25 +257,22 @@ namespace pim
|
|||||||
emitPlaceholder(argument.Integer);
|
emitPlaceholder(argument.Integer);
|
||||||
break;
|
break;
|
||||||
case Opcode::Return:
|
case Opcode::Return:
|
||||||
//emit("5E"); //pop esi
|
|
||||||
//emit("5A"); //pop edx
|
|
||||||
emit("C3"); //ret
|
emit("C3"); //ret
|
||||||
break;
|
break;
|
||||||
case Opcode::Leave:
|
case Opcode::Leave:
|
||||||
//emit("81 C7"); //add edi, constant
|
|
||||||
emit("81 C4"); //add esp, constant
|
emit("81 C4"); //add esp, constant
|
||||||
emit(argument.Integer);
|
emitConstantD(argument.Integer);
|
||||||
break;
|
break;
|
||||||
case Opcode::LocalEnter:
|
case Opcode::LocalEnter:
|
||||||
//emit("81 EF"); //sub edi constant
|
|
||||||
emit("81 EC"); //sub esp constant
|
emit("81 EC"); //sub esp constant
|
||||||
emit(argument.Integer);
|
emitConstantD(argument.Integer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//std::cout << programStack << std::endl;
|
//std::cout << programStack << std::endl;
|
||||||
programCounter++;
|
programCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 8; i++) { emit("90"); } //nop, helps find the code in memory with a debugger
|
||||||
|
|
||||||
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
|
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
|
||||||
{
|
{
|
||||||
@ -315,39 +296,27 @@ namespace pim
|
|||||||
|
|
||||||
void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize)
|
void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize)
|
||||||
{
|
{
|
||||||
//emit("B9"); //mov ecx, instancePointer
|
#ifdef _MSC_VER
|
||||||
emit("68"); //push instancePointer
|
//MSVC puts the instance pointer in ecx, not on the stack
|
||||||
emit((int) objectPtr);
|
emit("B9"); //mov ecx, instancePointer
|
||||||
|
emitConstantP(objectPtr);
|
||||||
emit("B8"); //mov eax, functionAddress
|
emit("B8"); //mov eax, functionAddress
|
||||||
emit((int)functionAddress);
|
emitConstantP(functionAddress);
|
||||||
emit("FF D0"); //call eax
|
emit("FF D0"); //call eax
|
||||||
emit("81 C4"); //add esp, stacksize
|
emit("81 C4"); //add esp, stacksize
|
||||||
emit((int)stackSize+sizeof(intptr_t));
|
emitConstantD(stackSize);
|
||||||
|
#else
|
||||||
|
emit("68"); //push instancePointer
|
||||||
|
emitConstantP(objectPtr);
|
||||||
|
emit("B8"); //mov eax, functionAddress
|
||||||
|
emitConstantP(functionAddress);
|
||||||
|
emit("FF D0"); //call eax
|
||||||
|
emit("81 C4"); //add esp, stacksize
|
||||||
|
emitConstantD(stackSize+sizeof(intptr_t));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86Native::emit(std::string opcode)
|
void X86Native::emitConstantD(long int constant)
|
||||||
{
|
|
||||||
unsigned char c1, c2;
|
|
||||||
unsigned char v;
|
|
||||||
const char * string = opcode.c_str();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
c1 = string[0];
|
|
||||||
c2 = string[1];
|
|
||||||
|
|
||||||
v = (hex( c1 ) << 4) | hex(c2);
|
|
||||||
nativeRom.push_back(v);
|
|
||||||
|
|
||||||
if (!string[2])
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
string += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void X86Native::emit(int constant)
|
|
||||||
{
|
{
|
||||||
nativeRom.push_back(constant & 0xFF);
|
nativeRom.push_back(constant & 0xFF);
|
||||||
nativeRom.push_back((constant >> 8) & 0xFF);
|
nativeRom.push_back((constant >> 8) & 0xFF);
|
||||||
@ -355,15 +324,9 @@ namespace pim
|
|||||||
nativeRom.push_back((constant >> 24) & 0xFF);
|
nativeRom.push_back((constant >> 24) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char X86Native::hex(char c)
|
void X86Native::emitConstantP(intptr_t constant)
|
||||||
{
|
{
|
||||||
if (c >= 'a' && c <= 'f')
|
emitConstantD(constant);
|
||||||
return 10 + c - 'a';
|
|
||||||
if (c >= 'A' && c <= 'F')
|
|
||||||
return 10 + c - 'A';
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
return c - '0';
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -7,15 +7,13 @@ namespace pim
|
|||||||
class X86Native : public Native
|
class X86Native : public Native
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
X86Native() : Native(), nativeRom() {}
|
X86Native() : Native() {}
|
||||||
virtual std::vector<unsigned char> Compile(Simulation * sim, Instruction * rom, int romSize);
|
virtual std::vector<unsigned char> Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize);
|
||||||
private:
|
protected:
|
||||||
void emit(std::string opcode);
|
virtual void emitConstantD(long int constant);
|
||||||
void emit(int constant);
|
virtual void emitConstantP(intptr_t constant);
|
||||||
void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize);
|
virtual void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize);
|
||||||
void emitPlaceholder(int virtualAddress);
|
virtual void emitPlaceholder(int virtualAddress);
|
||||||
unsigned char hex(char c);
|
|
||||||
std::vector<unsigned char> nativeRom;
|
|
||||||
std::map<int, int> virtualToNative;
|
std::map<int, int> virtualToNative;
|
||||||
std::map<int, int> placeholders;
|
std::map<int, int> placeholders;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user