Mercurial > LightClone
view LightClone/Source/VirtualMachine.cpp @ 48:4663f93aefc4
Tracing
author | koryspansel |
---|---|
date | Fri, 23 Sep 2011 11:50:59 -0700 |
parents | b60cbf3fa894 |
children | 95677f648a2c |
line wrap: on
line source
/* * VirtualMachine.cpp */ #include "VirtualMachine.h" /* * VirtualMachine */ VirtualMachine::VirtualMachine() : nInstructionPointer(0), nFunctionCount(0) { ClearMemory(); } /* * Step */ uint32 VirtualMachine::Step() { // decode and validate instruction pointer function and offset const uint8 nSourceFunction = DecodeAddressFunction(nInstructionPointer); const uint8 nSourceOffset = DecodeAddressOffset(nInstructionPointer); if(nSourceFunction < nFunctionCount && nSourceOffset <= kFunction[nSourceFunction].nSize) { TRACE("Reading address %d\n", nInstructionPointer); // read the next instruction const uint8 nInstruction = Read(); const uint8 nParameter = Read(); TRACE("Decoded I:%d P:%d\n", nInstruction, nParameter); if(nInstruction == Instruction_None) { return Action_Default; } else if(nInstruction == Instruction_Action) { // action instruction, the parameter is the action TRACE(" -- Action Decoded: %d\n", nParameter); return nParameter; } else if(nInstruction == Instruction_Call) { TRACE(" -- Call Decoded: %d\n", nParameter); // set instruction pointer to destination if(nParameter < nFunctionCount) { const uint8 nDestinationSize = kFunction[nParameter].nSize; // insert continuation jump into destination function nMemory[nParameter * FunctionStride + nDestinationSize + 0] = Instruction_Jump; nMemory[nParameter * FunctionStride + nDestinationSize + 1] = nInstructionPointer; TRACE(" - Inserting continuation\n"); TRACE(" Instruction: %d\n", Instruction_Jump); TRACE(" Destination: %d\n", nInstructionPointer); // update instruction pointer to destination address nInstructionPointer = nParameter * FunctionStride; // signal that we're not yet done return Action_Default; } } else if(nInstruction == Instruction_Jump) { TRACE(" -- Jump Decoded: %d\n", nParameter); // decode and validate destination function and offset const uint8 nDestinationFunction = DecodeAddressFunction(nParameter); const uint8 nDestinationOffset = DecodeAddressOffset(nParameter); TRACE(" - Function: %d\n", nDestinationFunction); TRACE(" - Offset : %d\n", nDestinationOffset); // set instruction pointer to destination if(nDestinationFunction < nFunctionCount && nDestinationOffset <= kFunction[nDestinationFunction].nSize) { // update instruction pointer to destination address nInstructionPointer = nParameter; // signal that we're not yet done return Action_Default; } } } return Action_Complete; } /* * Reset */ void VirtualMachine::Reset() { nInstructionPointer = 0; } /* * SetMemory */ bool VirtualMachine::SetMemory(uint8 nFunction, const uint8* pData, uint8 nSize) { if(nFunction < nFunctionCount) { const uint8 nFunctionAddress = kFunction[nFunction].nAddress; const uint8 nFunctionSize = kFunction[nFunction].nSize; for(uint8 nOffset = 0; nOffset < Min(nFunctionSize, nSize); ++nOffset) { nMemory[nFunctionAddress + nOffset] = pData[nOffset]; } return true; } return false; } /* * ClearMemory */ void VirtualMachine::ClearMemory() { for(uint8 nFunction = 0; nFunction < MaximumFunctionCount; ++nFunction) { for(uint8 nLocation = 0; nLocation < MaximumInstructionCount; ++nLocation) { nMemory[nFunction * FunctionStride + nLocation] = Instruction_None; } nMemory[nFunction * FunctionStride + FunctionStride - ContinuationInstructionSize + 0] = Instruction_Jump; nMemory[nFunction * FunctionStride + FunctionStride - ContinuationInstructionSize + 1] = 0; } } /* * AddFunction */ bool VirtualMachine::AddFunction(uint8 nFunction, uint8 nSize) { if(nFunctionCount + 1 < MaximumFunctionCount) { kFunction[nFunctionCount].nAddress = nFunctionCount * FunctionStride; kFunction[nFunctionCount].nSize = nSize * 2; ++nFunctionCount; return true; } return false; } /* * RemoveAllFunctions */ void VirtualMachine::RemoveAllFunctions() { nFunctionCount = 0; } /* * GetFunctionSize */ uint32 VirtualMachine::GetFunctionSize(uint32 nIndex) const { return nIndex < nFunctionCount ? kFunction[nIndex].nSize : 0; } /* * GetFunctionMemory */ uint8* VirtualMachine::GetFunctionMemory(uint32 nIndex) { return nIndex < nFunctionCount ? &nMemory[kFunction[nIndex].nAddress] : 0; }