static int MetaConstructFunctionInternal(lua_State L) { var typeObj = Lua.ObjectAtInternal(L, 1); Lua.Assert((typeObj != null && (typeObj is System.Type)), "Constructor needs type object."); var numArgs = Api.lua_gettop(L); int[] luaArgTypes = Lua.luaArgTypes_NoArgs; if (numArgs > 1) // the first arg is class itself { luaArgTypes = new int[numArgs - 1]; for (var i = 2; i <= numArgs; ++i) { luaArgTypes[i - 2] = Api.lua_type(L, i); } } var type = (System.Type)typeObj; if (luaArgTypes == Lua.luaArgTypes_NoArgs && type.IsValueType) { var value = Activator.CreateInstance(type); Lua.PushObjectInternal(L, value); return(1); } var mangledName = Lua.CheckHost(L).Mangle("__ctor", luaArgTypes, invokingStaticMethod: true, argStart: 2); var mc = Lua.GetMethodFromCache(type, mangledName); System.Reflection.ParameterInfo[] parameters = null; if (mc == null) { var constructors = type.GetConstructors(); System.Reflection.MethodBase selected = null; int highScore = int.MinValue; List <Exception> pendingExceptions = null; for (var i = 0; i < constructors.Length; ++i) { var method = constructors[i]; try { Lua.MatchingParameters(L, 2, method, luaArgTypes, ref highScore, ref selected, ref parameters); } catch (System.Reflection.AmbiguousMatchException e) { throw e; } catch (Exception e) { if (pendingExceptions == null) { pendingExceptions = new List <Exception>(); } pendingExceptions.Add(e); } } if (selected != null) { mc = Lua.CacheMethod(type, mangledName, selected, parameters); } else { var additionalMessage = string.Empty; if (pendingExceptions != null && pendingExceptions.Count > 0) { var sb = new System.Text.StringBuilder(); for (int i = 0; i < pendingExceptions.Count; ++i) { sb.AppendLine(pendingExceptions[i].Message); } additionalMessage = sb.ToString(); } throw new Exception(string.Format("No proper constructor available, calling {0}\n{1}", Lua.GetLuaInvokingSigniture("ctor", luaArgTypes), additionalMessage)); } } var ctor = (System.Reflection.ConstructorInfo)mc.method; IDisposable[] disposableArgs; var args = Lua.ArgsFrom(L, mc.parameters, mc.variadicArg, 2, luaArgTypes.Length, out disposableArgs); Lua.PushObjectInternal(L, ctor.Invoke(args)); if (disposableArgs != null) { foreach (var d in disposableArgs) { if (d != null) { d.Dispose(); } } } return(1); }