浏览代码

bug fixes, table methods

Xanathar 11 年之前
父节点
当前提交
b2ef3978d9

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

@@ -86,6 +86,7 @@
     <Compile Include="TestMore\TapRunner.cs" />
     <Compile Include="TestMore\TestMoreTests.cs" />
     <Compile Include="Units\FastStackTests.cs" />
+    <Compile Include="Units\InteropTests.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MoonSharp.Interpreter\MoonSharp.Interpreter.csproj">

+ 5 - 0
src/MoonSharp.Interpreter.Tests/TestMore/305-table.t

@@ -171,6 +171,8 @@ for name, line in pairsByKeys(lines, function (a, b) return a < b end) do
 end
 eq_array(output, {'luaH_get', 24, 'luaH_present', 48, 'luaH_set', 10}, "function sort")
 
+--[[ +++ Commented for coroutines
+
 function permgen (a, n)
     n = n or #a
     if n <= 1 then
@@ -241,3 +243,6 @@ eq_array({table.unpack({'a','b','c'},2,4)}, {'b','c'})
 --   fill-column: 100
 -- End:
 -- vim: ft=lua expandtab shiftwidth=4:
+
+
+--]]

+ 0 - 1
src/MoonSharp.Interpreter.Tests/TestMore/TestMoreTests.cs

@@ -234,7 +234,6 @@ namespace MoonSharp.Interpreter.Tests
 
 
 		[Test]
-		[Ignore]
 		public void TestMore_304_string()
 		{
 			TapRunner.Run(@"TestMore\304-string.t");

+ 30 - 0
src/MoonSharp.Interpreter.Tests/Units/InteropTests.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Interop;
+using NUnit.Framework;
+
+namespace MoonSharp.Interpreter.Tests.Units
+{
+	[TestFixture]
+	public class InteropTests
+	{
+		[Test]
+		public void Converter_FromObject()
+		{
+			//DynValue v;
+			//int? x = 3;
+			//int? y = null;
+
+			//v = Converter.FromObject(1);
+			//v = Converter.FromObject(x);
+			//v = Converter.FromObject(y);
+
+
+
+
+		}
+
+	}
+}

+ 1 - 1
src/MoonSharp.Interpreter/CoreLib/Patterns/PatternMatching.cs

@@ -310,7 +310,7 @@ namespace MoonSharp.Interpreter.CoreLib.Patterns
 									int ep = ClassEnd(ms, p); //points to what is next
 									char previous = (s == ms.SrcInit) ? '\0' : ms.Src[s - 1];
 									if (MatchBreaketClass(ms, previous, p, ep - 1) ||
-										!MatchBreaketClass(ms, ms.Src[s], p, ep - 1)) return -1;
+										(s < ms.Src.Length && !MatchBreaketClass(ms, ms.Src[s], p, ep - 1))) return -1;
 									p = ep; goto init; // else return match( ms, s, ep );
 								}
 							case '0':

+ 55 - 23
src/MoonSharp.Interpreter/CoreLib/TableModule.cs

@@ -10,39 +10,37 @@ namespace MoonSharp.Interpreter.CoreLib
 	[MoonSharpModule(Namespace = "table")]
 	public class TableModule
 	{
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue unpack(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			DynValue s = args.AsType(0, "unpack", DataType.Table, false);
+			DynValue vi = args.AsType(1, "unpack", DataType.Number, true);
+			DynValue vj = args.AsType(2, "unpack", DataType.Number, true);
+
+			int ii = vi.IsNil() ? 1 : (int)vi.Number;
+			int ij = vj.IsNil() ? GetTableLength(executionContext, s) : (int)vj.Number;
+
 			Table t = s.Table;
 
-			DynValue[] v = new DynValue[(int)t.Length];
+			DynValue[] v = new DynValue[ij - ii + 1];
 
-			for (int i = 1; i <= v.Length; i++)
-				v[i - 1] = t[i];
+			int tidx = 1;
+			for (int i = ii; i <= ij; i++)
+				v[tidx++] = t[i];
 
 			return DynValue.NewTuple(v);
 		}
 
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue pack(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
-			DynValue s = args[0];
 			Table t = new Table(executionContext.GetScript());
 			DynValue v = DynValue.NewTable(t);
 
-			if (s.IsNil())
-				return v;
+			for (int i = 0; i < args.Count; i++)
+				t[i + 1] = args[i];
 
-			if (s.Type == DataType.Tuple)
-			{
-				for (int i = 0; i < s.Tuple.Length; i++)
-					t[i + 1] = s.Tuple[i];
-			}
-			else
-			{
-				t[1] = s;
-			}
+			t["n"] = DynValue.NewNumber(args.Count);
 
 			return v;
 		}
@@ -116,13 +114,16 @@ namespace MoonSharp.Interpreter.CoreLib
 			return 0;
 		}
 
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue insert(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			DynValue vlist = args.AsType(0, "table.insert", DataType.Table, false);
 			DynValue vpos = args[1];
 			DynValue vvalue = args[2];
 
+			if (args.Count > 3)
+				throw new ScriptRuntimeException("wrong number of arguments to 'insert'");
+			
 			int len = GetTableLength(executionContext, vlist);
 			Table list = vlist.Table;
 
@@ -137,7 +138,10 @@ namespace MoonSharp.Interpreter.CoreLib
 
 			int pos = (int)vpos.Number;
 
-			for (int i = len; i <= pos; i--)
+			if (pos > len + 1 || pos < 1)
+				throw new ScriptRuntimeException("bad argument #2 to 'insert' (position out of bounds)");
+
+			for (int i = len; i >= pos; i--)
 			{
 				list[i + 1] = list[i];
 			}
@@ -148,13 +152,41 @@ namespace MoonSharp.Interpreter.CoreLib
 		}
 
 
+		[MoonSharpMethod]
+		public static DynValue remove(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			DynValue vlist = args.AsType(0, "table.remove", DataType.Table, false);
+			DynValue vpos = args.AsType(1, "table.remove", DataType.Number, true);
+			DynValue ret = DynValue.Nil;
+
+			if (args.Count > 2)
+				throw new ScriptRuntimeException("wrong number of arguments to 'remove'");
+
+			int len = GetTableLength(executionContext, vlist);
+			Table list = vlist.Table;
+
+			int pos = vpos.IsNil() ? len : (int)vpos.Number;
+
+			if (pos >= len + 1 || (pos < 1 && len > 0))
+				throw new ScriptRuntimeException("bad argument #1 to 'remove' (position out of bounds)");
+
+			for (int i = pos; i <= len; i++)
+			{
+				if (i == pos)
+					ret = list[i];
+
+				list[i] = list[i + 1];
+			}
+
+			return ret;
+		}
 
 
 		//table.concat (list [, sep [, i [, j]]])
 		//Given a list where all elements are strings or numbers, returns the string list[i]..sep..list[i+1] (...) sep..list[j]. 
 		//The default value for sep is the empty string, the default for i is 1, and the default for j is #list. If i is greater 
 		//than j, returns the empty string. 
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue concat(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			DynValue vlist = args.AsType(0, "concat", DataType.Table, false);
@@ -186,7 +218,7 @@ namespace MoonSharp.Interpreter.CoreLib
 				DynValue v = list[i];
 
 				if (v.Type != DataType.Number && v.Type != DataType.String)
-					throw new ScriptRuntimeException("invalid value (boolean) at index {0} in table for 'concat'", i);
+					throw new ScriptRuntimeException("invalid value ({1}) at index {0} in table for 'concat'", i, v.Type.ToLuaTypeString());
 
 				string s = v.ToPrintString();
 
@@ -226,13 +258,13 @@ namespace MoonSharp.Interpreter.CoreLib
 	[MoonSharpModule]
 	public class TableModule_Globals
 	{
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue unpack(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			return TableModule.unpack(executionContext, args);
 		}
 
-		[MoonSharpMethod()]
+		[MoonSharpMethod]
 		public static DynValue pack(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 			return TableModule.pack(executionContext, args);

+ 55 - 101
src/MoonSharp.Interpreter/DataTypes/DynValue.cs

@@ -16,9 +16,15 @@ namespace MoonSharp.Interpreter
 	public sealed class DynValue
 	{
 		static int s_RefIDCounter = 0;
+
 		private int m_RefID = ++s_RefIDCounter;
 		private int m_HashCode = -1;
 
+		private bool m_ReadOnly;
+		private double m_Number;
+		private object m_Object;
+		private DataType m_Type;
+
 
 		/// <summary>
 		/// Gets a unique reference identifier. This is guaranteed to be unique only in a single Script object as it's not thread-safe.
@@ -28,49 +34,49 @@ namespace MoonSharp.Interpreter
 		/// <summary>
 		/// Gets the type of the value.
 		/// </summary>
-		public DataType Type { get; private set; }
+		public DataType Type { get { return m_Type; } }
 		/// <summary>
 		/// Gets the function (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Function"/>)
 		/// </summary>
-		public Closure Function { get; private set; }
+		public Closure Function { get { return m_Object as Closure; } }
 		/// <summary>
 		/// Gets the numeric value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Number"/>)
 		/// </summary>
-		public double Number { get; private set; }
+		public double Number { get { return m_Number; } }
 		/// <summary>
 		/// Gets the values in the tuple (valid only if the <seealso cref="Type"/> is Tuple).
 		/// This field is currently also used to hold arguments in values whose <seealso cref="Type"/> is <seealso cref="DataType.TailCallRequest"/>.
 		/// </summary>
-		public DynValue[] Tuple { get; private set; }
+		public DynValue[] Tuple { get { return m_Object as DynValue[]; } }
 		/// <summary>
 		/// Gets the table (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Table"/>)
 		/// </summary>
-		public Table Table { get; private set; }
+		public Table Table { get { return m_Object as Table; } }
 		/// <summary>
 		/// Gets the boolean value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Boolean"/>)
 		/// </summary>
-		public bool Boolean { get; private set; }
+		public bool Boolean { get { return Number != 0; } }
 		/// <summary>
 		/// Gets the string value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.String"/>)
 		/// </summary>
-		public string String { get; private set; }
+		public string String { get { return m_Object as string; } }
 		/// <summary>
 		/// Gets the CLR callback (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.ClrFunction"/>)
 		/// </summary>
-		public CallbackFunction Callback { get; set; }
+		public CallbackFunction Callback { get { return m_Object as CallbackFunction; } }
 		/// <summary>
-		/// Gets or sets the user object, if this value is userdata
+		/// Gets the tail call data.
 		/// </summary>
-		public object UserObject { get; set; }
+		public TailCallData TailCallData { get { return m_Object as TailCallData; } }
 		/// <summary>
 		/// Gets the tail call data.
 		/// </summary>
-		public TailCallData TailCallData { get { return UserObject as TailCallData; } }
+		public UserData UserData { get { return m_Object as UserData; } }
 
 		/// <summary>
 		/// Returns true if this instance is write protected.
 		/// </summary>
-		public bool ReadOnly { get; internal set; }
+		public bool ReadOnly { get { return m_ReadOnly; }}
 
 
 
@@ -90,8 +96,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Boolean = v,
-				Type = DataType.Boolean,
+				m_Number = v ? 1 : 0,
+				m_Type = DataType.Boolean,
 			};
 		}
 
@@ -102,8 +108,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Number = num,
-				Type = DataType.Number,
+				m_Number = num,
+				m_Type = DataType.Number,
 				m_HashCode = -1,
 			};
 		}
@@ -115,8 +121,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				String = str,
-				Type = DataType.String,
+				m_Object = str,
+				m_Type = DataType.String,
 			};
 		}
 
@@ -128,8 +134,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Function = function,
-				Type = DataType.Function,
+				m_Object = function,
+				m_Type = DataType.Function,
 			};
 		}
 
@@ -140,8 +146,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Callback = new CallbackFunction(callBack),
-				Type = DataType.ClrFunction,
+				m_Object = new CallbackFunction(callBack),
+				m_Type = DataType.ClrFunction,
 			};
 		}
 
@@ -152,8 +158,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Callback = function,
-				Type = DataType.ClrFunction,
+				m_Object = function,
+				m_Type = DataType.ClrFunction,
 			};
 		}
 
@@ -164,8 +170,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				Table = table,
-				Type = DataType.Table,
+				m_Object = table,
+				m_Type = DataType.Table,
 			};
 		}
 
@@ -191,12 +197,12 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				UserObject = new TailCallData()
+				m_Object = new TailCallData()
 				{
 					Args = args,
 					Function = tailFn,
 				},
-				Type = DataType.TailCallRequest,
+				m_Type = DataType.TailCallRequest,
 			};
 		}
 
@@ -213,8 +219,8 @@ namespace MoonSharp.Interpreter
 		{
 			return new DynValue()
 			{
-				UserObject = tailCallData,
-				Type = DataType.TailCallRequest,
+				m_Object = tailCallData,
+				m_Type = DataType.TailCallRequest,
 			};
 		}
 
@@ -231,8 +237,8 @@ namespace MoonSharp.Interpreter
 
 			return new DynValue()
 			{
-				Tuple = values,
-				Type = DataType.Tuple,
+				m_Object = values,
+				m_Type = DataType.Tuple,
 			};
 		}
 
@@ -259,40 +265,11 @@ namespace MoonSharp.Interpreter
 
 			return new DynValue()
 			{
-				Tuple = vals.ToArray(),
-				Type = DataType.Tuple,
-			};
-		}
-
-		/// <summary>
-		/// Creates a new value initialized to the specified coroutine index.
-		/// </summary>
-		internal static DynValue NewCoroutine(int coroutineIdx)
-		{
-			return new DynValue()
-			{
-				Number = coroutineIdx,
-				Type = DataType.Thread
+				m_Object = vals.ToArray(),
+				m_Type = DataType.Tuple,
 			};
 		}
 
-
-		/// <summary>
-		///  Creates a new value initialized to the specified CLR object
-		/// </summary>
-		/// <param name="obj">The CLR object.</param>
-		/// <param name="metatable">Optional - the metatable.</param>
-		public static DynValue NewObject(object obj)
-		{
-			return new DynValue()
-			{
-				UserObject = obj,
-				Type = DataType.UserData,
-			};
-		}
-
-
-
 		/// <summary>
 		/// Returns this value as readonly - eventually cloning it in the process if it isn't readonly to start with.
 		/// </summary>
@@ -302,29 +279,23 @@ namespace MoonSharp.Interpreter
 				return this;
 			else
 			{
-				DynValue v = Clone();
-				v.ReadOnly = true;
-				return v;
+				return Clone(true);
 			}
 		}
 
-		/// <summary>
-		/// Clones this instance.
-		/// </summary>
-		/// <exception cref="System.ArgumentException">Can't clone Symbol values</exception>
 		public DynValue Clone()
+		{
+			return Clone(this.ReadOnly);
+		}
+
+		public DynValue Clone(bool readOnly)
 		{
 			DynValue v = new DynValue();
-			v.Boolean = this.Boolean;
-			v.Callback = this.Callback;
-			v.Function = this.Function;
-			v.Number = this.Number;
-			v.ReadOnly = this.ReadOnly;
-			v.String = this.String;
-			v.Table = this.Table;
-			v.Tuple = this.Tuple;
-			v.Type = this.Type;
+			v.m_Object = this.m_Object;
+			v.m_Number = this.m_Number;
 			v.m_HashCode = this.m_HashCode;
+			v.m_Type = this.m_Type;
+			v.m_ReadOnly = readOnly;
 			return v;
 		}
 
@@ -334,18 +305,7 @@ namespace MoonSharp.Interpreter
 		/// <exception cref="System.ArgumentException">Can't clone Symbol values</exception>
 		public DynValue CloneAsWritable()
 		{
-			DynValue v = new DynValue();
-			v.Boolean = this.Boolean;
-			v.Function = this.Function;
-			v.Callback = this.Callback;
-			v.Number = this.Number;
-			v.ReadOnly = false;
-			v.String = this.String;
-			v.Table = this.Table;
-			v.Tuple = this.Tuple;
-			v.Type = this.Type;
-			v.m_HashCode = this.m_HashCode;
-			return v;
+			return Clone(false);
 		}
 
 
@@ -599,15 +559,9 @@ namespace MoonSharp.Interpreter
 			if (this.ReadOnly)
 				throw new ScriptRuntimeException("Assigning on r-value");
 
-			this.Boolean = value.Boolean;
-			this.Callback = value.Callback;
-			this.Function = value.Function;
-			this.Number = value.Number;
-			this.ReadOnly = false;
-			this.String = value.String;
-			this.Table = value.Table;
-			this.Tuple = value.Tuple;
-			this.Type = value.Type;
+			this.m_Number = value.m_Number;
+			this.m_Object = value.m_Object;
+			this.m_Type = value.Type;
 			this.m_HashCode = -1;
 		}
 
@@ -655,7 +609,7 @@ namespace MoonSharp.Interpreter
 			if (this.Type != DataType.Number)
 				throw new InternalErrorException("Can't assign number to type {0}", this.Type);
 
-			this.Number = num;
+			this.m_Number = num;
 		}
 
 	}

+ 12 - 1
src/MoonSharp.Interpreter/DataTypes/Table.cs

@@ -144,6 +144,8 @@ namespace MoonSharp.Interpreter
 					CollectDeadKeys();
 					m_CachedLength = -1;
 				}
+				else if (value.IsNil())
+					m_CachedLength = -1;
 			}
 		}
 
@@ -228,6 +230,7 @@ namespace MoonSharp.Interpreter
 			return m_StringMap.ContainsKey(symbol);
 		}
 
+
 		public double Length
 		{
 			get 
@@ -236,7 +239,7 @@ namespace MoonSharp.Interpreter
 				{
 					m_CachedLength = 0;
 
-					for (int i = 1; m_ArrayMap.ContainsKey(i); i++)
+					for (int i = 1; m_ArrayMap.ContainsKey(i) && !m_ArrayMap.Find(i).Value.Value.IsNil(); i++)
 						m_CachedLength = i;
 				}
 
@@ -263,6 +266,14 @@ namespace MoonSharp.Interpreter
 		public Table MetaTable { get; set; }
 
 
+		
+
+		
+
+
+
+
+
 
 	}
 }

+ 16 - 0
src/MoonSharp.Interpreter/DataTypes/UserData.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter
+{
+	public class UserData
+	{
+		public object Object { get; set; }
+
+		public string Id { get; set;  }
+
+		public Table Metatable { get; set; }
+	}
+}

+ 0 - 4
src/MoonSharp.Interpreter/Execution/VM/ByteCode.cs

@@ -261,9 +261,5 @@ namespace MoonSharp.Interpreter.Execution.VM
 			return AppendInstruction(new Instruction() { OpCode = OpCode.Swap, NumVal = p1, NumVal2 = p2 });
 		}
 
-		public Instruction Emit_Clone()
-		{
-			return AppendInstruction(new Instruction() { OpCode = OpCode.Clone });
-		}
 	}
 }

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

@@ -17,7 +17,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 		Pop,		// Discards the topmost n elements from the v-stack. 
 		Copy,		// Copies the n-th value of the stack on the top
 		Swap,		// Swaps two entries relative to the v-stack
-		Clone,		// Sets the top of the stack to be a clone of itself (by value, not by ref)
 		Literal,	// Pushes a literal (constant value) on the stack. 
 		Closure,	// Creates a closure on the top of the v-stack, using the symbols for upvalues and num-val for entry point of the function.
 		NewTable,	// Creates a new empty table on the stack

+ 31 - 4
src/MoonSharp.Interpreter/Execution/VM/Processor/Processor_InstructionLoop.cs

@@ -181,9 +181,6 @@ namespace MoonSharp.Interpreter.Execution.VM
 						case OpCode.IndexSet:
 							instructionPtr = ExecIndexSet(i, instructionPtr);
 							break;
-						case OpCode.Clone:
-							m_ValueStack.Push(m_ValueStack.Pop().Clone());
-							break;
 						case OpCode.Invalid:
 							throw new NotImplementedException(string.Format("Invalid opcode : {0}", i.Name));
 						default:
@@ -406,7 +403,10 @@ namespace MoonSharp.Interpreter.Execution.VM
 			if (top.ReadOnly)
 			{
 				m_ValueStack.Pop();
-				top = top.CloneAsWritable();
+
+				if (top.ReadOnly)
+					top = top.CloneAsWritable();
+
 				m_ValueStack.Push(top);
 			}
 
@@ -496,6 +496,24 @@ namespace MoonSharp.Interpreter.Execution.VM
 			}
 		}
 
+		private IList<DynValue> ExpandToList(IList<DynValue> args, List<DynValue> target = null)
+		{
+			target = target ?? new List<DynValue>();
+
+			foreach (DynValue v in args)
+			{
+				if (v.Type == DataType.Tuple)
+				{
+					ExpandToList(v.Tuple, target);
+				}
+				else
+				{
+					target.Add(v);
+				}
+			}
+
+			return target;
+		}
 
 
 		private int Internal_ExecCall(int argsCount, int instructionPtr, CallbackFunction handler = null, CallbackFunction continuation = null)
@@ -505,6 +523,13 @@ namespace MoonSharp.Interpreter.Execution.VM
 			if (fn.Type == DataType.ClrFunction)
 			{
 				IList<DynValue> args = new Slice<DynValue>(m_ValueStack, m_ValueStack.Count - argsCount, argsCount, false);
+
+				// we expand tuples before callbacks
+				if (args.Any(v => v.Type == DataType.Tuple))
+				{
+					args = ExpandToList(args);
+				}
+
 				var ret = fn.Callback.Invoke(new ScriptExecutionContext(this, fn.Callback), args);
 				m_ValueStack.RemoveLast(argsCount + 1);
 				m_ValueStack.Push(ret);
@@ -553,6 +578,8 @@ namespace MoonSharp.Interpreter.Execution.VM
 		}
 
 
+
+
 		private int ExecRet(Instruction i)
 		{
 			CallStackItem csi;

+ 99 - 0
src/MoonSharp.Interpreter/Interop/Converter.cs

@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using MoonSharp.Interpreter.Execution;
+
+namespace MoonSharp.Interpreter.Interop
+{
+	public static class Converter
+	{
+		static readonly Type[] NumericTypes = 
+		{
+			typeof(sbyte), 
+			typeof(byte), 
+			//typeof(char),  // should we ?
+			typeof(short), 
+			typeof(ushort), 
+			typeof(int), 
+			typeof(uint), 
+			typeof(long), 
+			typeof(ulong), 
+			typeof(float), 
+			typeof(decimal), 
+			typeof(double)
+		};
+
+		public static bool CheckCallbackSignature(MethodInfo mi)
+		{
+			ParameterInfo[] pi = mi.GetParameters();
+
+			return (pi.Length == 2 && pi[0].ParameterType == typeof(ScriptExecutionContext)
+				&& pi[1].ParameterType == typeof(CallbackArguments) && mi.ReturnType == typeof(DynValue));
+		}
+
+		public static DataType? TryGetSimpleScriptTypeForClrType(Type t, out bool nullable)
+		{
+			Type tv = Nullable.GetUnderlyingType(t);
+
+			nullable = false;
+
+			if (tv != null)
+			{
+				nullable = true;
+				t = tv;
+			}
+
+			if (NumericTypes.Contains(t))
+				return DataType.Number;
+
+			if (t == typeof(bool))
+				return DataType.Boolean;
+
+			if (t == typeof(string) || t == typeof(StringBuilder) || t == typeof(char))
+				return DataType.String;
+
+			return null;
+		}
+
+
+
+
+		public static DynValue CreateValueFromSupportedObject(this Script script, object obj)
+		{
+			if (obj == null)
+				return DynValue.Nil;
+
+			if (NumericTypes.Contains(obj.GetType()))
+				return DynValue.NewNumber((double)obj);
+
+			if (obj is bool)
+				return DynValue.NewBoolean((bool)obj);
+
+			if (obj is string || obj is StringBuilder || obj is char)
+				return DynValue.NewString(obj.ToString());
+
+			if (obj is Table)
+				return DynValue.NewTable((Table)obj);
+
+			if (obj is CallbackFunction)
+				return DynValue.NewCallback((CallbackFunction)obj);
+
+			if (obj is Delegate)
+			{
+				Delegate d = (Delegate)obj;
+				MethodInfo mi = d.Method;
+
+				if (CheckCallbackSignature(mi))
+					return DynValue.NewCallback((Func<ScriptExecutionContext, CallbackArguments, DynValue>)d); 
+			}
+
+			return null;
+		}
+
+
+
+
+	}
+}

+ 31 - 0
src/MoonSharp.Interpreter/Interop/MethodAdapter.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Interop
+{
+	public class MethodAdapter
+	{
+		private class ArgType
+		{
+			public DataType Type;
+			public bool Nullable;
+		}
+
+		public MethodAdapter(MethodInfo mi)
+		{
+			foreach (var arg in mi.GetParameters())
+			{
+				
+			}
+		}
+
+
+
+
+
+
+	}
+}

+ 18 - 0
src/MoonSharp.Interpreter/Interop/MoonSharpInterop.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.Interop
+{
+	public static class MoonSharpInterop
+	{
+
+
+
+
+
+
+
+	}
+}

+ 52 - 0
src/MoonSharp.Interpreter/Interop/ReflectionMetatableBuilder.cs

@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Execution;
+
+namespace MoonSharp.Interpreter.Interop
+{
+	// Only __eq, __tostring, __index and __newindex are supported.
+	public class ReflectionMetatableBuilder
+	{
+		private static UserData GetUserData(CallbackArguments args)
+		{
+			DynValue v = args.AsType(0, "::ReflectionMetatableBuilder", DataType.UserData, false);
+			return v.UserData;
+		}
+
+
+		public static DynValue reflection_tostring(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			UserData u = GetUserData(args);
+			return DynValue.NewString(u.Object.ToString());
+		}
+
+		public static DynValue reflection_eq(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			UserData u = GetUserData(args);
+			DynValue a = args[1];
+
+			if (a.Type != DataType.UserData)
+				return DynValue.False;
+
+			return DynValue.NewBoolean(u.Object.Equals(a.UserData.Object));
+		}
+
+		public static DynValue reflection_index(ScriptExecutionContext executionContext, CallbackArguments args)
+		{
+			return DynValue.Nil;
+		}
+
+
+
+
+
+
+
+
+
+
+
+	}
+}

+ 3 - 7
src/MoonSharp.Interpreter/Modules/ModuleRegister.cs

@@ -5,6 +5,7 @@ using System.Reflection;
 using System.Text;
 using MoonSharp.Interpreter.CoreLib;
 using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.Interop;
 
 namespace MoonSharp.Interpreter
 {
@@ -51,13 +52,8 @@ namespace MoonSharp.Interpreter
 				{
 					MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
 
-					ParameterInfo[] pi = mi.GetParameters();
-
-					if (pi.Length != 2 || pi[0].ParameterType != typeof(ScriptExecutionContext)
-						|| pi[1].ParameterType != typeof(CallbackArguments) || mi.ReturnType != typeof(DynValue))
-					{
-						throw new ArgumentException(string.Format("Method {0} does not have the right signature.", mi.Name));
-					}
+					if (!Converter.CheckCallbackSignature(mi))
+							throw new ArgumentException(string.Format("Method {0} does not have the right signature.", mi.Name));
 
 					Func<ScriptExecutionContext, CallbackArguments, DynValue> func = (Func<ScriptExecutionContext, CallbackArguments, DynValue>)Delegate.CreateDelegate(typeof(Func<ScriptExecutionContext, CallbackArguments, DynValue>), mi);
 

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

@@ -100,6 +100,7 @@
     <Compile Include="DataStructs\Slice.cs" />
     <Compile Include="DataTypes\IScriptPrivateResource.cs" />
     <Compile Include="DataTypes\TailCallData.cs" />
+    <Compile Include="DataTypes\UserData.cs" />
     <Compile Include="DataTypes\WellKnownSymbols.cs" />
     <Compile Include="Debugging\DebuggerAction.cs" />
     <Compile Include="Debugging\IDebugger.cs" />
@@ -131,6 +132,10 @@
     <Compile Include="Execution\VM\Chunk.cs" />
     <Compile Include="Execution\VM\Processor\Processor_Errors.cs" />
     <Compile Include="Interface\IteratorHelper.cs" />
+    <Compile Include="Interop\Converter.cs" />
+    <Compile Include="Interop\MethodAdapter.cs" />
+    <Compile Include="Interop\MoonSharpInterop.cs" />
+    <Compile Include="Interop\ReflectionMetatableBuilder.cs" />
     <Compile Include="Loaders\ClassicLuaScriptLoader.cs" />
     <Compile Include="Loaders\IScriptLoader.cs" />
     <Compile Include="Execution\Scopes\ClosureContext.cs" />

+ 1 - 1
src/PerformanceComparison/Program.cs

@@ -147,7 +147,7 @@ end
 			sw = Stopwatch.StartNew();
 			for (int i = 0; i < ITERATIONS; i++)
 			{
-				script.Call(0, func);
+				script.Call(func);
 			}
 			sw.Stop();