예제 #1
0
 public static LuaFunction MakeRefTo(Lua L, int idx)
 {
     Lua.Assert(Api.lua_isfunction(L, idx), "not function");
     return(new LuaFunction {
         L_ = L, funcRef = L.MakeRefAt(idx)
     });
 }
예제 #2
0
        public static LuaThread MakeRefTo(Lua L, int idx)
        {
            Lua.Assert(Api.lua_isthread(L, idx));
            var threadRef = L.MakeRefAt(idx);

            return(new LuaThread {
                L_ = L, threadRef = threadRef
            });
        }
예제 #3
0
        static int MetaNewIndexFunctionInternal(lua_State L)
        {
            var isIndexingClassObject = IsIndexingClassObject(L);

            System.Type typeObject = null;
            if (isIndexingClassObject)
            {
                typeObject = (System.Type)Lua.ObjectAtInternal(L, 1);
            }

            object thisObject = null;

            if (!isIndexingClassObject)
            {
                thisObject = Lua.ObjectAtInternal(L, 1);
                typeObject = thisObject.GetType();
            }

            Lua.Assert(typeObject != null, "Should has a type.");

            if (Api.lua_isnumber(L, 2))
            {
                if (typeObject != null && typeObject.IsArray)
                {
                    var array = (System.Array)thisObject;
                    var value = Lua.ValueAtInternal(L, 3);
                    var index = (int)Api.lua_tointeger(L, 2);
                    array.SetValue(Lua.ConvertTo(value, typeObject.GetElementType()), index);
                }
                else
                {
                    Lua.SetValueAtIndexOfObject(L, thisObject, typeObject, new object[] { (int)Api.lua_tointeger(L, 2) }, Lua.ValueAtInternal(L, 3));
                }
            }
            else if (Api.lua_isstring(L, 2))
            {
                Lua.SetMember(L, thisObject, typeObject, Api.lua_tostring(L, 2), Lua.ValueAtInternal(L, 3), hasPrivatePrivillage: false);
            }
            else if (Api.lua_istable(L, 2))
            {
                var host = Lua.CheckHost(L);
                using (var p = LuaTable.MakeRefTo(host, 2))
                {
                    using (var ret = host.testPrivillage.InvokeMultiRet(p))
                    {
                        var name = (string)ret[1];
                        Lua.SetMember(L, thisObject, typeObject, name, Lua.ValueAtInternal(L, 3), hasPrivatePrivillage: true);
                    }
                }
            }
            else
            {
                Lua.SetValueAtIndexOfObject(L, thisObject, typeObject, new object[] { Lua.ValueAtInternal(L, 2) }, Lua.ValueAtInternal(L, 3));
            }
            return(0);
        }
예제 #4
0
 internal static LuaTable MakeRefTo(Lua L, int idx)
 {
     Lua.Assert(Api.lua_istable(L, idx));
     return(new LuaTable(L, idx));
 }
예제 #5
0
        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);
        }
예제 #6
0
        static int MetaIndexFunctionInternal(lua_State L)
        {
            var isIndexingClassObject = IsIndexingClassObject(L);

            System.Type typeObject = null;
            if (isIndexingClassObject)
            {
                typeObject = (System.Type)Lua.ObjectAtInternal(L, 1);
            }

            object thisObject = null;

            if (!isIndexingClassObject)
            {
                thisObject = Lua.ObjectAtInternal(L, 1);
                typeObject = thisObject.GetType();
            }

            Lua.Assert(typeObject != null, "Should have a type");

            if (Api.lua_isinteger(L, 2))
            {
                if (typeObject != null && typeObject.IsArray)
                {
                    var array = (System.Array)thisObject;
                    Lua.PushValueInternal(L, array.GetValue((int)Api.lua_tointeger(L, 2)));
                    return(1);
                }
                else
                {
                    return(Lua.IndexObjectInternal(L, thisObject, typeObject, new object[] { (int)Api.lua_tointeger(L, 2) }));
                }
            }
            else if (Api.lua_isstring(L, 2))
            {
                return(Lua.GetMember(L, thisObject, typeObject, Api.lua_tostring(L, 2), false, null, null));
            }
            else if (Api.lua_istable(L, 2))
            {
                var host = Lua.CheckHost(L);
                using (var p = LuaTable.MakeRefTo(host, 2))
                {
                    var isGettingTypeObject = (bool)host.isIndexingTypeObject.Invoke1(p);
                    if (isGettingTypeObject)
                    {
                        Lua.PushObjectInternal(L, typeObject);
                        return(1);
                    }
                    using (var ret = host.testPrivillage.InvokeMultiRet(p))
                    {
                        var name = (string)ret[1];
                        var hasPrivatePrivillage = (bool)ret[2];
                        var retrievingNestedType = (bool)ret[5];
                        if (retrievingNestedType)
                        {
                            var flags = System.Reflection.BindingFlags.Public;
                            if (hasPrivatePrivillage)
                            {
                                flags |= System.Reflection.BindingFlags.NonPublic;
                            }
                            var nestedType = typeObject.GetNestedType(name, flags);
                            if (nestedType != null)
                            {
                                Lua.PushTypeInternal(L, nestedType);
                            }
                            else
                            {
                                Api.lua_pushnil(L);
                            }
                            return(1);
                        }
                        var exactTypes   = (Type[])ret[3];
                        var genericTypes = (Type[])ret[4];
                        return(Lua.GetMember(L, thisObject, typeObject, name, hasPrivatePrivillage, exactTypes, genericTypes));
                    }
                }
            }
            else
            {
                return(Lua.IndexObjectInternal(L, thisObject, typeObject, new object[] { Lua.ValueAtInternal(L, 2) }));
            }
        }