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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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&#x0D;&#x0A;"
 							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