Mercurial > LightClone
diff LightClone/Source/VirtualMachine.cpp @ 54:95677f648a2c VirtualMachine Mk2
Refactored VirtualMachine
author | koryspansel |
---|---|
date | Fri, 30 Sep 2011 18:37:54 -0700 |
parents | 4663f93aefc4 |
children | dc1f4a668d50 |
line wrap: on
line diff
--- a/LightClone/Source/VirtualMachine.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/VirtualMachine.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -7,9 +7,9 @@ /* * VirtualMachine */ -VirtualMachine::VirtualMachine() : nInstructionPointer(0), nFunctionCount(0) +VirtualMachine::VirtualMachine() : nInstructionPointer(0), pFrame(NULL) { - ClearMemory(); + Clear(); } /* @@ -17,84 +17,44 @@ */ 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) + const uint8 nInstruction = Advance(); + TRACE("Read instruction %d at address %d\n", nInstruction, nInstructionPointer - 1); + + if(nInstruction == Instruction_Action) { - TRACE("Reading address %d\n", nInstructionPointer); + const uint8 nParameter = Advance(); + TRACE(" -- Action Decoded: %d\n", nParameter); - // read the next instruction - const uint8 nInstruction = Read(); - const uint8 nParameter = Read(); + return nParameter; + } + else - TRACE("Decoded I:%d P:%d\n", nInstruction, nParameter); + if(nInstruction == Instruction_Call) + { + const uint8 nParameter = Advance(); + TRACE(" -- Call Decoded: %d\n", nParameter); + + const uint32 nFunction = nParameter; + const uint32 nContinuation = nInstructionPointer; - if(nInstruction == Instruction_None) + PushFrame(nFunction, nContinuation); + } + else + + if(nInstruction == Instruction_Return) + { + if(pFrame) { - return Action_Default; - } - else - - if(nInstruction == Instruction_Action) - { - // action instruction, the parameter is the action - TRACE(" -- Action Decoded: %d\n", nParameter); - return nParameter; + PopFrame(); } 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; - } + // no frame to pop, we are done + return Action_Complete; } } - return Action_Complete; + return Action_None; } /* @@ -106,82 +66,89 @@ } /* - * SetMemory + * Clear */ -bool VirtualMachine::SetMemory(uint8 nFunction, const uint8* pData, uint8 nSize) +void VirtualMachine::Clear() { - if(nFunction < nFunctionCount) + for(uint32 i = 0; i < Capacity; ++i) { - 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; - + nMemory[i] = 0; } } /* - * AddFunction + * GetMemorySize */ -bool VirtualMachine::AddFunction(uint8 nFunction, uint8 nSize) +uint32 VirtualMachine::GetMemorySize() const { - if(nFunctionCount + 1 < MaximumFunctionCount) - { - kFunction[nFunctionCount].nAddress = nFunctionCount * FunctionStride; - kFunction[nFunctionCount].nSize = nSize * 2; + return Capacity; +} - ++nFunctionCount; - - return true; - } - - return false; +/* + * GetMemoryPointer + */ +uint8* VirtualMachine::GetMemoryPointer() +{ + return &nMemory[0]; } /* - * RemoveAllFunctions + * PushFrame */ -void VirtualMachine::RemoveAllFunctions() +void VirtualMachine::PushFrame(uint32 nFunctionAddress, uint32 nContinuationAddress) { - nFunctionCount = 0; + Frame* pInstance = pFrame; + + while(pInstance) + { + if(pInstance->nAddress == nFunctionAddress && pInstance->nContinuation == nContinuationAddress) + { + break; + } + + pInstance = pInstance->pLast; + } + + if(pInstance) + { + while(pFrame && pFrame != pInstance) + { + Frame* pValue = pFrame; + pFrame = pValue->pLast; + + kFrameAllocator.Free(pValue); + } + + //ASSERT(pFrame != NULL); + } + else + { + pInstance = kFrameAllocator.Allocate(); + pInstance->nAddress = nFunctionAddress; + pInstance->nContinuation = nContinuationAddress; + pInstance->pLast = pFrame; + + pFrame = pInstance; + } + + nInstructionPointer = nFunctionAddress; } /* - * GetFunctionSize + * PopFrame */ -uint32 VirtualMachine::GetFunctionSize(uint32 nIndex) const +void VirtualMachine::PopFrame() { - return nIndex < nFunctionCount ? kFunction[nIndex].nSize : 0; -} + if(pFrame) + { + nInstructionPointer = pFrame->nContinuation; -/* - * GetFunctionMemory - */ -uint8* VirtualMachine::GetFunctionMemory(uint32 nIndex) -{ - return nIndex < nFunctionCount ? &nMemory[kFunction[nIndex].nAddress] : 0; + Frame* pInstance = pFrame; + pFrame = pInstance->pLast; + + kFrameAllocator.Free(pInstance); + } + else + { + } }