Mercurial > LightClone
changeset 54:95677f648a2c VirtualMachine Mk2
Refactored VirtualMachine
author | koryspansel |
---|---|
date | Fri, 30 Sep 2011 18:37:54 -0700 |
parents | 8cefb65577cc |
children | 61b522f462e5 41fd0a87a1b9 |
files | LightClone/LightClone.vcproj LightClone/Source/ArrayList.h LightClone/Source/Bot.cpp LightClone/Source/CodePanel.cpp LightClone/Source/CodeSlot.cpp LightClone/Source/Compiler.cpp LightClone/Source/Compiler.h LightClone/Source/Core.h LightClone/Source/Main.cpp LightClone/Source/PoolAllocator.h LightClone/Source/Program.cpp LightClone/Source/Program.h LightClone/Source/Trace.cpp LightClone/Source/VirtualMachine.cpp LightClone/Source/VirtualMachine.h LightClone/ToDo.txt |
diffstat | 16 files changed, 487 insertions(+), 360 deletions(-) [+] |
line wrap: on
line diff
--- a/LightClone/LightClone.vcproj Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/LightClone.vcproj Fri Sep 30 18:37:54 2011 -0700 @@ -90,7 +90,6 @@ /> <Tool Name="VCPostBuildEventTool" - Description="" CommandLine="" /> </Configuration> @@ -171,7 +170,6 @@ /> <Tool Name="VCPostBuildEventTool" - Description="" CommandLine="LightTools\Build.py" /> </Configuration> @@ -201,6 +199,10 @@ > </File> <File + RelativePath=".\Source\Compiler.cpp" + > + </File> + <File RelativePath=".\Source\Environment.cpp" > </File> @@ -343,6 +345,10 @@ > </File> <File + RelativePath=".\Source\Compiler.h" + > + </File> + <File RelativePath=".\Source\Dialog.h" > </File> @@ -458,6 +464,10 @@ > </File> <File + RelativePath=".\Source\PoolAllocator.h" + > + </File> + <File RelativePath=".\Source\RenderContext.h" > </File> @@ -514,7 +524,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -525,7 +535,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -540,7 +550,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -551,7 +561,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -566,7 +576,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -577,7 +587,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -592,7 +602,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -603,7 +613,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -618,7 +628,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" /> @@ -629,7 +639,7 @@ <Tool Name="VCCustomBuildTool" Description="Building $(InputName)..." - CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def" + CommandLine="$(SolutionDir)LightTools\Build.py $(InputName).def
" AdditionalDependencies="$(SolutionDir)Assets\Maps\$(InputName).def" Outputs="$(SolutionDir)Data\Maps\$(InputName).map" />
--- a/LightClone/Source/ArrayList.h Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/ArrayList.h Fri Sep 30 18:37:54 2011 -0700 @@ -5,7 +5,7 @@ #ifndef __ARRAYLIST_H__ #define __ARRAYLIST_H__ -#include "Core.h" +#include "Types.h" /* * ArrayList
--- a/LightClone/Source/Bot.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Bot.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -79,7 +79,7 @@ nState = BotState_Idle; nColor = D3DCOLOR_XRGB(0, 255, 0); - kMachine.RemoveAllFunctions(); + //kMachine.RemoveAllFunctions(); } /*
--- a/LightClone/Source/CodePanel.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/CodePanel.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -44,7 +44,7 @@ pSlot[nIndex].SetPosition(fSlotPadding + (fSlotSizeX + fSlotSpacing) * j, fSlotPadding + (fSlotSizeY + fSlotSpacing) * i); pSlot[nIndex].Subscribe(CodeSlot::EventDrop, &CodePanel::OnActionDropped, this); pSlot[nIndex].SetSlot(nIndex); - pSlot[nIndex].SetAction(Action_Default); + pSlot[nIndex].SetAction(Action_None); Add(&pSlot[nIndex]); } @@ -79,7 +79,7 @@ for(uint32 i = 0; i < nCount; ++i) { - pSlot[i].SetAction(Action_Default); + pSlot[i].SetAction(Action_None); } }
--- a/LightClone/Source/CodeSlot.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/CodeSlot.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -23,7 +23,7 @@ /* * CodeSlot */ -CodeSlot::CodeSlot() : GuiImage(), nAction(Action_Default), bPermanent(false) +CodeSlot::CodeSlot() : GuiImage(), nAction(Action_None), bPermanent(false) { SetFlag(GuiElementFlag_Pickable); } @@ -72,7 +72,7 @@ { nAction = nValue; - SetTexture(nAction == Action_Default ? "Data\\Textures\\Slot.tga" : ActionTextureName[nAction - Action_Forward]); + SetTexture(nAction == Action_None ? "Data\\Textures\\Slot.tga" : ActionTextureName[nAction - Action_Forward]); } /* @@ -122,7 +122,7 @@ { pInterface->ReleaseCursor(); - if(nAction != Action_Default) + if(nAction != Action_None) { //TODO: Figure out some other way of doing this @@ -141,7 +141,7 @@ // not clear out the current action if(!bPermanent) { - SetAction(Action_Default); + SetAction(Action_None); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LightClone/Source/Compiler.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -0,0 +1,97 @@ +/* + * Compiler + */ + +#include "Compiler.h" +#include "Program.h" + +/* + * Compiler + */ +Compiler::Compiler() +{ + for(uint32 i = 0; i < MaximumFunctionCount; ++i) + { + nFunctionTable[i] = 0; + } + + for(uint32 i = 0; i < MaximumFunctionCount * MaximumInstructionCount; ++i) + { + nCallTable[i] = 0; + } +} + +/* + * Compile + */ +ErrorCode Compiler::Compile(const Program& kProgram, uint8* pData, uint32 nSize) +{ + uint32 nOffset = 0; + + //PASS 1: Compile all actions into bytecode instructions + + for(uint32 nFunction = 0; nFunction < MaximumFunctionCount; ++nFunction) + { + // store the address of the function for later fixup + nFunctionTable[nFunction] = nOffset; + + for(uint32 nInstruction = 0; nInstruction < MaximumInstructionCount; ++nInstruction) + { + const uint32 nAction = kProgram.GetAction(nFunction, nInstruction); + const uint32 nLength = GetInstructionSizeFromAction(nAction); + + if(nOffset + nLength < nSize) + { + if(Action_Forward <= nAction && nAction <= Action_Light) + { + pData[nOffset++] = Instruction_Action; + pData[nOffset++] = nAction; + } + else + + if(Action_FunctionA <= nAction && nAction <= Action_FunctionB) + { + pData[nOffset++] = Instruction_Call; + pData[nOffset++] = 0; + + // record the call to the specified function + nCallTable[nOffset - 1] = nAction - Action_FunctionA + 1; + } + else + + { + pData[nOffset++] = Instruction_Nop; + } + + nOffset += GetInstructionSizeFromAction(nAction); + } + else + { + return Error_Fail; + } + } + } + + //PASS 2: Fixup function call addresses + + for(uint32 nAddress = 0; nAddress < MaximumFunctionCount * MaximumInstructionCount; ++nAddress) + { + const uint32 nFunction = nCallTable[nAddress]; + + if(nFunction > 0) + { + // fixup address of function call + pData[nAddress] = nFunctionTable[nFunction]; + } + } + + return Error_Success; +} + +/* + * GetInstructionSizeFromAction + */ +uint32 Compiler::GetInstructionSizeFromAction(uint32 nAction) const +{ + return (Action_Forward <= nAction && nAction <= Action_FunctionB) ? 2 : 1; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LightClone/Source/Compiler.h Fri Sep 30 18:37:54 2011 -0700 @@ -0,0 +1,50 @@ +/* + * Compiler + */ + +#ifndef __COMPILER_H__ +#define __COMPILER_H__ + +#include "Core.h" + +/* + * Program + */ +class Program; + +/* + * Compiler + */ +class Compiler +{ + /* + * nFunctionTable + */ + uint32 nFunctionTable[MaximumFunctionCount]; + + /* + * nCallTable + */ + uint32 nCallTable[MaximumFunctionCount * MaximumInstructionCount]; + +public: + + /* + * Compiler + */ + Compiler(); + + /* + * Compile + */ + ErrorCode Compile(const Program& kProgram, uint8* pData, uint32 nSize); + +private: + + /* + * GetInstructionSizeFromAction + */ + uint32 GetInstructionSizeFromAction(uint32 nAction) const; +}; + +#endif //__COMPILER_H__
--- a/LightClone/Source/Core.h Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Core.h Fri Sep 30 18:37:54 2011 -0700 @@ -48,7 +48,7 @@ */ enum { - Action_Default, + Action_None, Action_Forward, Action_RotateCW, Action_RotateCCW, @@ -117,6 +117,16 @@ const uint32 VerticesPerBlock = FacesPerCube * TrianglesPerFace * VerticesPerTriangle; /* + * MaximumFunctionCount + */ +const uint32 MaximumFunctionCount = 3; + +/* + * MaximumInstructionCount + */ +const uint32 MaximumInstructionCount = 16; + +/* * Position * Represents the position of an object on a grid */
--- a/LightClone/Source/Main.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Main.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -5,6 +5,8 @@ #include <windows.h> #include <tchar.h> #include "Mediator.h" +#include "VirtualMachine.h" +#include "Trace.h" int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LightClone/Source/PoolAllocator.h Fri Sep 30 18:37:54 2011 -0700 @@ -0,0 +1,130 @@ +/* + * PoolAllocator + */ + +#ifndef __POOLALLOCATOR_H__ +#define __POOLALLOCATOR_H__ + +#include "Types.h" + +/* + * PoolAllocator + * Allocates instances of objects from an existing pool, all objects must be + * default constructable + */ +template<typename Type, uint32 Capacity> +class PoolAllocator +{ + /* + * SlotsPerBin + */ + static const uint32 SlotsPerBin = sizeof(uint32) << 3; + + /* + * BinsPerPool + */ + static const uint32 BinsPerPool = ((Capacity - 1) / SlotsPerBin) + 1; + + /* + * kPool + * Maintains the pool of objects to be allocated + */ + Type kPool[Capacity]; + + /* + * nStatus + * Tracks which entries in the pool are in use + */ + uint32 nStatus[BinsPerPool]; + +public: + + /* + * PoolAllocator + */ + PoolAllocator() + { + for(uint32 nBin = 0; nBin < BinsPerPool; ++nBin) + { + nStatus[nBin] = 0; + } + } + + /* + * Allocate + */ + Type* Allocate() + { + int32 nSlot = FindFreeSlot(); + if(nSlot >= 0) + { + uint32 nBin = nSlot / SlotsPerBin; + uint32 nIndex = nSlot - nBin * SlotsPerBin; + + nStatus[nBin] |= (1 << nIndex); + + return &kPool[nSlot]; + } + + return NULL; + } + + /* + * Free + */ + void Free(Type* pInstance) + { + int32 nSlot = FindSlot(pInstance); + if(nSlot >= 0) + { + uint32 nBin = nSlot / SlotsPerBin; + uint32 nIndex = nSlot - nBin * SlotsPerBin; + + nStatus[nBin] &= ~(1 << nIndex); + } + } + +private: + + /* + * FindSlot + */ + int32 FindSlot(Type* pInstance) + { + for(uint32 nSlot = 0; nSlot < Capacity; ++nSlot) + { + if(pInstance == &kPool[nSlot]) + { + return (int32)nSlot; + } + } + + return -1; + } + + /* + * FindFreeSlot + */ + int32 FindFreeSlot() + { + for(uint32 nBin = 0; nBin < BinsPerPool; ++nBin) + { + const uint32 nBinStatus = nStatus[nBin]; + + if(nBinStatus < 0xFFFFFFFF) + { + for(uint32 nIndex = 0; nIndex < SlotsPerBin; ++nIndex) + { + if(!(nBinStatus & (1 << nIndex))) + { + return (int32)(nBin * SlotsPerBin + nIndex); + } + } + } + } + + return -1; + } +}; + +#endif //__ARRAYLIST_H__
--- a/LightClone/Source/Program.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Program.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -3,6 +3,7 @@ */ #include "Program.h" +#include "Compiler.h" /* * Program @@ -31,22 +32,30 @@ */ void Program::SetAction(uint32 nFunction, uint32 nIndex, uint32 nAction) { - if(nFunction < FunctionCount && nIndex < Function::MaximumInstructionCount) + if(nFunction < MaximumFunctionCount && nIndex < MaximumInstructionCount) { kFunction[nFunction].nInstruction[nIndex] = nAction; } } /* + * GetAction + */ +uint32 Program::GetAction(uint32 nFunction, uint32 nIndex) const +{ + return (nFunction < MaximumFunctionCount && nIndex < MaximumInstructionCount) ? kFunction[nFunction].nInstruction[nIndex] : 0; +} + +/* * Clear */ void Program::Clear() { - for(uint32 i = 0; i < FunctionCount; ++i) + for(uint32 i = 0; i < MaximumFunctionCount; ++i) { - for(uint32 j = 0; j < Function::MaximumInstructionCount; ++j) + for(uint32 j = 0; j < MaximumInstructionCount; ++j) { - kFunction[i].nInstruction[j] = Action_Default; + kFunction[i].nInstruction[j] = Action_None; } } } @@ -56,89 +65,10 @@ */ ErrorCode Program::Upload(VirtualMachine& kMachine) const { - ErrorCode eCode = Error_Success; - kMachine.Reset(); - kMachine.ClearMemory(); - //kMachine.RemoveAllFunctions(); - - //uint32 nSize = kMachine.GetMemorySize(); - //uint8* pData = kMachine.GetMemoryPointer(); - - //for(uint32 i = 0; i < FunctionCount && eCode == Error_Success; ++i) - //{ - // eCode = Compile(i, pData, nSize); - //} - - return eCode; -} - -/* - * Compile - */ -ErrorCode Program::Compile(uint32 nIndex, uint8* pData, uint32 nSize) const -{ - ErrorCode eCode = Error_Success; - - for(uint32 i = 0; i < Function::MaximumInstructionCount && eCode == Error_Success; ++i) - { - // encode user-defined actions - eCode = EncodeAction(kFunction[nIndex].nInstruction[i], pData, nSize); - } - - if(eCode == Error_Success) - { - if(nSize > 0) - { - // add implicit return statement - *pData++ = Instruction_End; - } - else - { - eCode = Error_Fail; - } - } + kMachine.Clear(); - return eCode; -} - -/* - * EncodeAction - */ -ErrorCode Program::EncodeAction(uint32 nAction, uint8*& pData, uint32& nSize) const -{ - if(Action_Forward <= nAction && nAction <= Action_Light) - { - if(nSize >= 2) - { - *pData++ = Instruction_Action; - *pData++ = nAction; - - return nSize -= 2, Error_Success; - } - } - else + Compiler kCompiler; + return kCompiler.Compile(*this, kMachine.GetMemoryPointer(), kMachine.GetMemorySize()); - if(Action_FunctionA <= nAction && nAction <= Action_FunctionB) - { - if(nSize >= 2) - { - *pData++ = Instruction_Call; - *pData++ = nAction - Action_FunctionA + 1; - - return nSize -= 2, Error_Success; - } - } - else - - { - if(nSize >= 1) - { - *pData++ = Instruction_None; - - return nSize -= 1, Error_Success; - } - } - - return Error_Fail; }
--- a/LightClone/Source/Program.h Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Program.h Fri Sep 30 18:37:54 2011 -0700 @@ -14,21 +14,11 @@ class Program { /* - * FunctionCount - */ - static const uint32 FunctionCount = 3; - - /* * Function */ struct Function { /* - * MaximumInstructionCount - */ - static const uint32 MaximumInstructionCount = 16; - - /* * nInstruction */ uint32 nInstruction[MaximumInstructionCount]; @@ -53,7 +43,7 @@ /* * kFunction */ - Function kFunction[FunctionCount]; + Function kFunction[MaximumFunctionCount]; public: @@ -78,6 +68,11 @@ void SetAction(uint32 nFunction, uint32 nIndex, uint32 nAction); /* + * GetAction + */ + uint32 GetAction(uint32 nFunction, uint32 nIndex) const; + + /* * Clear */ void Clear(); @@ -86,18 +81,6 @@ * Upload */ ErrorCode Upload(VirtualMachine& kMachine) const; - -private: - - /* - * Compile - */ - ErrorCode Compile(uint32 nFunction, uint8* pData, uint32 nSize) const; - - /* - * EncodeAction - */ - ErrorCode EncodeAction(uint32 nAction, uint8*& pData, uint32& nSize) const; }; #endif //__PROGRAM_H__
--- a/LightClone/Source/Trace.cpp Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/Trace.cpp Fri Sep 30 18:37:54 2011 -0700 @@ -6,6 +6,7 @@ #if defined(TRACE_ENABLE) +#include "Core.h" #include "ArrayList.h" #include <stdarg.h> #include <stdio.h>
--- 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 + { + } }
--- a/LightClone/Source/VirtualMachine.h Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/Source/VirtualMachine.h Fri Sep 30 18:37:54 2011 -0700 @@ -6,17 +6,17 @@ #define __VIRTUALMACHINE_H__ #include "Core.h" +#include "PoolAllocator.h" /* * Instruction */ enum { - Instruction_None = 0, - Instruction_Action = 1, - Instruction_Jump = 2, - Instruction_Call = 3, - Instruction_End = 4, + Instruction_Nop, + Instruction_Action, + Instruction_Call, + Instruction_Return, }; /* @@ -25,76 +25,40 @@ class VirtualMachine { /* - * FunctionDefinition + * Capacity */ - struct FunctionDefinition + static const uint32 Capacity = 1024; + + /* + * Frame + * The frame holds the current execution context, which includes the + * starting address of the function and its continuation. + */ + struct Frame { /* - * nId + * nFunction + * Memory address of the currently executing function */ - uint8 nAddress; + uint32 nAddress; /* - * nSize + * nContinuation + * Memory address of the current function's continuation */ - uint8 nSize; + uint32 nContinuation; + + /* + * pLast + * Pointer to the previous call frame + */ + Frame* pLast; }; /* - * WordBits - */ - static const uint8 WordBits = sizeof(uint8) << 3; - - /* - * FunctionBits - */ - static const uint8 FunctionBits = 3; - - /* - * FunctionShift - */ - static const uint8 FunctionShift = WordBits - FunctionBits; - - /* - * FunctionMask - */ - static const uint8 FunctionMask = ((1 << FunctionBits) - 1) << FunctionShift; - - /* - * InstructionBits - */ - static const uint8 InstructionBits = WordBits - FunctionBits; - - /* - * InstructionShift + * FrameAllocator */ - static const uint8 InstructionShift = 0; - - /* - * InstructionMask - */ - static const uint8 InstructionMask = ((1 << InstructionBits) - 1) << InstructionShift; - - /* - * MaximumFunctionCount - */ - static const uint8 MaximumFunctionCount = 1 << FunctionBits; - - /* - * ContinuationInstructionSize - * Continuations use two instruction slots, one for the jump and one for the address - */ - static const uint8 ContinuationInstructionSize = 2; - - /* - * MaximumInstructionCount - */ - static const uint8 MaximumInstructionCount = (1 << InstructionBits) - ContinuationInstructionSize; - - /* - * FunctionStride - */ - static const uint8 FunctionStride = 1 << InstructionBits; + typedef PoolAllocator<Frame, 16> FrameAllocator; /* * nMemory @@ -102,24 +66,24 @@ * additional instruction is used to implement function * continuations. */ - uint8 nMemory[MaximumFunctionCount * FunctionStride]; + uint8 nMemory[Capacity]; /* * nInstructionPointer * Points to the instruction currently being executed. The value * can be decoded into a function index and instruction offset */ - uint8 nInstructionPointer; + uint32 nInstructionPointer; /* - * kFunction + * pFrame */ - FunctionDefinition kFunction[MaximumFunctionCount]; + Frame* pFrame; /* - * nFunctionCount + * kFrameAllocator */ - uint8 nFunctionCount; + FrameAllocator kFrameAllocator; public: @@ -139,60 +103,40 @@ void Reset(); /* - * SetMemory + * Clear */ - bool SetMemory(uint8 nFunction, const uint8* pData, uint8 nSize); - - /* - * ClearMemory - */ - void ClearMemory(); + void Clear(); /* - * AddFunction + * GetMemorySize */ - bool AddFunction(uint8 nFunction, uint8 nSize); + uint32 GetMemorySize() const; /* - * RemoveAllFunctions - */ - void RemoveAllFunctions(); - - /* - * GetFunctionSize + * GetMemoryPointer */ - uint32 GetFunctionSize(uint32 nFunction) const; - - /* - * GetFunctionMemory - */ - uint8* GetFunctionMemory(uint32 nFunction); + uint8* GetMemoryPointer(); private: /* - * Read + * Advance */ - uint8 Read() + uint8 Advance() { return nMemory[nInstructionPointer++]; } /* - * DecodeAddressFunction + * PushFrame */ - uint8 DecodeAddressFunction(uint8 nAddress) const - { - return (nAddress & FunctionMask) >> FunctionShift; - } + void PushFrame(uint32 nFunctionAddress, uint32 nContinuationAddress); /* - * DecodeAddressOffset + * PopFrame */ - uint8 DecodeAddressOffset(uint8 nAddress) const - { - return (nAddress & InstructionMask) >> InstructionShift; - } + void PopFrame(); + }; #endif //__VIRTUALMACHINE_H__
--- a/LightClone/ToDo.txt Fri Sep 30 15:23:16 2011 -0700 +++ b/LightClone/ToDo.txt Fri Sep 30 18:37:54 2011 -0700 @@ -5,4 +5,7 @@ 5. Help interface 6. Add asserts 7. Move resource manager into a service provider container -8. Refactor virtual machine \ No newline at end of file +8. Refactor virtual machine +9. Rename CodePanel to ProgramPanel +10. Rename CodeSlot to ActionSlot +11. Refactor CodePanel/CodeSlot to read/write data to/from Program \ No newline at end of file