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
+	{
+	}
 }