瀏覽代碼

Changed scope and execution to a 3 stack architecture

Xanathar 11 年之前
父節點
當前提交
b209c69e1d
共有 38 個文件被更改,包括 747 次插入225 次删除
  1. 2 2
      src/MoonSharp.Debugger/MainForm.cs
  2. 34 0
      src/MoonSharp.Interpreter/DataStructs/Extension_Methods.cs
  3. 2 8
      src/MoonSharp.Interpreter/Execution/DataTypes/Closure.cs
  4. 1 1
      src/MoonSharp.Interpreter/Execution/DataTypes/RValue.cs
  5. 33 66
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs
  6. 77 0
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs
  7. 60 30
      src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs
  8. 128 0
      src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/BuildTimeScope.cs
  9. 56 0
      src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/BuildTimeScopeFrame.cs
  10. 8 8
      src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/RuntimeScope.cs
  11. 30 0
      src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/RuntimeScopeFrame.cs
  12. 19 0
      src/MoonSharp.Interpreter/Execution/Scopes/RuntimeScopeBlock.cs
  13. 7 13
      src/MoonSharp.Interpreter/Execution/Scopes/RuntimeScopeFrame.cs
  14. 1 1
      src/MoonSharp.Interpreter/Execution/Script.cs
  15. 4 2
      src/MoonSharp.Interpreter/Execution/VM/CallStackItem.cs
  16. 16 10
      src/MoonSharp.Interpreter/Execution/VM/Chunk.cs
  17. 5 6
      src/MoonSharp.Interpreter/Execution/VM/Instruction.cs
  18. 1 2
      src/MoonSharp.Interpreter/Execution/VM/OpCode.cs
  19. 16 3
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor.cs
  20. 3 3
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Debugger.cs
  21. 32 34
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs
  22. 148 0
      src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Scope.cs
  23. 11 4
      src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj
  24. 2 5
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs
  25. 1 1
      src/MoonSharp.Interpreter/Tree/Loop.cs
  26. 4 4
      src/MoonSharp.Interpreter/Tree/NodeBase.cs
  27. 4 3
      src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs
  28. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/ForEachLoopStatement.cs
  29. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/ForLoopStatement.cs
  30. 10 1
      src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs
  31. 4 4
      src/MoonSharp.Interpreter/Tree/Statements/IfStatement.cs
  32. 5 0
      src/MoonSharp.Interpreter/Tree/Statements/LabelStatement.cs
  33. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/LocalAssignmentStatement.cs
  34. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs
  35. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs
  36. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/ScopeBlockStatement.cs
  37. 2 2
      src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs
  38. 11 2
      src/PerformanceComparison/Program.cs

+ 2 - 2
src/MoonSharp.Debugger/MainForm.cs

@@ -234,13 +234,13 @@ namespace MoonSharp.Debugger
 			{
 				lvCallStack.Add(
 					item.Address.ToString("X8"),
-					item.Name ?? "(???)",
+					item.Name ?? ((item.RetAddress < 0) ? "<chunk-root>": "<??unknown??>"),
 					item.RetAddress.ToString("X8"),
 					item.BasePtr.ToString("X8")
 					).Tag = item.Address;
 			}
 
-			lvCallStack.Add("---", "(main)", "---", "---");
+			lvCallStack.Add("---", "<CLR>", "---", "---");
 
 			lvCallStack.EndUpdate();
 		}

+ 34 - 0
src/MoonSharp.Interpreter/DataStructs/Extension_Methods.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter
+{
+	/// <summary>
+	/// Extension methods used in the whole project.
+	/// </summary>
+	internal static class Extension_Methods
+	{
+		/// <summary>
+		/// Gets a value from the dictionary or returns the default value
+		/// </summary>
+		/// <typeparam name="TKey">The type of the key.</typeparam>
+		/// <typeparam name="TValue">The type of the value.</typeparam>
+		/// <param name="dictionary">The dictionary.</param>
+		/// <param name="key">The key.</param>
+		/// <returns></returns>
+		public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
+		{
+			TValue v;
+
+			if (dictionary.TryGetValue(key, out v))
+				return v;
+
+			return default(TValue);
+		}
+
+
+
+	}
+}

+ 2 - 8
src/MoonSharp.Interpreter/Execution/DataTypes/Closure.cs

@@ -14,20 +14,14 @@ namespace MoonSharp.Interpreter.Execution
 		private static ClosureContext emptyClosure = new ClosureContext();
 
 
-		internal Closure(int idx, LRef[] symbols, RuntimeScope scope)
+		internal Closure(int idx, LRef[] symbols, RValue[] localscope)
 		{
 			ByteCodeLocation = idx;
 
 			if (symbols.Length > 0)
-				ClosureContext = new ClosureContext(symbols, symbols.Select(s => scope.Get(s)));
+				ClosureContext = new ClosureContext(symbols, symbols.Select(s => localscope[s.i_Index]));
 			else
 				ClosureContext = emptyClosure;
 		}
-
-		internal void EnterClosureBeforeCall(RuntimeScope scope)
-		{
-			scope.EnterClosure(ClosureContext);
-		}
-
 	}
 }

+ 1 - 1
src/MoonSharp.Interpreter/Execution/DataTypes/RValue.cs

@@ -11,7 +11,7 @@ namespace MoonSharp.Interpreter.Execution
 	public sealed class RValue
 	{
 		static int s_RefIDCounter = 0;
-		private int m_RefID = Interlocked.Increment(ref s_RefIDCounter);
+		private int m_RefID = ++s_RefIDCounter;
 
 		public int ReferenceID { get { return m_RefID; } }
 

+ 33 - 66
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs

@@ -1,91 +1,52 @@
 using System;
 using System.Collections.Generic;
-using MoonSharp.Interpreter.Diagnostics;
 using System.Linq;
 using System.Text;
+using MoonSharp.Interpreter.Execution.Scopes;
 
 namespace MoonSharp.Interpreter.Execution
 {
 	public class BuildTimeScope
 	{
-		List<BuildTimeScopeFrame> m_Locals = new List<BuildTimeScopeFrame>();
+		List<BuildTimeScopeFrame> m_Frames = new List<BuildTimeScopeFrame>();
 		List<IClosureBuilder> m_ClosureBuilders = new List<IClosureBuilder>();
 
 		public BuildTimeScope()
 		{
-			PushFunction();
+			//PushFunction();
 		}
 
-		public void EnterClosure(IClosureBuilder closureBuilder)
-		{
-			m_ClosureBuilders.Add(closureBuilder);
-			closureBuilder.UpvalueCreationTag = (m_Locals.Count - 1);
-		}
-
-		public void LeaveClosure()
-		{
-			m_ClosureBuilders.RemoveAt(m_ClosureBuilders.Count - 1);
-		}
-
-
-		int GetStartIndexForPush()
-		{
-			return m_Locals[m_Locals.Count - 1].MaxIndex;
-		}
-		int GetBaseIndexForPush()
+		public void PushFunction()
 		{
-			return m_Locals[m_Locals.Count - 1].BaseIndex;
+			m_Frames.Add(new BuildTimeScopeFrame());
 		}
 
 		public void PushBlock()
 		{
-			// Debug.WriteLine("PushBlock");
-			m_Locals.Add(new BuildTimeScopeFrame(GetBaseIndexForPush(), GetStartIndexForPush(), false));
+			m_Frames.Last().PushBlock();
 		}
 
-		public void PushFunction()
+		public RuntimeScopeBlock PopBlock()
 		{
-			// Debug.WriteLine("PushFunction");
-			m_Locals.Add(new BuildTimeScopeFrame(0, 0, true));
+			return m_Frames.Last().PopBlock();
 		}
 
-		RuntimeScopeFrame GetRuntimeFrameFromBuildFrame(BuildTimeScopeFrame frame, bool local)
+		public RuntimeScopeFrame PopFunction()
 		{
-			List<LRef> symbols = new List<LRef>();
-			for (int i = frame.StartIndex; i < frame.MaxIndex; i++)
-			{
-				LRef s;
-				if (local)
-					s = LRef.Local(frame.FindRev(i - frame.BaseIndex), i - frame.BaseIndex);
-				else
-					s = LRef.Global(frame.FindRev(i - frame.BaseIndex));
-
-				symbols.Add(s);
-			}
-
-			return new RuntimeScopeFrame(symbols, frame.MaxIndex - frame.StartIndex, frame.Breaking);
+			var last = m_Frames.Last();
+			last.ResolveLRefs();
+			m_Frames.RemoveAt(m_Frames.Count - 1);
+			
+			return last.GetRuntimeFrameData();
 		}
 
-		public RuntimeScopeFrame Pop()
-		{
-			BuildTimeScopeFrame frame = m_Locals[m_Locals.Count - 1];
-			m_Locals.RemoveAt(m_Locals.Count - 1);
-			// Debug.WriteLine(string.Format("Pop : {0}", frame.MaxIndex - frame.StartIndex));
-
-			return GetRuntimeFrameFromBuildFrame(frame, true);
-		}
 
 		public LRef Find(string name)
 		{
-			for (int i = m_Locals.Count - 1; i >= 0; i--)
-			{
-				int idx = m_Locals[i].Find(name);
-				if (idx >= 0)
-					return LRef.Local(name, idx);
+			LRef local = m_Frames.Last().Find(name);
 
-				if (m_Locals[i].Breaking)
-					break;
-			}
+			if (local != null)
+				return local;
 
 			IClosureBuilder closure = m_ClosureBuilders.LastOrDefault();
 
@@ -97,9 +58,9 @@ namespace MoonSharp.Interpreter.Execution
 				{
 					for (int i = closureLocalBlockIdx; i >= 0; i--)
 					{
-						int idx = m_Locals[i].Find(name);
-						if (idx >= 0)
-							return closure.CreateUpvalue(this, LRef.Local(name, idx));
+						LRef symb = m_Frames[i].Find(name);
+						if (symb != null)
+							return closure.CreateUpvalue(this, symb);
 					}
 				}
 			}
@@ -109,20 +70,26 @@ namespace MoonSharp.Interpreter.Execution
 
 		public LRef DefineLocal(string name)
 		{
-			return LRef.Local(name, m_Locals[m_Locals.Count - 1].Define(name));
+			return m_Frames.Last().DefineLocal(name);
 		}
 
 		public LRef TryDefineLocal(string name)
 		{
-			int idx = m_Locals[m_Locals.Count - 1].Find(name);
+			return m_Frames.Last().TryDefineLocal(name);
+		}
 
-			if (idx >= 0)
-				return LRef.Local(name, idx);
 
-			var s = LRef.Local(name, m_Locals[m_Locals.Count - 1].Define(name));
-			// Debug.WriteLine(string.Format("Define local : {0}", s));
-			return s;
+		public void EnterClosure(IClosureBuilder closureBuilder)
+		{
+			m_ClosureBuilders.Add(closureBuilder);
+			closureBuilder.UpvalueCreationTag = (m_Frames.Count - 1);
+		}
+
+		public void LeaveClosure()
+		{
+			m_ClosureBuilders.RemoveAt(m_ClosureBuilders.Count - 1);
 		}
 
+
 	}
 }

+ 77 - 0
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeBlock.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Execution.Scopes
+{
+	internal class BuildTimeScopeBlock
+	{
+		internal BuildTimeScopeBlock Parent { get; private set; }
+		internal List<BuildTimeScopeBlock> ChildNodes { get; private set; }
+
+		internal RuntimeScopeBlock ScopeBlock { get; private set; }
+
+		Dictionary<string, LRef> m_DefinedNames = new Dictionary<string, LRef>();
+
+		internal BuildTimeScopeBlock(BuildTimeScopeBlock parent)
+		{
+			Parent = parent;
+			ChildNodes = new List<BuildTimeScopeBlock>();
+			ScopeBlock = new RuntimeScopeBlock();
+		}
+
+
+		internal BuildTimeScopeBlock AddChild()
+		{
+			BuildTimeScopeBlock block = new BuildTimeScopeBlock(this);
+			ChildNodes.Add(block);
+			return block;
+		}
+
+		internal LRef Find(string name)
+		{
+			return m_DefinedNames.GetOrDefault(name);
+		}
+
+		internal LRef Define(string name)
+		{
+			LRef l = LRef.Local(name, -1);
+			if (m_DefinedNames.ContainsKey(name))
+			{
+				int a = 3;
+			}
+			m_DefinedNames.Add(name, l);
+			return l;
+		}
+
+		internal int ResolveLRefs(BuildTimeScopeFrame buildTimeScopeFrame)
+		{
+			int firstVal = -1;
+			int lastVal = -1;
+
+			foreach (LRef lref in m_DefinedNames.Values)
+			{
+				int pos = buildTimeScopeFrame.AllocVar(lref);
+
+				if (firstVal < 0)
+					firstVal = pos;
+
+				lastVal = pos;
+			}
+
+			this.ScopeBlock.From = firstVal;
+			this.ScopeBlock.ToInclusive = this.ScopeBlock.To = lastVal;
+
+			if (firstVal < 0)
+				this.ScopeBlock.From = buildTimeScopeFrame.GetPosForNextVar();
+
+			foreach (var child in ChildNodes)
+			{
+				this.ScopeBlock.ToInclusive = Math.Max(this.ScopeBlock.ToInclusive, child.ResolveLRefs(buildTimeScopeFrame));
+			}
+
+			return lastVal;
+		}
+	}
+}

+ 60 - 30
src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs

@@ -2,55 +2,85 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
-using MoonSharp.Interpreter.Execution;
 
-namespace MoonSharp.Interpreter.Execution
+namespace MoonSharp.Interpreter.Execution.Scopes
 {
-	class BuildTimeScopeFrame
+	internal class BuildTimeScopeFrame
 	{
-		Dictionary<string, int> m_IndexList = new Dictionary<string, int>();
-		Dictionary<int, string> m_RevIndexList = new Dictionary<int, string>();
+		BuildTimeScopeBlock m_ScopeTreeRoot;
+		BuildTimeScopeBlock m_ScopeTreeHead;
+		RuntimeScopeFrame m_ScopeFrame = new RuntimeScopeFrame();
 
-		public int BaseIndex { get; private set; }
-		public int StartIndex { get; private set; }
-
-		public int MaxIndex { get; private set; }
-
-		public bool Breaking { get; private set; }
+		internal BuildTimeScopeFrame()
+		{
+			m_ScopeTreeHead = m_ScopeTreeRoot = new BuildTimeScopeBlock(null);
+		}
 
-		public BuildTimeScopeFrame(int baseIndex, int startIndex, bool breaking)
+		internal void PushBlock()
 		{
-			BaseIndex = baseIndex;
-			StartIndex = MaxIndex = startIndex;
-			Breaking = breaking;
+			m_ScopeTreeHead = m_ScopeTreeHead.AddChild();
 		}
 
-		public int Find(string name)
+		internal RuntimeScopeBlock PopBlock()
 		{
-			if (m_IndexList.ContainsKey(name))
-				return m_IndexList[name];
+			var tree = m_ScopeTreeHead;
 
-			return -1;
+			m_ScopeTreeHead = m_ScopeTreeHead.Parent;
+
+			if (m_ScopeTreeHead == null)
+				throw new InternalErrorException("Can't pop block - stack underflow");
+
+			return tree.ScopeBlock;
 		}
 
-		public string FindRev(int idx)
+		internal RuntimeScopeFrame GetRuntimeFrameData()
 		{
-			return m_RevIndexList[idx];
+			if (m_ScopeTreeHead != m_ScopeTreeRoot)
+				throw new InternalErrorException("Misaligned scope frames/blocks!");
+
+			m_ScopeFrame.ToFirstBlock = m_ScopeTreeRoot.ScopeBlock.To;
+
+			return m_ScopeFrame;
 		}
 
-		public int Define(string name)
+		internal LRef Find(string name)
 		{
-			if (!m_IndexList.ContainsKey(name))
-			{
-				m_IndexList.Add(name, MaxIndex - BaseIndex);
-				m_RevIndexList.Add(MaxIndex - BaseIndex, name);
-				return MaxIndex++;
-			}
-			else
+			for (var tree = m_ScopeTreeHead; tree != null; tree = tree.Parent)
 			{
-				return m_IndexList[name];
+				LRef l = tree.Find(name);
+
+				if (l != null)
+					return l;
 			}
+
+			return null;
+		}
+
+		internal LRef DefineLocal(string name)
+		{
+			return m_ScopeTreeHead.Define(name);
 		}
 
+		internal LRef TryDefineLocal(string name)
+		{
+			return m_ScopeTreeHead.Find(name) ?? m_ScopeTreeHead.Define(name);
+		}
+
+		internal void ResolveLRefs()
+		{
+			m_ScopeTreeRoot.ResolveLRefs(this);
+		}
+
+		internal int AllocVar(LRef var)
+		{
+			var.i_Index = m_ScopeFrame.DebugSymbols.Count;
+			m_ScopeFrame.DebugSymbols.Add(var);
+			return var.i_Index;
+		}
+
+		internal int GetPosForNextVar()
+		{
+			return m_ScopeFrame.DebugSymbols.Count;
+		}
 	}
 }

+ 128 - 0
src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/BuildTimeScope.cs

@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using MoonSharp.Interpreter.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Execution
+{
+	public class BuildTimeScope_UNUSED
+	{
+		List<BuildTimeScopeFrame_UNUSED> m_Locals = new List<BuildTimeScopeFrame_UNUSED>();
+		List<IClosureBuilder> m_ClosureBuilders = new List<IClosureBuilder>();
+
+		public BuildTimeScope_UNUSED()
+		{
+			PushFunction();
+		}
+
+		public void EnterClosure(IClosureBuilder closureBuilder)
+		{
+			m_ClosureBuilders.Add(closureBuilder);
+			closureBuilder.UpvalueCreationTag = (m_Locals.Count - 1);
+		}
+
+		public void LeaveClosure()
+		{
+			m_ClosureBuilders.RemoveAt(m_ClosureBuilders.Count - 1);
+		}
+
+
+		int GetStartIndexForPush()
+		{
+			return m_Locals[m_Locals.Count - 1].MaxIndex;
+		}
+		int GetBaseIndexForPush()
+		{
+			return m_Locals[m_Locals.Count - 1].BaseIndex;
+		}
+
+		public void PushBlock()
+		{
+			// Debug.WriteLine("PushBlock");
+			m_Locals.Add(new BuildTimeScopeFrame_UNUSED(GetBaseIndexForPush(), GetStartIndexForPush(), false));
+		}
+
+		public void PushFunction()
+		{
+			// Debug.WriteLine("PushFunction");
+			m_Locals.Add(new BuildTimeScopeFrame_UNUSED(0, 0, true));
+		}
+
+		RuntimeScopeFrame_UNUSED GetRuntimeFrameFromBuildFrame(BuildTimeScopeFrame_UNUSED frame, bool local)
+		{
+			List<LRef> symbols = new List<LRef>();
+			for (int i = frame.StartIndex; i < frame.MaxIndex; i++)
+			{
+				LRef s;
+				if (local)
+					s = LRef.Local(frame.FindRev(i - frame.BaseIndex), i - frame.BaseIndex);
+				else
+					s = LRef.Global(frame.FindRev(i - frame.BaseIndex));
+
+				symbols.Add(s);
+			}
+
+			return new RuntimeScopeFrame_UNUSED(symbols, frame.MaxIndex - frame.StartIndex, frame.Breaking);
+		}
+
+		public RuntimeScopeFrame_UNUSED Pop()
+		{
+			BuildTimeScopeFrame_UNUSED frame = m_Locals[m_Locals.Count - 1];
+			m_Locals.RemoveAt(m_Locals.Count - 1);
+			// Debug.WriteLine(string.Format("Pop : {0}", frame.MaxIndex - frame.StartIndex));
+
+			return GetRuntimeFrameFromBuildFrame(frame, true);
+		}
+
+		public LRef Find(string name)
+		{
+			for (int i = m_Locals.Count - 1; i >= 0; i--)
+			{
+				int idx = m_Locals[i].Find(name);
+				if (idx >= 0)
+					return LRef.Local(name, idx);
+
+				if (m_Locals[i].Breaking)
+					break;
+			}
+
+			IClosureBuilder closure = m_ClosureBuilders.LastOrDefault();
+
+			if (closure != null)
+			{
+				int closureLocalBlockIdx = (int)closure.UpvalueCreationTag;
+
+				if (closureLocalBlockIdx >= 0)
+				{
+					for (int i = closureLocalBlockIdx; i >= 0; i--)
+					{
+						int idx = m_Locals[i].Find(name);
+						if (idx >= 0)
+							return null; // was closure.CreateUpvalue(this, LRef.Local(name, idx));
+					}
+				}
+			}
+
+			return LRef.Global(name);
+		}
+
+		public LRef DefineLocal(string name)
+		{
+			return LRef.Local(name, m_Locals[m_Locals.Count - 1].Define(name));
+		}
+
+		public LRef TryDefineLocal(string name)
+		{
+			int idx = m_Locals[m_Locals.Count - 1].Find(name);
+
+			if (idx >= 0)
+				return LRef.Local(name, idx);
+
+			var s = LRef.Local(name, m_Locals[m_Locals.Count - 1].Define(name));
+			// Debug.WriteLine(string.Format("Define local : {0}", s));
+			return s;
+		}
+
+	}
+}

+ 56 - 0
src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/BuildTimeScopeFrame.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Execution;
+
+namespace MoonSharp.Interpreter.Execution
+{
+	class BuildTimeScopeFrame_UNUSED
+	{
+		Dictionary<string, int> m_IndexList = new Dictionary<string, int>();
+		Dictionary<int, string> m_RevIndexList = new Dictionary<int, string>();
+
+		public int BaseIndex { get; private set; }
+		public int StartIndex { get; private set; }
+
+		public int MaxIndex { get; private set; }
+
+		public bool Breaking { get; private set; }
+
+		public BuildTimeScopeFrame_UNUSED(int baseIndex, int startIndex, bool breaking)
+		{
+			BaseIndex = baseIndex;
+			StartIndex = MaxIndex = startIndex;
+			Breaking = breaking;
+		}
+
+		public int Find(string name)
+		{
+			if (m_IndexList.ContainsKey(name))
+				return m_IndexList[name];
+
+			return -1;
+		}
+
+		public string FindRev(int idx)
+		{
+			return m_RevIndexList[idx];
+		}
+
+		public int Define(string name)
+		{
+			if (!m_IndexList.ContainsKey(name))
+			{
+				m_IndexList.Add(name, MaxIndex - BaseIndex);
+				m_RevIndexList.Add(MaxIndex - BaseIndex, name);
+				return MaxIndex++;
+			}
+			else
+			{
+				return m_IndexList[name];
+			}
+		}
+
+	}
+}

+ 8 - 8
src/MoonSharp.Interpreter/Execution/Scopes/RuntimeScope.cs → src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/RuntimeScope.cs

@@ -8,15 +8,15 @@ using MoonSharp.Interpreter.DataStructs;
 
 namespace MoonSharp.Interpreter.Execution
 {
-	public class RuntimeScope
+	public class RuntimeScope_UNUSED
 	{
 		Table m_GlobalTable;
 		FastStack<RValue> m_ScopeStack = new FastStack<RValue>(131072); // start with a 512KB scope stack
 		FastStack<int> m_LocalBaseIndexes = new FastStack<int>(16384);
 		FastStack<ClosureContext> m_ClosureStack = new FastStack<ClosureContext>(4096);
-		FastStack<RuntimeScopeFrame> m_ScopeFrames = new FastStack<RuntimeScopeFrame>(8192);
+		FastStack<RuntimeScopeFrame_UNUSED> m_ScopeFrames = new FastStack<RuntimeScopeFrame_UNUSED>(8192);
 
-		public RuntimeScope()
+		public RuntimeScope_UNUSED()
 		{
 		}
 
@@ -36,7 +36,7 @@ namespace MoonSharp.Interpreter.Execution
 			m_ClosureStack.RemoveLast();
 		}
 
-		public void PushFrame(RuntimeScopeFrame frame)
+		public void PushFrame(RuntimeScopeFrame_UNUSED frame)
 		{
 			int size = frame.Count;
 
@@ -49,16 +49,16 @@ namespace MoonSharp.Interpreter.Execution
 
 		}
 
-		public void PopFrame(RuntimeScopeFrame frame)
+		public void PopFrame(RuntimeScopeFrame_UNUSED frame)
 		{
 			System.Diagnostics.Debug.Assert(frame == m_ScopeFrames.Peek());
 			PopFrame();
 		}
 
 
-		public RuntimeScopeFrame PopFrame()
+		public RuntimeScopeFrame_UNUSED PopFrame()
 		{
-			RuntimeScopeFrame frame = m_ScopeFrames.Pop();
+			RuntimeScopeFrame_UNUSED frame = m_ScopeFrames.Pop();
 
 			int size = frame.Count;
 			if (size > 0)
@@ -78,7 +78,7 @@ namespace MoonSharp.Interpreter.Execution
 			while (!PopFrame().RestartOfBase) ;
 		}
 
-		public void PopFramesToFrame(RuntimeScopeFrame runtimeScopeFrame)
+		public void PopFramesToFrame(RuntimeScopeFrame_UNUSED runtimeScopeFrame)
 		{
 			while (m_ScopeFrames.Peek() != runtimeScopeFrame)
 				PopFrame();

+ 30 - 0
src/MoonSharp.Interpreter/Execution/Scopes/OldScopeClasses/RuntimeScopeFrame.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Execution
+{
+	public class RuntimeScopeFrame_UNUSED
+	{
+		public List<LRef> m_DebugSymbols { get; private set;}
+		public int Count { get; private set;}
+		public bool RestartOfBase { get; private set; }
+
+
+		public RuntimeScopeFrame_UNUSED(IEnumerable<LRef> symbols, int count, bool restartOfBase)
+		{
+			m_DebugSymbols = symbols.ToList();
+			Count = count;
+			RestartOfBase = restartOfBase;
+
+			if (Count != m_DebugSymbols.Count)
+				throw new Exception("WTF");
+		}
+
+		public override string ToString()
+		{
+			return string.Format("{0} frame : #{1}", RestartOfBase ? "Function" : "Block", Count);
+		}
+	}
+}

+ 19 - 0
src/MoonSharp.Interpreter/Execution/Scopes/RuntimeScopeBlock.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Execution
+{
+	public class RuntimeScopeBlock
+	{
+		public int From { get; internal set; }
+		public int To { get; internal set; }
+		public int ToInclusive { get; internal set; }
+
+		public override string ToString()
+		{
+			return String.Format("ScopeBlock : {0} -> {1} --> {2}", From, To, ToInclusive);
+		}
+	}
+}

+ 7 - 13
src/MoonSharp.Interpreter/Execution/Scopes/RuntimeScopeFrame.cs

@@ -5,26 +5,20 @@ using System.Text;
 
 namespace MoonSharp.Interpreter.Execution
 {
-	public class RuntimeScopeFrame
+	public class RuntimeScopeFrame 
 	{
-		public List<LRef> m_DebugSymbols { get; private set;}
-		public int Count { get; private set;}
-		public bool RestartOfBase { get; private set; }
+		public List<LRef> DebugSymbols { get; private set; }
+		public int Count { get { return DebugSymbols.Count; } }
+		public int ToFirstBlock { get; internal set; }
 
-
-		public RuntimeScopeFrame(IEnumerable<LRef> symbols, int count, bool restartOfBase)
+		public RuntimeScopeFrame()
 		{
-			m_DebugSymbols = symbols.ToList();
-			Count = count;
-			RestartOfBase = restartOfBase;
-
-			if (Count != m_DebugSymbols.Count)
-				throw new Exception("WTF");
+			DebugSymbols = new List<LRef>();
 		}
 
 		public override string ToString()
 		{
-			return string.Format("{0} frame : #{1}", RestartOfBase ? "Function" : "Block", Count);
+			return string.Format("ScopeFrame : #{0}", Count);
 		}
 	}
 }

+ 1 - 1
src/MoonSharp.Interpreter/Execution/Script.cs

@@ -42,7 +42,7 @@ namespace MoonSharp.Interpreter.Execution
 
 			using (var _ = new CodeChrono("MoonSharpScript.Execute"))
 			{
-				return m_Main.Execute();
+				return m_Main.InvokeRoot();
 			}
 		}
 

+ 4 - 2
src/MoonSharp.Interpreter/Execution/VM/CallStackItem.cs

@@ -5,12 +5,14 @@ using System.Text;
 
 namespace MoonSharp.Interpreter.Execution.VM
 {
-
 	public class CallStackItem
 	{
+		public int Debug_EntryPoint;
+		public LRef[] Debug_Symbols;
+
 		public int BasePointer;
 		public int ReturnAddress;
-		public int Debug_EntryPoint;
+		public RValue[] LocalScope;
 	}
 
 }

+ 16 - 10
src/MoonSharp.Interpreter/Execution/VM/Chunk.cs

@@ -132,10 +132,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 		{
 			Emit(new Instruction() { OpCode = OpCode.Debug, Name = str.Substring(0, Math.Min(32, str.Length)) });
 		}
-		public void DebugFn(string fnname)
-		{
-			Emit(new Instruction() { OpCode = OpCode.DebugFn, Name = fnname });
-		}
 
 		//[Conditional("EMIT_DEBUG_OPS")]
 		public void Debug(Antlr4.Runtime.Tree.IParseTree parseTree)
@@ -144,19 +140,19 @@ namespace MoonSharp.Interpreter.Execution.VM
 			Emit(new Instruction() { OpCode = OpCode.Debug, Name = str.Substring(0, Math.Min(32, str.Length)) });
 		}
 
-		public Instruction Enter(RuntimeScopeFrame runtimeScopeFrame)
+		public Instruction Enter(RuntimeScopeBlock runtimeScopeBlock)
 		{
-			return Emit(new Instruction() { OpCode = OpCode.Enter, Frame = runtimeScopeFrame });
+			return Emit(new Instruction() { OpCode = OpCode.Enter, Block = runtimeScopeBlock });
 		}
 
-		public Instruction Leave(RuntimeScopeFrame runtimeScopeFrame)
+		public Instruction Leave(RuntimeScopeBlock runtimeScopeBlock)
 		{
-			return Emit(new Instruction() { OpCode = OpCode.Leave });
+			return Emit(new Instruction() { OpCode = OpCode.Leave, Block = runtimeScopeBlock });
 		}
 
-		public Instruction Exit(RuntimeScopeFrame runtimeScopeFrame = null)
+		public Instruction Exit(RuntimeScopeBlock runtimeScopeBlock = null)
 		{
-			return Emit(new Instruction() { OpCode = OpCode.Exit, Frame = runtimeScopeFrame });
+			return Emit(new Instruction() { OpCode = OpCode.Exit, Block = runtimeScopeBlock });
 		}
 
 		public Instruction Closure(LRef[] symbols, int jmpnum)
@@ -237,5 +233,15 @@ namespace MoonSharp.Interpreter.Execution.VM
 		{
 			return Emit(new Instruction() { OpCode = OpCode.Method });
 		}
+
+		public Instruction BeginFn(RuntimeScopeFrame m_StackFrame, string funcName)
+		{
+			return Emit(new Instruction() { OpCode = OpCode.BeginFn, 
+				SymbolList = m_StackFrame.DebugSymbols.ToArray(), 
+				NumVal = m_StackFrame.Count,
+				NumVal2 = m_StackFrame.ToFirstBlock,
+				Name = funcName 
+			});
+		}
 	}
 }

+ 5 - 6
src/MoonSharp.Interpreter/Execution/VM/Instruction.cs

@@ -14,7 +14,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 		public RValue Value;
 		public int NumVal;
 		public int NumVal2;
-		public RuntimeScopeFrame Frame;
+		public RuntimeScopeBlock Block;
 		public bool Breakpoint;
 
 		public override string ToString()
@@ -31,10 +31,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 					break;
 				case OpCode.Enter:
 				case OpCode.Exit:
-					append = string.Format("{0}{1}", GenSpaces(), FrameToString(Frame));
+					append = string.Format("{0}{1}", GenSpaces(), FrameToString(Block));
 					break;
-				case OpCode.DebugFn:
-					return string.Format("[[ function {0} ]]", Name);
 				case OpCode.Debug:
 					return string.Format("[[ {0} ]]", Name);
 				case OpCode.Load:
@@ -77,12 +75,12 @@ namespace MoonSharp.Interpreter.Execution.VM
 			return this.OpCode.ToString().ToUpperInvariant() + append;
 		}
 
-		private string FrameToString(RuntimeScopeFrame frame)
+		private string FrameToString(RuntimeScopeBlock frame)
 		{
 			if (frame == null)
 				return "<null>";
 			else
-				return string.Format("{0}({1})", frame.RestartOfBase ? "function" : "block", frame.Count);
+				return frame.ToString();
 		}
 
 		private string PurifyFromNewLines(RValue Value)
@@ -96,5 +94,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 		}
 
 
+
 	}
 }

+ 1 - 2
src/MoonSharp.Interpreter/Execution/VM/OpCode.cs

@@ -12,7 +12,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 		Nop,		// Does not perform any operation.
 		Invalid,	// Crashes the executor with an unrecoverable NotImplementedException.
 		Debug,		// Does not perform any operation. Used to help debugging.
-		DebugFn,	// Does not perform any operation. Used to help the debugger.
 
 		// Stack ops and assignment
 		Pop,		// Discards the topmost n elements from the v-stack. 
@@ -29,6 +28,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 		Leave,		// Leaves a stack frame
 		Exit,		// Leaves every stack frame up and including the topmost function frame, plus it exits the topmost closure
 		ExitClsr,	// Exits a closure at runtime
+		BeginFn,	// Adjusts for start of function, taking in parameters and allocating locals
 		Args,		// Takes the arguments passed to a function and sets the appropriate symbols in the local scope
 		Call,		// Calls the function specified on the specified element from the top of the v-stack. If the function is a Moon# function, it pushes its numeric value on the v-stack, then pushes the current PC onto the x-stack, enters the function closure and jumps to the function first instruction. If the function is a CLR function, it pops the function value from the v-stack, then invokes the function synchronously and finally pushes the result on the v-stack.
 		Ret,		// Pops the top n values of the v-stack. Then pops an X value from the v-stack. Then pops X values from the v-stack. Afterwards, it pushes the top n values popped in the first step, pops the top of the x-stack and jumps to that location.
@@ -73,6 +73,5 @@ namespace MoonSharp.Interpreter.Execution.VM
 		// Iterators
 		IterPrep,   // Prepares an interator for execution 
 		IterUpd,	// Updates the var part of an iterator
-
 	}
 }

+ 16 - 3
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor.cs

@@ -16,26 +16,39 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		FastStack<RValue> m_ValueStack = new FastStack<RValue>(131072);
 		FastStack<CallStackItem> m_ExecutionStack = new FastStack<CallStackItem>(131072);
-		RuntimeScope m_Scope;
+		FastStack<ClosureContext> m_ClosureStack = new FastStack<ClosureContext>(131072);
 
 		IDebugger m_DebuggerAttached = null;
 		DebuggerAction.ActionType m_DebuggerCurrentAction = DebuggerAction.ActionType.None;
 		int m_DebuggerCurrentActionTarget = -1;
 
+		Table m_GlobalTable = new Table();
+
 		public Processor(Chunk rootChunk)
 		{
 			m_RootChunk = m_CurChunk = rootChunk;
 			m_InstructionPtr = 0;
-			m_Scope = new RuntimeScope();
 		}
 
 		public void Reset(Table global)
 		{
 			m_CurChunk = m_RootChunk;
 			m_InstructionPtr = 0;
-			m_Scope.GlobalTable = global;
+			m_GlobalTable = global;
 		}
 
+		public RValue InvokeRoot()
+		{
+			m_ValueStack.Push(new RValue(0));  // func val
+			m_ValueStack.Push(new RValue(0));  // func args count
+			m_ExecutionStack.Push(new CallStackItem()
+			{
+				BasePointer = m_ValueStack.Count,
+				Debug_EntryPoint = 0,
+				ReturnAddress = -1,
+			});
 
+			return Processing_Loop();
+		}
 	}
 }

+ 3 - 3
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Debugger.cs

@@ -97,11 +97,11 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		private WatchItem Debugger_RefreshWatch(string name)
 		{
-			LRef L = m_Scope.FindRefByName(name);
+			LRef L = FindRefByName(name);
 
 			if (L != null)
 			{
-				RValue v = m_Scope.Get(L);
+				RValue v = this.GetGenericSymbol(L);
 
 				return new WatchItem()
 				{
@@ -126,7 +126,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 				var I = m_CurChunk.Code[c.Debug_EntryPoint];
 
-				string callname = I.OpCode == OpCode.DebugFn ? I.Name : null;
+				string callname = I.OpCode == OpCode.BeginFn ? I.Name : null;
 
 
 				wis.Add(new WatchItem()

+ 32 - 34
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

@@ -9,9 +9,9 @@ namespace MoonSharp.Interpreter.Execution.VM
 {
 	sealed partial class Processor
 	{
-		public RValue Execute()
+		private RValue Processing_Loop()
 		{
-			while (m_InstructionPtr < m_CurChunk.Code.Count && !m_Terminate)
+			while (m_InstructionPtr < m_CurChunk.Code.Count && m_InstructionPtr >= 0)
 			{
 				Instruction i = m_CurChunk.Code[m_InstructionPtr];
 
@@ -26,13 +26,12 @@ namespace MoonSharp.Interpreter.Execution.VM
 				{
 					case OpCode.Nop:
 					case OpCode.Debug:
-					case OpCode.DebugFn:
 						break;
 					case OpCode.Pop:
 						m_ValueStack.RemoveLast(i.NumVal);
 						break;
 					case OpCode.Load:
-						m_ValueStack.Push(m_Scope.Get(i.Symbol));
+						m_ValueStack.Push(this.GetGenericSymbol(i.Symbol));
 						break;
 					case OpCode.Literal:
 						m_ValueStack.Push(i.Value);
@@ -102,19 +101,20 @@ namespace MoonSharp.Interpreter.Execution.VM
 						m_ValueStack.Push(RValue.FromPotentiallyNestedTuple(StackTopToArrayReverse(i.NumVal, true)));
 						break;
 					case OpCode.Enter:
-						m_Scope.PushFrame(i.Frame);
+						NilifyBlockData(i.Block);
 						break;
 					case OpCode.Leave:
-						m_Scope.PopFrame();
-						break;
 					case OpCode.Exit:
-						ExecExit(i);
+						ClearBlockData(i.Block, i.OpCode == OpCode.Exit);
 						break;
 					case OpCode.Closure:
-						m_ValueStack.Push(new RValue(new Closure(i.NumVal, i.SymbolList, m_Scope)));
+						m_ValueStack.Push(new RValue(new Closure(i.NumVal, i.SymbolList, m_ExecutionStack.Peek().LocalScope)));
 						break;
 					case OpCode.ExitClsr:
-						m_Scope.LeaveClosure();
+						this.LeaveClosure();
+						break;
+					case OpCode.BeginFn:
+						ExecBeginFn(i);
 						break;
 					case OpCode.Args:
 						ExecArgs(i);
@@ -177,6 +177,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		}
 
+
+
 		private void ExecJNil(Instruction i)
 		{
 			RValue v = m_ValueStack.Pop();
@@ -232,19 +234,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 			m_ValueStack.Push(v);
 		}
 
-		private void ExecExit(Instruction i)
-		{
-			if (i.Frame == null)
-			{
-				m_Scope.PopFramesToFunction();
-				if (m_ExecutionStack.Count > 0)
-					m_Scope.LeaveClosure();
-			}
-			else
-			{
-				m_Scope.PopFramesToFrame(i.Frame);
-			}
-		}
 
 		private void ExecJFor(Instruction i)
 		{
@@ -286,12 +275,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		private void ExecRet(Instruction i)
 		{
-			if (m_ExecutionStack.Count == 0)
-			{
-				m_Terminate = true;
-				return;
-			}
-
 			if (i.NumVal == 0)
 			{
 				int retpoint = PopToBasePointer();
@@ -315,6 +298,21 @@ namespace MoonSharp.Interpreter.Execution.VM
 			}
 		}
 
+		private void ExecBeginFn(Instruction i)
+		{
+			CallStackItem c = m_ExecutionStack.Peek();
+			c.Debug_Symbols = i.SymbolList;
+			c.LocalScope = new RValue[i.NumVal];
+
+			if (i.NumVal2 >= 0 && i.NumVal > 0)
+			{
+				for (int idx = 0; idx < i.NumVal2; idx++)
+				{
+					c.LocalScope[idx] = new RValue();
+				}
+			}
+		}
+
 		private int PopToBasePointer()
 		{
 			var xs = m_ExecutionStack.Pop();
@@ -339,11 +337,11 @@ namespace MoonSharp.Interpreter.Execution.VM
 			{
 				if (i >= numargs)
 				{
-					m_Scope.Assign(I.SymbolList[i], new RValue());
+					this.AssignGenericSymbol(I.SymbolList[i], new RValue());
 				}
 				else
 				{
-					m_Scope.Assign(I.SymbolList[i], m_ValueStack.Peek(numargs - i).CloneAsWritable());
+					this.AssignGenericSymbol(I.SymbolList[i], m_ValueStack.Peek(numargs - i).CloneAsWritable());
 				}
 			}
 		}
@@ -370,7 +368,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 					Debug_EntryPoint = fn.Function.ByteCodeLocation
 				});
 				m_InstructionPtr = fn.Function.ByteCodeLocation;
-				fn.Function.EnterClosureBeforeCall(m_Scope);
+				this.EnterClosure(fn.Function.ClosureContext);
 			}
 			else
 			{
@@ -546,7 +544,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 			}
 			else
 			{
-				m_Scope.Assign(l, r.ToSimplestValue());
+				this.AssignGenericSymbol(l, r.ToSimplestValue());
 			}
 		}
 
@@ -608,7 +606,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		private void ExecSymStorN(Instruction i)
 		{
-			m_Scope.Assign(i.Symbol, m_ValueStack.Peek());
+			this.AssignGenericSymbol(i.Symbol, m_ValueStack.Peek());
 		}
 
 

+ 148 - 0
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_Scope.cs

@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.DataStructs;
+
+namespace MoonSharp.Interpreter.Execution.VM
+{
+	sealed partial class Processor
+	{
+
+		public void EnterClosure(ClosureContext closureValues)
+		{
+			m_ClosureStack.Push(closureValues);
+		}
+
+		public void LeaveClosure()
+		{
+			m_ClosureStack.RemoveLast();
+		}
+
+		private void NilifyBlockData(RuntimeScopeBlock runtimeScopeBlock)
+		{
+			int from = runtimeScopeBlock.From;
+			int to = runtimeScopeBlock.To;
+
+			var array = this.m_ExecutionStack.Peek().LocalScope;
+
+			if (to >= 0 && from >= 0)
+			{
+				for (int i = from; i <= to; i++)
+					array[i] = new RValue();
+			}
+		}
+
+		private void ClearBlockData(RuntimeScopeBlock runtimeScopeBlock, bool clearToInclusive)
+		{
+			int from = runtimeScopeBlock.From;
+			int to = clearToInclusive ? runtimeScopeBlock.ToInclusive : runtimeScopeBlock.To;
+
+			var array = this.m_ExecutionStack.Peek().LocalScope;
+
+			if (to >= 0 && from >= 0)
+			{
+				Array.Clear(array, from, to - from + 1);
+			}
+		}
+
+
+		public RValue GetGenericSymbol(LRef symref)
+		{
+			switch (symref.i_Type)
+			{
+				case LRefType.Global:
+					return m_GlobalTable[symref.i_Name];
+				case LRefType.Local:
+					return m_ExecutionStack.Peek().LocalScope[symref.i_Index];
+				case LRefType.Upvalue:
+					List<RValue> closureValues = m_ClosureStack.Count > 0 ? m_ClosureStack[m_ClosureStack.Count - 1] : null;
+
+					if (closureValues != null)
+					{
+						return closureValues[symref.i_Index];
+					}
+					else
+					{
+						throw new ScriptRuntimeException(null, "Invalid upvalue at resolution: {0}", symref.i_Name);
+					}
+				case LRefType.Index:
+				case LRefType.Invalid:
+				default:
+					throw new InternalErrorException("Unexpected {0} LRef at resolution: {1}", symref.i_Type, symref.i_Name);
+			}
+		}
+
+		public void AssignGenericSymbol(LRef symref, RValue value)
+		{
+			switch (symref.i_Type)
+			{
+				case LRefType.Global:
+					m_GlobalTable[symref.i_Name] = value.CloneAsWritable();
+					break;
+				case LRefType.Local:
+					{
+						var stackframe = m_ExecutionStack.Peek();
+
+						RValue v = stackframe.LocalScope[symref.i_Index];
+						if (v == null)
+							stackframe.LocalScope[symref.i_Index] = v = new RValue();
+
+						v.Assign(value);
+					}
+					break;
+				case LRefType.Upvalue:
+					{
+						List<RValue> closureValues = m_ClosureStack.Count > 0 ? m_ClosureStack[m_ClosureStack.Count - 1] : null;
+
+						if (closureValues != null)
+						{
+							closureValues[symref.i_Index].Assign(value);
+						}
+						else
+						{
+							throw new ScriptRuntimeException(null, "Invalid upvalue at resolution: {0}", symref.i_Name);
+						}
+					}
+					break;
+				case LRefType.Index:
+				case LRefType.Invalid:
+				default:
+					throw new InternalErrorException("Unexpected {0} LRef at resolution: {1}", symref.i_Type, symref.i_Name);
+			}
+		}
+
+		public LRef FindRefByName(string name)
+		{
+			var stackframe = m_ExecutionStack.Peek();
+
+			if (stackframe.Debug_Symbols != null)
+			{
+				for (int i = stackframe.Debug_Symbols.Length - 1; i >= 0; i--)
+				{
+					var l = stackframe.Debug_Symbols[i];
+
+					if (l.i_Name == name && stackframe.LocalScope[i] != null)
+						return l;
+				}
+			}
+
+			if (m_ClosureStack.Count > 0)
+			{
+				var closure = m_ClosureStack.Peek(0);
+
+				for (int i = 0; i < closure.Symbols.Length; i++)
+					if (closure.Symbols[i] == name)
+					{
+						return LRef.Upvalue(name, i);
+					}
+			}
+
+			if (m_GlobalTable.HasStringSymbol(name))
+				return LRef.Global(name);
+
+			return null;
+		}
+
+	}
+}

+ 11 - 4
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -75,6 +75,7 @@
   <ItemGroup>
     <Compile Include="CoreLib\BasicMethods.cs" />
     <Compile Include="CoreLib\MetaTableMethods.cs" />
+    <Compile Include="DataStructs\Extension_Methods.cs" />
     <Compile Include="DataStructs\FastStackDynamic.cs" />
     <Compile Include="DataStructs\Slice.cs" />
     <Compile Include="Debugging\DebuggerAction.cs" />
@@ -92,13 +93,18 @@
     <Compile Include="Execution\DataTypes\CallbackFunction.cs" />
     <Compile Include="Execution\Scopes\ClosureContext.cs" />
     <Compile Include="Execution\Scopes\LoopTracker.cs" />
-    <Compile Include="Execution\Scopes\BuildTimeScope.cs" />
-    <Compile Include="Execution\Scopes\BuildTimeScopeFrame.cs" />
+    <Compile Include="Execution\Scopes\OldScopeClasses\BuildTimeScope.cs" />
+    <Compile Include="Execution\Scopes\OldScopeClasses\BuildTimeScopeFrame.cs" />
     <Compile Include="Execution\Scopes\IClosureBuilder.cs" />
     <Compile Include="Execution\DataTypes\LRefType.cs" />
-    <Compile Include="Execution\Scopes\RuntimeScope.cs" />
-    <Compile Include="Execution\Scopes\RuntimeScopeFrame.cs" />
+    <Compile Include="Execution\Scopes\OldScopeClasses\RuntimeScope.cs" />
+    <Compile Include="Execution\Scopes\OldScopeClasses\RuntimeScopeFrame.cs" />
     <Compile Include="Execution\DataTypes\LRef.cs" />
+    <Compile Include="Execution\Scopes\BuildTimeScope.cs" />
+    <Compile Include="Execution\Scopes\BuildTimeScopeBlock.cs" />
+    <Compile Include="Execution\Scopes\BuildTimeScopeFrame.cs" />
+    <Compile Include="Execution\Scopes\RuntimeScopeBlock.cs" />
+    <Compile Include="Execution\Scopes\RuntimeScopeFrame.cs" />
     <Compile Include="Execution\ScriptLoadingContext.cs" />
     <Compile Include="Execution\DataTypes\DataType.cs" />
     <Compile Include="Execution\DataTypes\RValue.cs" />
@@ -115,6 +121,7 @@
     </Compile>
     <Compile Include="Execution\VM\Processor\Processor_Debugger.cs" />
     <Compile Include="Execution\VM\Processor\Processor_InstructionLoop.cs" />
+    <Compile Include="Execution\VM\Processor\Processor_Scope.cs" />
     <Compile Include="Execution\VM\Processor\Processor_UtilityFunctions.cs" />
     <Compile Include="Grammar\Lua.g4.lexer.cs">
       <DependentUpon>Lua.g4</DependentUpon>

+ 2 - 5
src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

@@ -77,7 +77,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 			m_Statement = NodeFactory.CreateStatement(context.block(), lcontext);
 
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopFunction();
 
 			lcontext.Scope.LeaveClosure();
 		}
@@ -101,15 +101,12 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 			Instruction I = bc.Jump(OpCode.Jump, -1);
 
-			bc.DebugFn(friendlyName ?? "<anonymous>");
-
-			bc.Enter(m_StackFrame);
+			bc.BeginFn(m_StackFrame, friendlyName ?? "<anonymous>");
 
 			if (m_ParamNames.Length > 0)
 				bc.Args(m_ParamNames);
 
 			m_Statement.Compile(bc);
-			bc.Leave(m_StackFrame);
 
 			bc.ExitClsr();
 

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Loop.cs

@@ -9,7 +9,7 @@ namespace MoonSharp.Interpreter.Tree
 {
 	internal class Loop : ILoop
 	{
-		public RuntimeScopeFrame Scope;
+		public RuntimeScopeBlock Scope;
 		public List<Instruction> BreakJumps = new List<Instruction>();
 
 		public void CompileBreak(Chunk bc)

+ 4 - 4
src/MoonSharp.Interpreter/Tree/NodeBase.cs

@@ -41,10 +41,10 @@ namespace MoonSharp.Interpreter.Tree
 				throw  RuntimeError(format, args);
 		}
 
-		public virtual void Compile(Chunk bc)
-		{
-			bc.Invalid(this.GetType().Name);
-		}
+		public abstract void Compile(Chunk bc);
+
+
+
 
 	}
 }

+ 4 - 3
src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs

@@ -17,14 +17,15 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		{
 			lcontext.Scope.PushFunction();
 			m_Block = NodeFactory.CreateStatement(context.block(), lcontext);
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopFunction();
 		}
 
 		public override void Compile(Execution.VM.Chunk bc)
 		{
-			bc.Enter(m_StackFrame);
+			bc.BeginFn(m_StackFrame, "<chunk-root>");
 			m_Block.Compile(bc);
-			bc.Leave(m_StackFrame);
+			bc.Ret(0);
+			//bc.Leave(m_StackFrame);
 		}
 
 	}

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/ForEachLoopStatement.cs

@@ -10,7 +10,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 {
 	class ForEachLoopStatement : Statement
 	{
-		RuntimeScopeFrame m_StackFrame;
+		RuntimeScopeBlock m_StackFrame;
 		LRef[] m_Names;
 		Expression m_RValues;
 		Statement m_Block;
@@ -34,7 +34,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			
 			m_Block = NodeFactory.CreateStatement(context.block(), lcontext);
 
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 
 		public override void Compile(Chunk bc)

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/ForLoopStatement.cs

@@ -12,7 +12,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	class ForLoopStatement : Statement
 	{
 		//for' NAME '=' exp ',' exp (',' exp)? 'do' block 'end'
-		RuntimeScopeFrame m_StackFrame;
+		RuntimeScopeBlock m_StackFrame;
 		Statement m_InnerBlock;
 		LRef m_VarName;
 		Expression m_Start, m_End, m_Step;
@@ -33,7 +33,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			lcontext.Scope.PushBlock();
 			m_VarName = lcontext.Scope.DefineLocal(context.NAME().GetText());
 			m_InnerBlock = NodeFactory.CreateStatement(context.block(), lcontext);
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 
 		public override void Compile(Chunk bc)

+ 10 - 1
src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs

@@ -72,7 +72,16 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 		public override void Compile(Execution.VM.Chunk bc)
 		{
-			if (m_Local || m_MethodName == null)
+			if (m_Local)
+			{
+				bc.Symbol(m_FuncName);
+				bc.Literal(RValue.Nil);
+				bc.Store();
+				bc.Symbol(m_FuncName);
+				m_FuncDef.Compile(bc, () => bc.Store(), m_FriendlyName);
+				return;
+			}
+			else if (m_MethodName == null)
 			{
 				bc.Symbol(m_FuncName);
 				m_FuncDef.Compile(bc, () => bc.Store(), m_FriendlyName);

+ 4 - 4
src/MoonSharp.Interpreter/Tree/Statements/IfStatement.cs

@@ -15,12 +15,12 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		{
 			public Expression Exp;
 			public Statement Block;
-			public RuntimeScopeFrame StackFrame;
+			public RuntimeScopeBlock StackFrame;
 		}
 
 		List<IfBlock> m_Ifs = new List<IfBlock>();
 		Statement m_Else = null;
-		RuntimeScopeFrame m_ElseStackFrame;
+		RuntimeScopeBlock m_ElseStackFrame;
 
 
 		public IfStatement(LuaParser.Stat_ifblockContext context, ScriptLoadingContext lcontext)
@@ -36,7 +36,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 				lcontext.Scope.PushBlock();
 				var ifblock = new IfBlock() { Exp = NodeFactory.CreateExpression(exp, lcontext), Block = NodeFactory.CreateStatement(blk, lcontext) };
-				ifblock.StackFrame = lcontext.Scope.Pop();
+				ifblock.StackFrame = lcontext.Scope.PopBlock();
 
 				m_Ifs.Add(ifblock);
 			}
@@ -45,7 +45,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			{
 				lcontext.Scope.PushBlock();
 				m_Else = NodeFactory.CreateStatement(context.block()[bcount - 1], lcontext);
-				m_ElseStackFrame = lcontext.Scope.Pop();
+				m_ElseStackFrame = lcontext.Scope.PopBlock();
 			}
 		}
 

+ 5 - 0
src/MoonSharp.Interpreter/Tree/Statements/LabelStatement.cs

@@ -16,5 +16,10 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		{
 			Label = context.label().NAME().GetText();
 		}
+
+		public override void Compile(Execution.VM.Chunk bc)
+		{
+			throw new NotImplementedException();
+		}
 	}
 }

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Statements/LocalAssignmentStatement.cs

@@ -31,7 +31,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 			m_Names = context.namelist().NAME()
 				.Select(n => n.GetText())
-				.Select(n => lcontext.Scope.DefineLocal(n))
+				.Select(n => lcontext.Scope.TryDefineLocal(n))
 				.ToArray();
 		}
 

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/RepeatStatement.cs

@@ -12,7 +12,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	{
 		Expression m_Condition;
 		Statement m_Block;
-		RuntimeScopeFrame m_StackFrame;
+		RuntimeScopeBlock m_StackFrame;
 
 		public RepeatStatement(LuaParser.Stat_repeatuntilloopContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
@@ -20,7 +20,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 			lcontext.Scope.PushBlock();
 			m_Block = NodeFactory.CreateStatement(context.block(), lcontext);
 			m_Condition = NodeFactory.CreateExpression(context.exp(), lcontext);
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 
 

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs

@@ -24,7 +24,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		public override void Compile(Execution.VM.Chunk bc)
 		{
 			m_Expression.Compile(bc);
-			bc.Exit();
+			//bc.Exit();
 			bc.Ret(1);
 		}
 	}

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/ScopeBlockStatement.cs

@@ -10,14 +10,14 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	class ScopeBlockStatement : Statement
 	{
 		Statement m_Block;
-		RuntimeScopeFrame m_StackFrame;
+		RuntimeScopeBlock m_StackFrame;
 
 		public ScopeBlockStatement(LuaParser.Stat_doblockContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
 		{
 			lcontext.Scope.PushBlock();
 			m_Block = NodeFactory.CreateStatement(context.block(), lcontext);
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 
 		public override void Compile(Execution.VM.Chunk bc)

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/WhileStatement.cs

@@ -12,7 +12,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 	{
 		Expression m_Condition;
 		Statement m_Block;
-		RuntimeScopeFrame m_StackFrame;
+		RuntimeScopeBlock m_StackFrame;
 
 		public WhileStatement(LuaParser.Stat_whiledoloopContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
@@ -21,7 +21,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 
 			lcontext.Scope.PushBlock();
 			m_Block = NodeFactory.CreateStatement(context.block(), lcontext);
-			m_StackFrame = lcontext.Scope.Pop();
+			m_StackFrame = lcontext.Scope.PopBlock();
 		}
 
 

+ 11 - 2
src/PerformanceComparison/Program.cs

@@ -1,4 +1,6 @@
-using System;
+#define PROFILER
+
+using System;
 using System.Collections.Generic;
 using MoonSharp.Interpreter.Diagnostics;
 using System.IO;
@@ -13,13 +15,17 @@ namespace PerformanceComparison
 {
 	class Program
 	{
+#if PROFILER
+		const int ITERATIONS = 10;
+#else
 		const int ITERATIONS = 1;
+#endif
 
 		static  string scriptText = @"
 			function move(n, src, dst, via)
 				if n > 0 then
 					move(n - 1, src, via, dst)
-					print(src, 'to', dst)
+					--print(src, 'to', dst)
 					move(n - 1, via, dst, src)
 				end
 			end
@@ -154,6 +160,7 @@ end
 
 			File.WriteAllText(@"c:\temp\hanoi.lua", scriptText);
 
+#if !PROFILER
 
 			var fn = lua.LoadFile(@"c:\temp\hanoi.lua");
 
@@ -164,6 +171,8 @@ end
 			}
 			sw.Stop();
 
+#endif
+
 			Console.WriteLine("NLua  : {0} ms", sw.ElapsedMilliseconds);
 
 			Console.WriteLine("M# == NL ? {0}", g_MoonSharpStr.ToString() == g_NLuaStr.ToString());