# HG changeset patch
# User koryspansel
# Date 1317433198 25200
# Node ID 61b522f462e549be7f55dbbe74062ca50279e0fd
# Parent 8cefb65577ccc605fbcf1cd60d08605be6c1e606# Parent 95677f648a2caa801cc3a3372da2203fb6a8fbdd
Merge VirtualMachine Mk2
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/LightClone.vcproj
--- a/LightClone/LightClone.vcproj Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/LightClone.vcproj Fri Sep 30 18:39:58 2011 -0700
@@ -90,7 +90,6 @@
/>
@@ -171,7 +170,6 @@
/>
@@ -201,6 +199,10 @@
>
+
+
@@ -343,6 +345,10 @@
>
+
+
@@ -458,6 +464,10 @@
>
+
+
@@ -514,7 +524,7 @@
@@ -525,7 +535,7 @@
@@ -540,7 +550,7 @@
@@ -551,7 +561,7 @@
@@ -566,7 +576,7 @@
@@ -577,7 +587,7 @@
@@ -592,7 +602,7 @@
@@ -603,7 +613,7 @@
@@ -618,7 +628,7 @@
@@ -629,7 +639,7 @@
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/ArrayList.h
--- a/LightClone/Source/ArrayList.h Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/ArrayList.h Fri Sep 30 18:39:58 2011 -0700
@@ -5,7 +5,7 @@
#ifndef __ARRAYLIST_H__
#define __ARRAYLIST_H__
-#include "Core.h"
+#include "Types.h"
/*
* ArrayList
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Bot.cpp
--- a/LightClone/Source/Bot.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Bot.cpp Fri Sep 30 18:39:58 2011 -0700
@@ -79,7 +79,7 @@
nState = BotState_Idle;
nColor = D3DCOLOR_XRGB(0, 255, 0);
- kMachine.RemoveAllFunctions();
+ //kMachine.RemoveAllFunctions();
}
/*
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/CodePanel.cpp
--- a/LightClone/Source/CodePanel.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/CodePanel.cpp Fri Sep 30 18:39:58 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);
}
}
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/CodeSlot.cpp
--- a/LightClone/Source/CodeSlot.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/CodeSlot.cpp Fri Sep 30 18:39:58 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);
}
}
}
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Compiler.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/Compiler.cpp Fri Sep 30 18:39:58 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
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Compiler.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/Compiler.h Fri Sep 30 18:39:58 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__
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Core.h
--- a/LightClone/Source/Core.h Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Core.h Fri Sep 30 18:39:58 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
*/
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Main.cpp
--- a/LightClone/Source/Main.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Main.cpp Fri Sep 30 18:39:58 2011 -0700
@@ -5,6 +5,8 @@
#include
#include
#include "Mediator.h"
+#include "VirtualMachine.h"
+#include "Trace.h"
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int)
{
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/PoolAllocator.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/PoolAllocator.h Fri Sep 30 18:39:58 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
+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__
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Program.cpp
--- a/LightClone/Source/Program.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Program.cpp Fri Sep 30 18:39:58 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;
}
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Program.h
--- a/LightClone/Source/Program.h Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Program.h Fri Sep 30 18:39:58 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__
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/Trace.cpp
--- a/LightClone/Source/Trace.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/Trace.cpp Fri Sep 30 18:39:58 2011 -0700
@@ -6,6 +6,7 @@
#if defined(TRACE_ENABLE)
+#include "Core.h"
#include "ArrayList.h"
#include
#include
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/VirtualMachine.cpp
--- a/LightClone/Source/VirtualMachine.cpp Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/VirtualMachine.cpp Fri Sep 30 18:39:58 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
+ {
+ }
}
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/Source/VirtualMachine.h
--- a/LightClone/Source/VirtualMachine.h Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/Source/VirtualMachine.h Fri Sep 30 18:39:58 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 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__
diff -r 8cefb65577cc -r 61b522f462e5 LightClone/ToDo.txt
--- a/LightClone/ToDo.txt Fri Sep 30 15:23:16 2011 -0700
+++ b/LightClone/ToDo.txt Fri Sep 30 18:39:58 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