Xanathar 11 år sedan
förälder
incheckning
d457b98a13

+ 158 - 138
src/MoonSharp.Debugger/MainForm.Designer.cs

@@ -64,11 +64,6 @@
 			this.splitContainer2 = new System.Windows.Forms.SplitContainer();
 			this.tabControl2 = new System.Windows.Forms.TabControl();
 			this.tabPage3 = new System.Windows.Forms.TabPage();
-			this.lvWatches = new MoonSharp.Debugger.DoubleBufferedListView();
-			this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
 			this.toolStrip2 = new System.Windows.Forms.ToolStrip();
 			this.btnAddWatch = new System.Windows.Forms.ToolStripButton();
 			this.btnRemoveWatch = new System.Windows.Forms.ToolStripButton();
@@ -77,10 +72,6 @@
 			this.toolGoToCodeWatches = new System.Windows.Forms.ToolStripButton();
 			this.label3 = new System.Windows.Forms.Label();
 			this.tabPage4 = new System.Windows.Forms.TabPage();
-			this.lvVStack = new MoonSharp.Debugger.DoubleBufferedListView();
-			this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
 			this.toolStrip3 = new System.Windows.Forms.ToolStrip();
 			this.btnViewVStk = new System.Windows.Forms.ToolStripButton();
 			this.toolGoToCodeVStack = new System.Windows.Forms.ToolStripButton();
@@ -88,18 +79,29 @@
 			this.imageList1 = new System.Windows.Forms.ImageList(this.components);
 			this.tabControl1 = new System.Windows.Forms.TabControl();
 			this.tabPage1 = new System.Windows.Forms.TabPage();
-			this.lvCallStack = new MoonSharp.Debugger.DoubleBufferedListView();
-			this.colAddress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.colName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.colReturn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
-			this.colBP = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
 			this.toolStrip4 = new System.Windows.Forms.ToolStrip();
 			this.toolGoToCodeXStack = new System.Windows.Forms.ToolStripButton();
 			this.tabPage2 = new System.Windows.Forms.TabPage();
 			this.label1 = new System.Windows.Forms.Label();
 			this.splitContainer3 = new System.Windows.Forms.SplitContainer();
-			this.codeView = new MoonSharp.Debugger.SourceCodeDebugControl();
 			this.txtOutput = new System.Windows.Forms.TextBox();
+			this.btnFollow = new System.Windows.Forms.ToolStripButton();
+			this.timerFollow = new System.Windows.Forms.Timer(this.components);
+			this.lvWatches = new MoonSharp.Debugger.DoubleBufferedListView();
+			this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.lvVStack = new MoonSharp.Debugger.DoubleBufferedListView();
+			this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.lvCallStack = new MoonSharp.Debugger.DoubleBufferedListView();
+			this.colAddress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.colName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.colReturn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.colBP = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+			this.codeView = new MoonSharp.Debugger.SourceCodeDebugControl();
 			this.menuStrip1.SuspendLayout();
 			this.toolStrip1.SuspendLayout();
 			this.splitContainer1.Panel1.SuspendLayout();
@@ -280,7 +282,8 @@
             this.toolStepOver,
             this.toolStepIN,
             this.toolStripSeparator3,
-            this.toolStripButton5});
+            this.toolStripButton5,
+            this.btnFollow});
 			this.toolStrip1.Location = new System.Drawing.Point(0, 24);
 			this.toolStrip1.Name = "toolStrip1";
 			this.toolStrip1.Size = new System.Drawing.Size(1094, 25);
@@ -439,45 +442,6 @@
 			this.tabPage3.Text = "Watches";
 			this.tabPage3.UseVisualStyleBackColor = true;
 			// 
-			// lvWatches
-			// 
-			this.lvWatches.BackColor = System.Drawing.SystemColors.Window;
-			this.lvWatches.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
-            this.columnHeader1,
-            this.columnHeader2,
-            this.columnHeader3,
-            this.columnHeader4});
-			this.lvWatches.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.lvWatches.FullRowSelect = true;
-			this.lvWatches.GridLines = true;
-			this.lvWatches.Location = new System.Drawing.Point(3, 28);
-			this.lvWatches.Name = "lvWatches";
-			this.lvWatches.Size = new System.Drawing.Size(350, 249);
-			this.lvWatches.TabIndex = 4;
-			this.lvWatches.UseCompatibleStateImageBehavior = false;
-			this.lvWatches.View = System.Windows.Forms.View.Details;
-			this.lvWatches.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvWatches_MouseDoubleClick);
-			// 
-			// columnHeader1
-			// 
-			this.columnHeader1.Text = "Name";
-			this.columnHeader1.Width = 72;
-			// 
-			// columnHeader2
-			// 
-			this.columnHeader2.Text = "Type";
-			this.columnHeader2.Width = 57;
-			// 
-			// columnHeader3
-			// 
-			this.columnHeader3.Text = "Value";
-			this.columnHeader3.Width = 111;
-			// 
-			// columnHeader4
-			// 
-			this.columnHeader4.Text = "Symbol loc.";
-			this.columnHeader4.Width = 72;
-			// 
 			// toolStrip2
 			// 
 			this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -558,39 +522,6 @@
 			this.tabPage4.Text = "V-Stack";
 			this.tabPage4.UseVisualStyleBackColor = true;
 			// 
-			// lvVStack
-			// 
-			this.lvVStack.BackColor = System.Drawing.SystemColors.Window;
-			this.lvVStack.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
-            this.columnHeader5,
-            this.columnHeader6,
-            this.columnHeader7});
-			this.lvVStack.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.lvVStack.FullRowSelect = true;
-			this.lvVStack.GridLines = true;
-			this.lvVStack.Location = new System.Drawing.Point(3, 28);
-			this.lvVStack.Name = "lvVStack";
-			this.lvVStack.Size = new System.Drawing.Size(350, 249);
-			this.lvVStack.TabIndex = 7;
-			this.lvVStack.UseCompatibleStateImageBehavior = false;
-			this.lvVStack.View = System.Windows.Forms.View.Details;
-			this.lvVStack.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvVStack_MouseDoubleClick);
-			// 
-			// columnHeader5
-			// 
-			this.columnHeader5.Text = "Stack ofs";
-			this.columnHeader5.Width = 72;
-			// 
-			// columnHeader6
-			// 
-			this.columnHeader6.Text = "Type";
-			this.columnHeader6.Width = 94;
-			// 
-			// columnHeader7
-			// 
-			this.columnHeader7.Text = "Value";
-			this.columnHeader7.Width = 157;
-			// 
 			// toolStrip3
 			// 
 			this.toolStrip3.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -665,44 +596,6 @@
 			this.tabPage1.Text = "Call Stack";
 			this.tabPage1.UseVisualStyleBackColor = true;
 			// 
-			// lvCallStack
-			// 
-			this.lvCallStack.BackColor = System.Drawing.SystemColors.Window;
-			this.lvCallStack.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
-            this.colAddress,
-            this.colName,
-            this.colReturn,
-            this.colBP});
-			this.lvCallStack.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.lvCallStack.FullRowSelect = true;
-			this.lvCallStack.GridLines = true;
-			this.lvCallStack.Location = new System.Drawing.Point(3, 28);
-			this.lvCallStack.Name = "lvCallStack";
-			this.lvCallStack.Size = new System.Drawing.Size(350, 294);
-			this.lvCallStack.TabIndex = 8;
-			this.lvCallStack.UseCompatibleStateImageBehavior = false;
-			this.lvCallStack.View = System.Windows.Forms.View.Details;
-			// 
-			// colAddress
-			// 
-			this.colAddress.Text = "Address";
-			this.colAddress.Width = 72;
-			// 
-			// colName
-			// 
-			this.colName.Text = "Name";
-			this.colName.Width = 106;
-			// 
-			// colReturn
-			// 
-			this.colReturn.Text = "Return";
-			this.colReturn.Width = 72;
-			// 
-			// colBP
-			// 
-			this.colBP.Text = "Base Ptr";
-			this.colBP.Width = 72;
-			// 
 			// toolStrip4
 			// 
 			this.toolStrip4.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -763,6 +656,143 @@
 			this.splitContainer3.SplitterDistance = 446;
 			this.splitContainer3.TabIndex = 0;
 			// 
+			// txtOutput
+			// 
+			this.txtOutput.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+			this.txtOutput.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.txtOutput.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
+			this.txtOutput.Location = new System.Drawing.Point(0, 0);
+			this.txtOutput.Multiline = true;
+			this.txtOutput.Name = "txtOutput";
+			this.txtOutput.ReadOnly = true;
+			this.txtOutput.Size = new System.Drawing.Size(726, 213);
+			this.txtOutput.TabIndex = 0;
+			// 
+			// btnFollow
+			// 
+			this.btnFollow.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+			this.btnFollow.Image = ((System.Drawing.Image)(resources.GetObject("btnFollow.Image")));
+			this.btnFollow.ImageTransparentColor = System.Drawing.Color.Magenta;
+			this.btnFollow.Name = "btnFollow";
+			this.btnFollow.Size = new System.Drawing.Size(46, 22);
+			this.btnFollow.Text = "Follow";
+			this.btnFollow.Click += new System.EventHandler(this.btnFollow_Click);
+			// 
+			// timerFollow
+			// 
+			this.timerFollow.Interval = 50;
+			this.timerFollow.Tick += new System.EventHandler(this.timerFollow_Tick);
+			// 
+			// lvWatches
+			// 
+			this.lvWatches.BackColor = System.Drawing.SystemColors.Window;
+			this.lvWatches.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.columnHeader1,
+            this.columnHeader2,
+            this.columnHeader3,
+            this.columnHeader4});
+			this.lvWatches.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.lvWatches.FullRowSelect = true;
+			this.lvWatches.GridLines = true;
+			this.lvWatches.Location = new System.Drawing.Point(3, 28);
+			this.lvWatches.Name = "lvWatches";
+			this.lvWatches.Size = new System.Drawing.Size(350, 249);
+			this.lvWatches.TabIndex = 4;
+			this.lvWatches.UseCompatibleStateImageBehavior = false;
+			this.lvWatches.View = System.Windows.Forms.View.Details;
+			this.lvWatches.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvWatches_MouseDoubleClick);
+			// 
+			// columnHeader1
+			// 
+			this.columnHeader1.Text = "Name";
+			this.columnHeader1.Width = 72;
+			// 
+			// columnHeader2
+			// 
+			this.columnHeader2.Text = "Type";
+			this.columnHeader2.Width = 57;
+			// 
+			// columnHeader3
+			// 
+			this.columnHeader3.Text = "Value";
+			this.columnHeader3.Width = 111;
+			// 
+			// columnHeader4
+			// 
+			this.columnHeader4.Text = "Symbol loc.";
+			this.columnHeader4.Width = 72;
+			// 
+			// lvVStack
+			// 
+			this.lvVStack.BackColor = System.Drawing.SystemColors.Window;
+			this.lvVStack.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.columnHeader5,
+            this.columnHeader6,
+            this.columnHeader7});
+			this.lvVStack.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.lvVStack.FullRowSelect = true;
+			this.lvVStack.GridLines = true;
+			this.lvVStack.Location = new System.Drawing.Point(3, 28);
+			this.lvVStack.Name = "lvVStack";
+			this.lvVStack.Size = new System.Drawing.Size(350, 249);
+			this.lvVStack.TabIndex = 7;
+			this.lvVStack.UseCompatibleStateImageBehavior = false;
+			this.lvVStack.View = System.Windows.Forms.View.Details;
+			this.lvVStack.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvVStack_MouseDoubleClick);
+			// 
+			// columnHeader5
+			// 
+			this.columnHeader5.Text = "Stack ofs";
+			this.columnHeader5.Width = 72;
+			// 
+			// columnHeader6
+			// 
+			this.columnHeader6.Text = "Type";
+			this.columnHeader6.Width = 94;
+			// 
+			// columnHeader7
+			// 
+			this.columnHeader7.Text = "Value";
+			this.columnHeader7.Width = 157;
+			// 
+			// lvCallStack
+			// 
+			this.lvCallStack.BackColor = System.Drawing.SystemColors.Window;
+			this.lvCallStack.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.colAddress,
+            this.colName,
+            this.colReturn,
+            this.colBP});
+			this.lvCallStack.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.lvCallStack.FullRowSelect = true;
+			this.lvCallStack.GridLines = true;
+			this.lvCallStack.Location = new System.Drawing.Point(3, 28);
+			this.lvCallStack.Name = "lvCallStack";
+			this.lvCallStack.Size = new System.Drawing.Size(350, 294);
+			this.lvCallStack.TabIndex = 8;
+			this.lvCallStack.UseCompatibleStateImageBehavior = false;
+			this.lvCallStack.View = System.Windows.Forms.View.Details;
+			// 
+			// colAddress
+			// 
+			this.colAddress.Text = "Address";
+			this.colAddress.Width = 72;
+			// 
+			// colName
+			// 
+			this.colName.Text = "Name";
+			this.colName.Width = 106;
+			// 
+			// colReturn
+			// 
+			this.colReturn.Text = "Return";
+			this.colReturn.Width = 72;
+			// 
+			// colBP
+			// 
+			this.colBP.Text = "Base Ptr";
+			this.colBP.Width = 72;
+			// 
 			// codeView
 			// 
 			this.codeView.ActiveLine = -1;
@@ -778,18 +808,6 @@
 			this.codeView.SourceCode = null;
 			this.codeView.TabIndex = 1;
 			// 
-			// txtOutput
-			// 
-			this.txtOutput.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
-			this.txtOutput.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.txtOutput.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
-			this.txtOutput.Location = new System.Drawing.Point(0, 0);
-			this.txtOutput.Multiline = true;
-			this.txtOutput.Name = "txtOutput";
-			this.txtOutput.ReadOnly = true;
-			this.txtOutput.Size = new System.Drawing.Size(726, 213);
-			this.txtOutput.TabIndex = 0;
-			// 
 			// MainForm
 			// 
 			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -909,6 +927,8 @@
 		private System.Windows.Forms.ColumnHeader colBP;
 		private System.Windows.Forms.ToolStrip toolStrip4;
 		private System.Windows.Forms.ToolStripButton toolGoToCodeXStack;
+		private System.Windows.Forms.ToolStripButton btnFollow;
+		private System.Windows.Forms.Timer timerFollow;
 
 
 	}

+ 20 - 0
src/MoonSharp.Debugger/MainForm.cs

@@ -147,11 +147,20 @@ namespace MoonSharp.Debugger
 
 		void DebugAction(DebuggerAction action)
 		{
+			bool savedState = timerFollow.Enabled;
+			timerFollow.Enabled = false;
+
 			m_NextAction = action;
 			m_WaitLock.Set();
 
 			if (!m_WaitBack.WaitOne(1000))
+			{
 				MessageBox.Show(this, "Operation timed out", "Timeout");
+			}
+			else
+			{
+				timerFollow.Enabled = true;
+			}
 		}
 
 
@@ -163,6 +172,7 @@ namespace MoonSharp.Debugger
 			}
 			catch (Exception ex)
 			{
+				timerFollow.Enabled = false;
 				Console_WriteLine("Guest raised unhandled CLR exception: {0}\n{1}\n", ex.GetType(), ex.ToString());
 			}
 		}
@@ -366,6 +376,16 @@ namespace MoonSharp.Debugger
 			codeView.CursorLine = code;
 		}
 
+		private void timerFollow_Tick(object sender, EventArgs e)
+		{
+			toolStepIN.PerformClick();
+		}
+
+		private void btnFollow_Click(object sender, EventArgs e)
+		{
+			timerFollow.Start();
+		}
+
 
 
 	}

+ 62 - 49
src/MoonSharp.Debugger/MainForm.resx

@@ -123,6 +123,22 @@
   <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>132, 17</value>
   </metadata>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="btnFollow.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
+        YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
+        0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
+        bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
+        VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
+        c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
+        Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
+        mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
+        kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
+        TgDQASA1MVpwzwAAAABJRU5ErkJggg==
+</value>
+  </data>
   <metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>237, 17</value>
   </metadata>
@@ -140,57 +156,57 @@
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACe
-        DQAAAk1TRnQBSQFMAgEBBAEAASABAQEgAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+        DQAAAk1TRnQBSQFMAgEBBAEAATABAQEwAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
         AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AIgADDAEQA1kBvwP2
         Af8D9gH/A1kBvwMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAEAAD9gH/
-        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/5AAA1kBvwOcAf8DHgH/Ax4B/wP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/xAAA/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wP2Af+QAAP2Af8DHgH/Ax4B/wMeAf8D9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMe
-        Af8DHgH/Ax4B/wP2Af8QAAP2Af8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/FAAD9gH/A/YB/wP2
+        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/5AAA1kBvwOcAf8DHAH/AxwB/wP2Af8D9gH/A/YB/wP2
+        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/xAAA/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wP2Af+QAAP2Af8DHAH/AxwB/wMcAf8D9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMc
+        Af8DHAH/AxwB/wP2Af8QAAP2Af8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/FAAD9gH/A/YB/wP2
         Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8cAAP2Af8D9gH/A/YB/wP2Af8D9gH/CAADIQEwAyEBMAQA
-        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/Ax4B/wMeAf8DHgH/A/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/EAAD9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/xQA
-        A/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/HAAD9gH/Ax4B/wMeAf8DHgH/A/YB/wQA
-        AyEBMANiAe8DYgHvAyEBMAP2Af8DHgH/Ax4B/wMeAf8D9gH/A/YB/wMeAf8D9gH/A/YB/wP2Af8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wgAA/YB/wP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/DAAD9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wP2Af8cAAP2Af8DHgH/A/YB/wP2Af8D9gH/AyEBMANiAe8DhgH/A0AB/wNiAe8D9gH/A/YB/wP2
-        Af8DHgH/A/YB/wP2Af8DHgH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8IAAP2Af8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        A/YB/wwAA/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8UAAP2Af8DHgH/
-        A/YB/wQAAyEBMAM6AWADYgHvA4YB/wMeAf8DQAH/A2IB7wMhATAD9gH/Ax4B/wP2Af8D9gH/Ax4B/wP2
+        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/AxwB/wMcAf8DHAH/A/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/EAAD9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/xQA
+        A/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/HAAD9gH/AxwB/wMcAf8DHAH/A/YB/wQA
+        AyEBMANiAe8DYgHvAyEBMAP2Af8DHAH/AxwB/wMcAf8D9gH/A/YB/wMcAf8D9gH/A/YB/wP2Af8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wgAA/YB/wP2Af8D9gH/A/YB/wP2
+        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/DAAD9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wP2Af8cAAP2Af8DHAH/A/YB/wP2Af8D9gH/AyEBMANiAe8DhgH/Az4B/wNiAe8D9gH/A/YB/wP2
+        Af8DHAH/A/YB/wP2Af8DHAH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
+        Af8D9gH/A/YB/wP2Af8IAAP2Af8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        A/YB/wwAA/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8UAAP2Af8DHAH/
+        A/YB/wQAAyEBMAM6AWADYgHvA4YB/wMcAf8DPgH/A2IB7wMhATAD9gH/AxwB/wP2Af8D9gH/AxwB/wP2
         Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/CAAD9gH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wP2Af8UAAP2Af8DHgH/Ax4B/wMe
-        Af8DHgH/Ax4B/wMeAf8DHgH/A/YB/xQAA/YB/wMeAf8D9gH/AyEBMANiAe8DYgHvAzoBYANiAe8DhgH/
-        A0AB/wNiAe8DIQEwA/YB/wMeAf8D9gH/A/YB/wMeAf8D9gH/A/YB/wP2Af8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wgAA/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8D9gH/FAAD9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wP2Af8UAAP2
-        Af8DHgH/A/YB/wNiAe8DhgH/A0AB/wNiAe8DOgFgA2IB7wP2Af8DYgHvAyEBMAP2Af8DHgH/A/YB/wP2
-        Af8DHgH/Ax4B/wMeAf8D9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wP2
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wP2Af8UAAP2Af8DHAH/AxwB/wMc
+        Af8DHAH/AxwB/wMcAf8DHAH/A/YB/xQAA/YB/wMcAf8D9gH/AyEBMANiAe8DYgHvAzoBYANiAe8DhgH/
+        Az4B/wNiAe8DIQEwA/YB/wMcAf8D9gH/A/YB/wMcAf8D9gH/A/YB/wP2Af8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wgAA/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
+        Af8D9gH/A/YB/wP2Af8D9gH/FAAD9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wP2Af8UAAP2
+        Af8DHAH/A/YB/wNiAe8DhgH/Az4B/wNiAe8DOgFgA2IB7wP2Af8DYgHvAyEBMAP2Af8DHAH/A/YB/wP2
+        Af8DHAH/AxwB/wMcAf8D9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wP2
         Af8MAAP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8YAAP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wgAA/YB/wMeAf8D9gH/A4YB/wMeAf8DHgH/
-        A0AB/wNiAe8DYgHvA4YB/wNAAf8DYgHvA/YB/wMeAf8D9gH/A/YB/wMeAf8DHgH/Ax4B/wP2Af8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wwAA/YB/wMeAf8DHgH/Ax4B/wMe
-        Af8DHgH/Ax4B/wMeAf8DHgH/A/YB/xgAA/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wMeAf8DHgH/
-        Ax4B/wMeAf8D9gH/CAAD9gH/Ax4B/wP2Af8DhgH/Ax4B/wMeAf8DHgH/A0AB/wPrAf8DhgH/Ax4B/wNA
-        Af8D9gH/Ax4B/wP2Af8DWQG/A5wB/wMeAf8DHgH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
-        Af8D9gH/A/YB/wP2Af8D9gH/DAAD9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/
-        GAAD9gH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/Ax4B/wMeAf8DHgH/Ax4B/wP2Af8IAAP2Af8DHgH/
-        A/YB/wNiAe8DhgH/Ax4B/wMeAf8DQAH/A2IB7wNiAe8DhgH/A0AB/wP2Af8DHgH/A/YB/wMMARAD9gH/
+        Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wgAA/YB/wMcAf8D9gH/A4YB/wMcAf8DHAH/
+        Az4B/wNiAe8DYgHvA4YB/wM+Af8DYgHvA/YB/wMcAf8D9gH/A/YB/wMcAf8DHAH/AxwB/wP2Af8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wwAA/YB/wMcAf8DHAH/AxwB/wMc
+        Af8DHAH/AxwB/wMcAf8DHAH/A/YB/xgAA/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wMcAf8DHAH/
+        AxwB/wMcAf8D9gH/CAAD9gH/AxwB/wP2Af8DhgH/AxwB/wMcAf8DHAH/Az4B/wPrAf8DhgH/AxwB/wM+
+        Af8D9gH/AxwB/wP2Af8DWQG/A5wB/wMcAf8DHAH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2
+        Af8D9gH/A/YB/wP2Af8D9gH/DAAD9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/
+        GAAD9gH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/AxwB/wMcAf8DHAH/AxwB/wP2Af8IAAP2Af8DHAH/
+        A/YB/wNiAe8DhgH/AxwB/wMcAf8DPgH/A2IB7wNiAe8DhgH/Az4B/wP2Af8DHAH/A/YB/wMMARAD9gH/
         A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8MAAP2
         Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8QAAP2Af8D9gH/A/YB/wP2Af8D9gH/
-        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/CAAD9gH/Ax4B/wP2Af8DIQEwA2IB7wOG
-        Af8DQAH/A2IB7wMhATADIQEwA2IB7wNcAd8D9gH/Ax4B/wP2Af8EAAP2Af8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/
-        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8EAAP2Af8DHgH/Ax4B/wMe
-        Af8DHgH/Ax4B/wP2Af8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/CAAD9gH/Ax4B/wP2Af8D9gH/
-        A/YB/wNiAe8DYgHvAyEBMAgAA/YB/wP2Af8D9gH/Ax4B/wP2Af8EAAP2Af8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wP2Af8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wP2Af8EAAP2Af8DHgH/Ax4B/wMe
-        Af8DHgH/Ax4B/wP2Af8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/CAAD9gH/Ax4B/wMeAf8DHgH/
-        A/YB/wMhATADIQEwDAAD9gH/Ax4B/wMeAf8DHgH/A/YB/wQAA/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8D9gH/A/YB/wMeAf8DHgH/Ax4B/wMeAf8DHgH/
-        Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/Ax4B/wMeAf8DHgH/A/YB/wQAA/YB/wP2Af8D9gH/A/YB/wP2
+        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/CAAD9gH/AxwB/wP2Af8DIQEwA2IB7wOG
+        Af8DPgH/A2IB7wMhATADIQEwA2IB7wNcAd8D9gH/AxwB/wP2Af8EAAP2Af8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/
+        A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8EAAP2Af8DHAH/AxwB/wMc
+        Af8DHAH/AxwB/wP2Af8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/CAAD9gH/AxwB/wP2Af8D9gH/
+        A/YB/wNiAe8DYgHvAyEBMAgAA/YB/wP2Af8D9gH/AxwB/wP2Af8EAAP2Af8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wP2Af8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wP2Af8EAAP2Af8DHAH/AxwB/wMc
+        Af8DHAH/AxwB/wP2Af8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/CAAD9gH/AxwB/wMcAf8DHAH/
+        A/YB/wMhATADIQEwDAAD9gH/AxwB/wMcAf8DHAH/A/YB/wQAA/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8D9gH/A/YB/wMcAf8DHAH/AxwB/wMcAf8DHAH/
+        AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/AxwB/wMcAf8DHAH/A/YB/wQAA/YB/wP2Af8D9gH/A/YB/wP2
         Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8IAAP2Af8D9gH/A/YB/wP2Af8D9gH/
         FAAD9gH/A/YB/wP2Af8D9gH/A/YB/wQAA/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/
         A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/
@@ -204,10 +220,7 @@
   <metadata name="toolStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>673, 17</value>
   </metadata>
-  <metadata name="toolStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>463, 17</value>
-  </metadata>
-  <metadata name="toolStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>673, 17</value>
+  <metadata name="timerFollow.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>778, 17</value>
   </metadata>
 </root>

+ 1 - 1
src/MoonSharp.Interpreter/CoreLib/BasicMethods.cs

@@ -7,7 +7,7 @@ using MoonSharp.Interpreter.Execution;
 namespace MoonSharp.Interpreter.CoreLib
 {
 	[MoonSharpModule]
-	public static class BasicMethods
+	public class BasicMethods
 	{
 		//type (v)
 		//----------------------------------------------------------------------------------------------------------------

+ 24 - 1
src/MoonSharp.Interpreter/CoreLib/ErrorHandling.cs

@@ -2,10 +2,33 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.Execution.VM;
 
 namespace MoonSharp.Interpreter.CoreLib
 {
-	class ErrorHandling
+	[MoonSharpModule]
+	public class ErrorHandling
 	{
+		[MoonSharpMethod]
+		public static DynValue pcall(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			DynValue v = args[0];
+			DynValue[] a = new DynValue[args.Count - 1];
+
+			for (int i = 1; i < args.Count; i++)
+				a[i - 1] = args[i];
+
+			return DynValue.NewTailCallReq(new TailCallData()
+			{
+				Args = a,
+				Function = v,
+				Mode = CallMode.PCall
+			});
+		}
+
+
+
+
 	}
 }

+ 27 - 4
src/MoonSharp.Interpreter/DataTypes/DynValue.cs

@@ -6,6 +6,7 @@ using System.Linq;
 using System.Text;
 using System.Threading;
 using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.Execution.VM;
 
 namespace MoonSharp.Interpreter
 {
@@ -178,8 +179,8 @@ namespace MoonSharp.Interpreter
 		/// Creates a new request for a tail call. This is the preferred way to execute Lua/Moon# code from a callback,
 		/// although it's not always possible to use it. When a function (callback or script closure) returns a
 		/// TailCallRequest, the bytecode processor immediately executes the function contained in the request.
-		/// By executing script in this way, a callback function ensures it's not on the stack anymore and thus state
-		/// can be saved.
+		/// By executing script in this way, a callback function ensures it's not on the stack anymore and thus a number
+		/// of functionality (state savings, coroutines, etc) keeps working at full power.
 		/// </summary>
 		/// <param name="tailFn">The function to be called.</param>
 		/// <param name="args">The arguments.</param>
@@ -188,8 +189,30 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				UserObject = tailFn,
-				Tuple = args,
+				UserObject = new TailCallData()
+				{
+					Args = args,
+					Function = tailFn,
+					Mode = CallMode.Normal 
+				},
+				Type = DataType.TailCallRequest,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new request for a tail call. This is the preferred way to execute Lua/Moon# code from a callback,
+		/// although it's not always possible to use it. When a function (callback or script closure) returns a
+		/// TailCallRequest, the bytecode processor immediately executes the function contained in the request.
+		/// By executing script in this way, a callback function ensures it's not on the stack anymore and thus a number
+		/// of functionality (state savings, coroutines, etc) keeps working at full power.
+		/// </summary>
+		/// <param name="tailFn">The data for the tail call.</param>
+		/// <returns></returns>
+		public static DynValue NewTailCallReq(TailCallData tailCallData)
+		{
+			return new DynValue()
+			{
+				UserObject = tailCallData,
 				Type = DataType.TailCallRequest,
 			};
 		}

+ 15 - 0
src/MoonSharp.Interpreter/DataTypes/TailCallData.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Execution.VM;
+
+namespace MoonSharp.Interpreter
+{
+	public class TailCallData
+	{
+		public DynValue Function { get; set; }
+		public DynValue[] Args { get; set; }
+		public CallMode Mode { get; set; }
+	}
+}

+ 10 - 0
src/MoonSharp.Interpreter/Execution/VM/CallStackItem.cs

@@ -5,11 +5,21 @@ using System.Text;
 
 namespace MoonSharp.Interpreter.Execution.VM
 {
+	public enum CallMode
+	{
+		Normal,
+		PCall,
+		Require,
+	}
+
+
 	public class CallStackItem
 	{
 		public int Debug_EntryPoint;
 		public SymbolRef[] Debug_Symbols;
 
+		public CallMode Mode;
+
 		public int BasePointer;
 		public int ReturnAddress;
 		public DynValue[] LocalScope;

+ 240 - 180
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

@@ -11,177 +11,207 @@ namespace MoonSharp.Interpreter.Execution.VM
 	{
 		private DynValue Processing_Loop(int instructionPtr)
 		{
-			while (true)
-			{
-				Instruction i = m_RootChunk.Code[instructionPtr];
+			repeat_execution:
 
-				if (m_DebuggerAttached != null)
+			try
+			{
+				while (true)
 				{
-					ListenDebugger(i, instructionPtr);
+					Instruction i = m_RootChunk.Code[instructionPtr];
+
+					if (m_DebuggerAttached != null)
+					{
+						ListenDebugger(i, instructionPtr);
+					}
+
+					++instructionPtr;
+
+					switch (i.OpCode)
+					{
+						case OpCode.Nop:
+						case OpCode.Debug:
+							break;
+						case OpCode.Pop:
+							m_ValueStack.RemoveLast(i.NumVal);
+							break;
+						case OpCode.Copy:
+							m_ValueStack.Push(m_ValueStack.Peek(i.NumVal));
+							break;
+						case OpCode.Swap:
+							ExecSwap(i);
+							break;
+						case OpCode.Literal:
+							m_ValueStack.Push(i.Value);
+							break;
+						case OpCode.Add:
+							instructionPtr = ExecAdd(i, instructionPtr);
+							break;
+						case OpCode.Concat:
+							instructionPtr = ExecConcat(i, instructionPtr);
+							break;
+						case OpCode.Neg:
+							instructionPtr = ExecNeg(i, instructionPtr);
+							break;
+						case OpCode.Sub:
+							instructionPtr = ExecSub(i, instructionPtr);
+							break;
+						case OpCode.Mul:
+							instructionPtr = ExecMul(i, instructionPtr);
+							break;
+						case OpCode.Div:
+							instructionPtr = ExecDiv(i, instructionPtr);
+							break;
+						case OpCode.Mod:
+							instructionPtr = ExecMod(i, instructionPtr);
+							break;
+						case OpCode.Power:
+							instructionPtr = ExecPower(i, instructionPtr);
+							break;
+						case OpCode.Eq:
+							instructionPtr = ExecEq(i, instructionPtr);
+							break;
+						case OpCode.LessEq:
+							instructionPtr = ExecLessEq(i, instructionPtr);
+							break;
+						case OpCode.Less:
+							instructionPtr = ExecLess(i, instructionPtr);
+							break;
+						case OpCode.Len:
+							instructionPtr = ExecLen(i, instructionPtr);
+							break;
+						case OpCode.Call:
+							instructionPtr = Internal_ExecCall(i.NumVal, instructionPtr);
+							break;
+						case OpCode.Scalar:
+							m_ValueStack.Push(m_ValueStack.Pop().ToScalar());
+							break;
+						case OpCode.Not:
+							ExecNot(i);
+							break;
+						case OpCode.JfOrPop:
+						case OpCode.JtOrPop:
+							instructionPtr = ExecShortCircuitingOperator(i, instructionPtr);
+							break;
+						case OpCode.JNil:
+							{
+								DynValue v = m_ValueStack.Pop();
+
+								if (v.Type == DataType.Nil)
+									instructionPtr = i.NumVal;
+							}
+							break;
+						case OpCode.Jf:
+							instructionPtr = JumpBool(i, false, instructionPtr);
+							break;
+						case OpCode.Jump:
+							instructionPtr = i.NumVal;
+							break;
+						case OpCode.MkTuple:
+							ExecMkTuple(i);
+							break;
+						case OpCode.Enter:
+							NilifyBlockData(i);
+							break;
+						case OpCode.Leave:
+						case OpCode.Exit:
+							ClearBlockData(i);
+							break;
+						case OpCode.Closure:
+							ExecClosure(i);
+							break;
+						case OpCode.BeginFn:
+							ExecBeginFn(i);
+							break;
+						case OpCode.ToBool:
+							m_ValueStack.Push(DynValue.NewBoolean(m_ValueStack.Pop().CastToBool()));
+							break;
+						case OpCode.Args:
+							ExecArgs(i);
+							break;
+						case OpCode.Ret:
+							instructionPtr = ExecRet(i);
+							if (instructionPtr < 0)
+								goto return_to_native_code;
+							break;
+						case OpCode.Incr:
+							ExecIncr(i);
+							break;
+						case OpCode.ToNum:
+							ExecToNum(i);
+							break;
+						case OpCode.JFor:
+							instructionPtr = ExecJFor(i, instructionPtr);
+							break;
+						case OpCode.NewTable:
+							m_ValueStack.Push(DynValue.NewTable(this.m_Script));
+							break;
+						case OpCode.IterPrep:
+							ExecIterPrep(i);
+							break;
+						case OpCode.IterUpd:
+							ExecIterUpd(i);
+							break;
+						case OpCode.ExpTuple:
+							ExecExpTuple(i);
+							break;
+						case OpCode.Local:
+							m_ValueStack.Push(m_ExecutionStack.Peek().LocalScope[i.Symbol.i_Index]);
+							break;
+						case OpCode.Upvalue:
+							m_ValueStack.Push(m_ExecutionStack.Peek().ClosureScope[i.Symbol.i_Index]);
+							break;
+						case OpCode.StoreUpv:
+							ExecStoreUpv(i);
+							break;
+						case OpCode.StoreLcl:
+							ExecStoreLcl(i);
+							break;
+						case OpCode.TblInitN:
+							ExecTblInitN(i);
+							break;
+						case OpCode.TblInitI:
+							ExecTblInitI(i);
+							break;
+						case OpCode.Index:
+							instructionPtr = ExecIndex(i, instructionPtr);
+							break;
+						case OpCode.PushEnv:
+							m_ValueStack.Push(DynValue.NewTable(m_GlobalTable));
+							break;
+						case OpCode.IndexSet:
+							instructionPtr = ExecIndexSet(i, instructionPtr);
+							break;
+						case OpCode.Invalid:
+							throw new NotImplementedException(string.Format("Invalid opcode : {0}", i.Name));
+						default:
+							throw new NotImplementedException(string.Format("Execution for {0} not implented yet!", i.OpCode));
+					}
 				}
+			}
+			catch (ScriptRuntimeException ex)
+			{
+				while (m_ExecutionStack.Count > 0)
+				{
+					CallStackItem csi = PopToBasePointer();
+
+					CallMode mode = csi.Mode;
+					if (mode == CallMode.PCall)
+					{
+						instructionPtr = csi.ReturnAddress;
+						var argscnt = (int)(m_ValueStack.Pop().Number);
+						m_ValueStack.RemoveLast(argscnt + 1);
+
+						m_ValueStack.Push(DynValue.NewTuple(DynValue.False, DynValue.NewString(ex.Message)));
 
-				++instructionPtr;
+						goto repeat_execution;
+					}
+				}
 
-				switch (i.OpCode)
+				if (m_ExecutionStack.Count == 0)
 				{
-					case OpCode.Nop:
-					case OpCode.Debug:
-						break;
-					case OpCode.Pop:
-						m_ValueStack.RemoveLast(i.NumVal);
-						break;
-					case OpCode.Copy:
-						m_ValueStack.Push(m_ValueStack.Peek(i.NumVal));
-						break;
-					case OpCode.Swap:
-						ExecSwap(i);
-						break;
-					case OpCode.Literal:
-						m_ValueStack.Push(i.Value);
-						break;
-					case OpCode.Add:
-						instructionPtr = ExecAdd(i, instructionPtr);
-						break;
-					case OpCode.Concat:
-						instructionPtr = ExecConcat(i, instructionPtr);
-						break;
-					case OpCode.Neg:
-						instructionPtr = ExecNeg(i, instructionPtr);
-						break;
-					case OpCode.Sub:
-						instructionPtr = ExecSub(i, instructionPtr);
-						break;
-					case OpCode.Mul:
-						instructionPtr = ExecMul(i, instructionPtr);
-						break;
-					case OpCode.Div:
-						instructionPtr = ExecDiv(i, instructionPtr);
-						break;
-					case OpCode.Mod:
-						instructionPtr = ExecMod(i, instructionPtr);
-						break;
-					case OpCode.Power:
-						instructionPtr = ExecPower(i, instructionPtr);
-						break;
-					case OpCode.Eq:
-						instructionPtr = ExecEq(i, instructionPtr);
-						break;
-					case OpCode.LessEq:
-						instructionPtr = ExecLessEq(i, instructionPtr);
-						break;
-					case OpCode.Less:
-						instructionPtr = ExecLess(i, instructionPtr);
-						break;
-					case OpCode.Len:
-						instructionPtr = ExecLen(i, instructionPtr);
-						break;
-					case OpCode.Call:
-						instructionPtr = Internal_ExecCall(i.NumVal, instructionPtr);
-						break;
-					case OpCode.Scalar:
-						m_ValueStack.Push(m_ValueStack.Pop().ToScalar());
-						break;
-					case OpCode.Not:
-						ExecNot(i);
-						break;
-					case OpCode.JfOrPop:
-					case OpCode.JtOrPop:
-						instructionPtr = ExecShortCircuitingOperator(i, instructionPtr);
-						break;
-					case OpCode.JNil:
-						{
-							DynValue v = m_ValueStack.Pop();
-
-							if (v.Type == DataType.Nil)
-								instructionPtr = i.NumVal;
-						}
-						break;
-					case OpCode.Jf:
-						instructionPtr = JumpBool(i, false, instructionPtr);
-						break;
-					case OpCode.Jump:
-						instructionPtr = i.NumVal;
-						break;
-					case OpCode.MkTuple:
-						ExecMkTuple(i);
-						break;
-					case OpCode.Enter:
-						NilifyBlockData(i);
-						break;
-					case OpCode.Leave:
-					case OpCode.Exit:
-						ClearBlockData(i);
-						break;
-					case OpCode.Closure:
-						ExecClosure(i);
-						break;
-					case OpCode.BeginFn:
-						ExecBeginFn(i);
-						break;
-					case OpCode.ToBool:
-						m_ValueStack.Push(DynValue.NewBoolean(m_ValueStack.Pop().CastToBool()));
-						break;
-					case OpCode.Args:
-						ExecArgs(i);
-						break;
-					case OpCode.Ret:
-						instructionPtr = ExecRet(i);
-						if (instructionPtr < 0)
-							goto return_to_native_code;
-						break;
-					case OpCode.Incr:
-						ExecIncr(i);
-						break;
-					case OpCode.ToNum:
-						ExecToNum(i);
-						break;
-					case OpCode.JFor:
-						instructionPtr = ExecJFor(i, instructionPtr);
-						break;
-					case OpCode.NewTable:
-						m_ValueStack.Push(DynValue.NewTable(this.m_Script));
-						break;
-					case OpCode.IterPrep:
-						ExecIterPrep(i);
-						break;
-					case OpCode.IterUpd:
-						ExecIterUpd(i);
-						break;
-					case OpCode.ExpTuple:
-						ExecExpTuple(i);
-						break;
-					case OpCode.Local:
-						m_ValueStack.Push(m_ExecutionStack.Peek().LocalScope[i.Symbol.i_Index]);
-						break;
-					case OpCode.Upvalue:
-						m_ValueStack.Push(m_ExecutionStack.Peek().ClosureScope[i.Symbol.i_Index]);
-						break;
-					case OpCode.StoreUpv:
-						ExecStoreUpv(i);
-						break;
-					case OpCode.StoreLcl:
-						ExecStoreLcl(i);
-						break;
-					case OpCode.TblInitN:
-						ExecTblInitN(i);
-						break;
-					case OpCode.TblInitI:
-						ExecTblInitI(i);
-						break;
-					case OpCode.Index:
-						instructionPtr = ExecIndex(i, instructionPtr);
-						break;
-					case OpCode.PushEnv:
-						m_ValueStack.Push(DynValue.NewTable(m_GlobalTable));
-						break;
-					case OpCode.IndexSet:
-						instructionPtr = ExecIndexSet(i, instructionPtr);
-						break;
-					case OpCode.Invalid:
-						throw new NotImplementedException(string.Format("Invalid opcode : {0}", i.Name));
-					default:
-						throw new NotImplementedException(string.Format("Execution for {0} not implented yet!", i.OpCode));
+					throw;
 				}
+
 			}
 
 		return_to_native_code:
@@ -399,11 +429,11 @@ namespace MoonSharp.Interpreter.Execution.VM
 			}
 		}
 
-		private int PopToBasePointer()
+		private CallStackItem PopToBasePointer()
 		{
-			var xs = m_ExecutionStack.Pop();
-			m_ValueStack.CropAtCount(xs.BasePointer);
-			return xs.ReturnAddress;
+			var csi = m_ExecutionStack.Pop();
+			m_ValueStack.CropAtCount(csi.BasePointer);
+			return csi;
 		}
 
 		private int PopExecStackAndCheckVStack(int vstackguard)
@@ -446,7 +476,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 
 
-		private int Internal_ExecCall(int argsCount, int instructionPtr)
+		private int Internal_ExecCall(int argsCount, int instructionPtr, CallMode mode = CallMode.Normal)
 		{
 			DynValue fn = m_ValueStack.Peek(argsCount);
 
@@ -457,7 +487,7 @@ namespace MoonSharp.Interpreter.Execution.VM
 				m_ValueStack.RemoveLast(argsCount + 1);
 				m_ValueStack.Push(ret);
 
-				return ExecTailChk(null, instructionPtr);
+				return Internal_CheckForTailRequests(null, instructionPtr);
 			}
 			else if (fn.Type == DataType.Function)
 			{
@@ -467,7 +497,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 					BasePointer = m_ValueStack.Count,
 					ReturnAddress = instructionPtr,
 					Debug_EntryPoint = fn.Function.ByteCodeLocation,
-					ClosureScope = fn.Function.ClosureContext
+					ClosureScope = fn.Function.ClosureContext,
+					Mode = mode,
 				});
 				return fn.Function.ByteCodeLocation;
 			}
@@ -499,32 +530,59 @@ namespace MoonSharp.Interpreter.Execution.VM
 
 		private int ExecRet(Instruction i)
 		{
+			CallStackItem csi;
 			int retpoint = 0;
 
 			if (i.NumVal == 0)
 			{
-				retpoint = PopToBasePointer();
+				csi = PopToBasePointer();
+				retpoint = csi.ReturnAddress;
 				var argscnt = (int)(m_ValueStack.Pop().Number);
 				m_ValueStack.RemoveLast(argscnt + 1);
 				m_ValueStack.Push(DynValue.Nil);
-				return retpoint;
 			}
 			else if (i.NumVal == 1)
 			{
 				var retval = m_ValueStack.Pop();
-				retpoint = PopToBasePointer();
+				csi = PopToBasePointer();
+				retpoint = csi.ReturnAddress;
 				var argscnt = (int)(m_ValueStack.Pop().Number);
 				m_ValueStack.RemoveLast(argscnt + 1);
 				m_ValueStack.Push(retval);
-				return ExecTailChk(i, retpoint);
+				retpoint = Internal_CheckForTailRequests(i, retpoint);
 			}
 			else
 			{
 				throw new InternalErrorException("RET supports only 0 and 1 ret val scenarios");
 			}
+
+			if (csi.Mode != CallMode.Normal)
+				AdjustRetValueForMode(csi.Mode);
+
+			return retpoint;
+		}
+
+		private void AdjustRetValueForMode(CallMode callMode)
+		{
+			DynValue r = m_ValueStack.Pop();
+
+			switch (callMode)
+			{
+				case CallMode.PCall:
+					m_ValueStack.Push(DynValue.NewTupleNested(DynValue.True, r));
+					break;
+				case CallMode.Require:
+					break;
+				case CallMode.Normal:
+				default:
+					throw new InternalErrorException("Unreachable case .. reached");
+			}
+
+
+			
 		}
 
-		private int ExecTailChk(Instruction i, int instructionPtr)
+		private int Internal_CheckForTailRequests(Instruction i, int instructionPtr)
 		{
 			DynValue tail = m_ValueStack.Peek(0);
 
@@ -532,13 +590,15 @@ namespace MoonSharp.Interpreter.Execution.VM
 			{
 				m_ValueStack.Pop(); // discard tail call request
 
-				m_ValueStack.Push((DynValue)tail.UserObject);
+				TailCallData tcd = (TailCallData)tail.UserObject;
+
+				m_ValueStack.Push(tcd.Function);
 
-				for (int ii = 0; ii < tail.Tuple.Length; ii++)
-					m_ValueStack.Push(tail.Tuple[ii]);
+				for (int ii = 0; ii < tcd.Args.Length; ii++)
+					m_ValueStack.Push(tcd.Args[ii]);
 
 				//instructionPtr -= 1;
-				return Internal_ExecCall(tail.Tuple.Length, instructionPtr);
+				return Internal_ExecCall(tcd.Args.Length, instructionPtr, tcd.Mode);
 			}
 
 

+ 5 - 3
src/MoonSharp.Interpreter/Modules/CoreModules.cs

@@ -8,18 +8,20 @@ namespace MoonSharp.Interpreter
 	[Flags]
 	public enum CoreModules
 	{
+		Basic = 0x40,
 		GlobalConsts = 0x1,
 		TableIterators = 0x2,
 		Metatables = 0x4,
 		String = 0x8,
 		LoadMethods = 0x10,
 		Table = 0x20,
+		ErrorHandling = 0x80,
 
 
 
-		Preset_HardSandbox = GlobalConsts | TableIterators | String | Table,
-		Preset_SoftSandbox = Preset_HardSandbox | Metatables,
-		Preset_Default = Preset_SoftSandbox | LoadMethods ,
+		Preset_HardSandbox = GlobalConsts | TableIterators | String | Table | Basic,
+		Preset_SoftSandbox = Preset_HardSandbox | Metatables | ErrorHandling,
+		Preset_Default = Preset_SoftSandbox | LoadMethods,
 		Preset_Complete = Preset_Default,
 
 	}

+ 2 - 0
src/MoonSharp.Interpreter/Modules/ModuleRegister.cs

@@ -14,11 +14,13 @@ namespace MoonSharp.Interpreter
 		{
 			if (modules.Has(CoreModules.GlobalConsts)) RegisterConstants(table);
 			if (modules.Has(CoreModules.TableIterators)) RegisterModuleType<TableIterators>(table);
+			if (modules.Has(CoreModules.Basic)) RegisterModuleType<BasicMethods>(table);
 			if (modules.Has(CoreModules.Metatables)) RegisterModuleType<MetaTableMethods>(table);
 			if (modules.Has(CoreModules.String)) RegisterModuleType<StringModule>(table);
 			if (modules.Has(CoreModules.LoadMethods)) RegisterModuleType<LoadMethods>(table);
 			if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule>(table);
 			if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule_Globals>(table);
+			if (modules.Has(CoreModules.ErrorHandling)) RegisterModuleType<ErrorHandling>(table);
 
 			return table;
 		}

+ 1 - 0
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -98,6 +98,7 @@
     <Compile Include="DataStructs\LinkedListIndex.cs" />
     <Compile Include="DataStructs\Slice.cs" />
     <Compile Include="DataTypes\IScriptPrivateResource.cs" />
+    <Compile Include="DataTypes\TailCallData.cs" />
     <Compile Include="Debugging\DebuggerAction.cs" />
     <Compile Include="Debugging\IDebugger.cs" />
     <Compile Include="Debugging\SourceCodeType.cs" />