예제 #1
0
 /*
  * Creates the metatable for type references
  */
 private void CreateClassMetatable(LuaState luaState)
 {
     luaState.NewMetaTable("luaNet_class");
     luaState.PushString("__gc");
     luaState.PushCFunction(MetaFunctions.GcFunction);
     luaState.SetTable(-3);
     luaState.PushString("__tostring");
     luaState.PushCFunction(MetaFunctions.ToStringFunction);
     luaState.SetTable(-3);
     luaState.PushString("__index");
     luaState.PushCFunction(MetaFunctions.ClassIndexFunction);
     luaState.SetTable(-3);
     luaState.PushString("__newindex");
     luaState.PushCFunction(MetaFunctions.ClassNewIndexFunction);
     luaState.SetTable(-3);
     luaState.PushString("__call");
     luaState.PushCFunction(MetaFunctions.CallConstructorFunction);
     luaState.SetTable(-3);
     luaState.SetTop(-2);
 }
예제 #2
0
        /*
         * Gets an object from the Lua stack according to its Lua type.
         */
        internal object GetObject(LuaState luaState, int index)
        {
            LuaType type = luaState.Type(index);

            switch (type)
            {
            case LuaType.Number:
            {
                if (luaState.IsInteger(index))
                {
                    return(luaState.ToInteger(index));
                }

                return(luaState.ToNumber(index));
            }

            case LuaType.String:
                return(luaState.ToString(index, false));

            case LuaType.Boolean:
                return(luaState.ToBoolean(index));

            case LuaType.Table:
                return(GetTable(luaState, index));

            case LuaType.Function:
                return(GetFunction(luaState, index));

            case LuaType.UserData:
            {
                int udata = luaState.ToNetObject(index, Tag);
                return(udata != -1 ? _objects[udata] : GetUserData(luaState, index));
            }

            case LuaType.Thread:
                return(GetThread(luaState, index));

            default:
                return(null);
            }
        }
예제 #3
0
        int EnumFromIntInternal(LuaState luaState)
        {
            Type t = TypeOf(luaState, 1);

            if (t == null || !t.IsEnum)
            {
                return(PushError(luaState, "Not an Enum."));
            }

            object  res = null;
            LuaType lt  = luaState.Type(2);

            if (lt == LuaType.Number)
            {
                int ival = (int)luaState.ToNumber(2);
                res = Enum.ToObject(t, ival);
            }
            else if (lt == LuaType.String)
            {
                string sflags = luaState.ToString(2, false);
                string err    = null;
                try
                {
                    res = Enum.Parse(t, sflags, true);
                }
                catch (ArgumentException e)
                {
                    err = e.Message;
                }
                if (err != null)
                {
                    return(PushError(luaState, err));
                }
            }
            else
            {
                return(PushError(luaState, "Second argument must be a integer or a string."));
            }
            PushObject(luaState, res, "luaNet_metatable");
            return(1);
        }
예제 #4
0
        /*
         * Gets an object from the Lua stack according to its Lua type.
         */
        internal object GetObject(LuaState luaState, int index)
        {
            var type = luaState.Type(index);

            switch (type)
            {
            case LuaType.Number:
            {
                return(luaState.ToNumber(index));
            }

            case LuaType.String:
            {
                return(luaState.ToString(index));
            }

            case LuaType.Boolean:
            {
                return(luaState.ToBoolean(index));
            }

            case LuaType.Table:
            {
                return(GetTable(luaState, index));
            }

            case LuaType.Function:
            {
                return(GetFunction(luaState, index));
            }

            case LuaType.UserData:
            {
                int udata = luaState.ToNetObject(index, Tag);
                return(udata != -1 ? objects[udata] : GetUserData(luaState, index));
            }

            default:
                return(null);
            }
        }
예제 #5
0
        private int UnregisterTableInternal(LuaState luaState)
        {
            try
            {
                if (luaState.GetMetaTable(1))
                {
                    luaState.PushString("__index");
                    luaState.GetTable(-2);
                    object obj = GetRawNetObject(luaState, -1);

                    if (obj == null)
                    {
                        ThrowError(luaState, "unregister_table: arg is not valid table");
                    }

                    var luaTableField = obj.GetType().GetField("__luaInterface_luaTable");

                    if (luaTableField == null)
                    {
                        ThrowError(luaState, "unregister_table: arg is not valid table");
                    }

                    luaTableField.SetValue(obj, null);
                    luaState.PushNil();
                    luaState.SetMetaTable(1);
                    luaState.PushString("base");
                    luaState.PushNil();
                    luaState.SetTable(1);
                }
                else
                {
                    ThrowError(luaState, "unregister_table: arg is not valid table");
                }
            }
            catch (Exception e)
            {
                ThrowError(luaState, e.Message);
            }

            return(0);
        }
예제 #6
0
 /*
  * Registers the global functions used by NLua
  */
 private void SetGlobalFunctions(LuaState luaState)
 {
     luaState.PushCFunction(MetaFunctions.IndexFunction);
     luaState.SetGlobal("get_object_member");
     luaState.PushCFunction(_importTypeFunction);
     luaState.SetGlobal("import_type");
     luaState.PushCFunction(_loadAssemblyFunction);
     luaState.SetGlobal("load_assembly");
     luaState.PushCFunction(_registerTableFunction);
     luaState.SetGlobal("make_object");
     luaState.PushCFunction(_unregisterTableFunction);
     luaState.SetGlobal("free_object");
     luaState.PushCFunction(_getMethodSigFunction);
     luaState.SetGlobal("get_method_bysig");
     luaState.PushCFunction(_getConstructorSigFunction);
     luaState.SetGlobal("get_constructor_bysig");
     luaState.PushCFunction(_ctypeFunction);
     luaState.SetGlobal("ctype");
     luaState.PushCFunction(_enumFromIntFunction);
     luaState.SetGlobal("enum");
 }
예제 #7
0
        public static IntPtr CheckUData(this LuaState state, int ud, string name)
        {
            var p = state.ToUserData(ud);

            if (p == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }
            if (!state.GetMetaTable(ud))
            {
                return(IntPtr.Zero);
            }

            state.GetField(LuaRegistry.Index, name);

            var isEqual = state.RawEqual(-1, -2);

            state.Pop(2);

            return(isEqual ? p : IntPtr.Zero);
        }
예제 #8
0
        /*
         * Pushes a CLR object into the Lua stack as an userdata
         * with the provided metatable
         */
        internal void PushObject(LuaState luaState, object o, string metatable)
        {
            int index = -1;

            // Pushes nil
            if (o == null)
            {
                luaState.PushNil();
                return;
            }

            // Object already in the list of Lua objects? Push the stored reference.
            bool found = (!o.GetType().IsValueType || o.GetType().IsEnum) && _objectsBackMap.TryGetValue(o, out index);

            if (found)
            {
                luaState.GetMetaTable("luaNet_objects");
                luaState.RawGetInteger(-1, index);

                // Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep
                // occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later.  During that window we might call
                // this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called.  In that case, we go ahead and call collect
                // object here
                // did we find a non nil object in our table? if not, we need to call collect object
                var type = luaState.Type(-1);
                if (type != LuaType.Nil)
                {
                    luaState.Remove(-2);         // drop the metatable - we're going to leave our object on the stack
                    return;
                }

                // MetaFunctions.dumpStack(this, luaState);
                luaState.Remove(-1);     // remove the nil object value
                luaState.Remove(-1);     // remove the metatable
                CollectObject(o, index); // Remove from both our tables and fall out to get a new ID
            }

            index = AddObject(o);
            PushNewObject(luaState, o, index, metatable);
        }
예제 #9
0
        public static int ToNetObject(this LuaState state, int index, IntPtr tag)
        {
            if (state.Type(index) != LuaType.UserData)
            {
                return(-1);
            }

            IntPtr userData;

            if (state.CheckMetaTable(index, tag))
            {
                userData = state.ToUserData(index);
                if (userData != IntPtr.Zero)
                {
                    return(Marshal.ReadInt32(userData));
                }
            }

            userData = state.CheckUData(index, "luaNet_class");
            if (userData != IntPtr.Zero)
            {
                return(Marshal.ReadInt32(userData));
            }

            userData = state.CheckUData(index, "luaNet_searchbase");
            if (userData != IntPtr.Zero)
            {
                return(Marshal.ReadInt32(userData));
            }

            userData = state.CheckUData(index, "luaNet_function");
            if (userData != IntPtr.Zero)
            {
                return(Marshal.ReadInt32(userData));
            }

            return(-1);
        }
예제 #10
0
        private int UnregisterTableInternal(LuaState luaState)
        {
            if (!luaState.GetMetaTable(1))
            {
                ThrowError(luaState, "unregister_table: arg is not valid table");
                return(0);
            }

            luaState.PushString("__index");
            luaState.GetTable(-2);
            var obj = GetRawNetObject(luaState, -1);

            if (obj == null)
            {
                ThrowError(luaState, "unregister_table: arg is not valid table");
            }

            if (obj != null)
            {
                var luaTableField = obj.GetType().GetField("__luaInterface_luaTable");

                if (luaTableField == null)
                {
                    ThrowError(luaState, "unregister_table: arg is not valid table");
                }

                // ReSharper disable once PossibleNullReferenceException
                luaTableField.SetValue(obj, null);
            }

            luaState.PushNil();
            luaState.SetMetaTable(1);
            luaState.PushString("base");
            luaState.PushNil();
            luaState.SetTable(1);

            return(0);
        }
예제 #11
0
 public static void PopGlobalTable(this LuaState luaState)
 {
     if (!luaState.IsTable(-1))
     {
         throw new Exception("expect table - " + luaState.Type(-1).ToString());
     }
     //REG[2]=value at top?
     //luaState.RawSetInteger(LuaRegistry.Index, (long) LuaRegistryIndex.Globals);
     luaState.GetGlobal("setfenv");
     if (!luaState.IsCFunction(-1))
     {
         throw new Exception("expect setfenv");
     }
     luaState.PushInteger(1);
     luaState.PushCopy(-3);
     try
     {
         luaState.Call(2, 0);
     }catch (Exception e)
     {
         Debug.WriteLine(e.Message);
     }
 }
예제 #12
0
        public ObjectTranslator(Lua interpreter, LuaState luaState)
        {
            _tagPtr          = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
            this.interpreter = interpreter;
            typeChecker      = new CheckType(this);
            metaFunctions    = new MetaFunctions(this);
            assemblies       = new List <Assembly>();

            _importTypeFunction        = ImportType;
            _loadAssemblyFunction      = LoadAssembly;
            _registerTableFunction     = RegisterTable;
            _unregisterTableFunction   = UnregisterTable;
            _getMethodSigFunction      = GetMethodSignature;
            _getConstructorSigFunction = GetConstructorSignature;
            _ctypeFunction             = CType;
            _enumFromIntFunction       = EnumFromInt;

            CreateLuaObjectList(luaState);
            CreateIndexingMetaFunction(luaState);
            CreateBaseClassMetatable(luaState);
            CreateClassMetatable(luaState);
            CreateFunctionMetatable(luaState);
            SetGlobalFunctions(luaState);
        }
예제 #13
0
        private int GetConstructorSignatureInternal(LuaState luaState)
        {
            ProxyType klass = null;
            int       udata = luaState.CheckUObject(1, "luaNet_class");

            if (udata != -1)
            {
                klass = (ProxyType)_objects[udata];
            }

            if (klass == null)
            {
                ThrowError(luaState, "get_constructor_bysig: first arg is invalid type reference");
            }

            var signature = new Type[luaState.GetTop() - 1];

            for (int i = 0; i < signature.Length; i++)
            {
                signature[i] = FindType(luaState.ToString(i + 2, false));
            }

            try
            {
                ConstructorInfo constructor    = klass.UnderlyingSystemType.GetConstructor(signature);
                var             wrapper        = new LuaMethodWrapper(this, null, klass, constructor);
                var             invokeDelegate = wrapper.InvokeFunction;
                PushFunction(luaState, invokeDelegate);
            }
            catch (Exception e)
            {
                ThrowError(luaState, e);
                luaState.PushNil();
            }
            return(1);
        }
예제 #14
0
        /*
         * Gets an object from the Lua stack with the desired type, if it matches, otherwise
         * returns null.
         */
        internal object GetAsType(LuaState luaState, int stackPos, Type paramType)
        {
            var extractor = typeChecker.CheckLuaType(luaState, stackPos, paramType);

            return(extractor != null?extractor(luaState, stackPos) : null);
        }
예제 #15
0
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool MatchParameters(LuaState luaState, MethodBase method, ref MethodCache methodCache)
 {
     return(metaFunctions.MatchParameters(luaState, method, ref methodCache));
 }
예제 #16
0
 /*
  * Pushes a delegate into the stack
  */
 internal void PushFunction(LuaState luaState, LuaNativeFunction func)
 {
     PushObject(luaState, func, "luaNet_function");
 }
예제 #17
0
 /*
  * Pushes a type reference into the stack
  */
 internal void PushType(LuaState luaState, Type t)
 {
     PushObject(luaState, new ProxyType(t), "luaNet_class");
 }
예제 #18
0
        public static void NewUData(this LuaState state, int val)
        {
            IntPtr pointer = state.NewUserData(Marshal.SizeOf(typeof(int)));

            Marshal.WriteInt32(pointer, val);
        }
예제 #19
0
        private int LoadAssemblyInternal(LuaState luaState)
        {
            try
            {
                string    assemblyName = luaState.ToString(1, false);
                Assembly  assembly     = null;
                Exception exception    = null;

                try
                {
                    assembly = Assembly.Load(assemblyName);
                }
                catch (BadImageFormatException)
                {
                    // The assemblyName was invalid.  It is most likely a path.
                }
                catch (FileNotFoundException e)
                {
                    exception = e;
                }

                if (assembly == null)
                {
                    try
                    {
                        assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
                    }
                    catch (FileNotFoundException e)
                    {
                        exception = e;
                    }
                    if (assembly == null)
                    {
                        AssemblyName mscor = assemblies[0].GetName();
                        AssemblyName name  = new AssemblyName();
                        name.Name        = assemblyName;
                        name.CultureInfo = mscor.CultureInfo;
                        name.Version     = mscor.Version;
                        name.SetPublicKeyToken(mscor.GetPublicKeyToken());
                        name.SetPublicKey(mscor.GetPublicKey());
                        assembly = Assembly.Load(name);

                        if (assembly != null)
                        {
                            exception = null;
                        }
                    }
                    if (exception != null)
                    {
                        ThrowError(luaState, exception);
                    }
                }
                if (assembly != null && !assemblies.Contains(assembly))
                {
                    assemblies.Add(assembly);
                }
            }
            catch (Exception e)
            {
                ThrowError(luaState, e);
            }
            return(0);
        }
예제 #20
0
 static int PushError(LuaState luaState, string msg)
 {
     luaState.PushNil();
     luaState.PushString(msg);
     return(2);
 }
예제 #21
0
 public static bool IsNumericType(this LuaState state, int index)
 {
     return(state.Type(index) == LuaType.Number);
 }
예제 #22
0
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool MatchParameters(LuaState luaState, MethodBase method, MethodCache methodCache, int skipParam)
 {
     return(metaFunctions.MatchParameters(luaState, method, methodCache, skipParam));
 }
예제 #23
0
 internal Array TableToArray(LuaState luaState, ExtractValue extractValue, Type paramArrayType, int startIndex, int count)
 {
     return(metaFunctions.TableToArray(luaState, extractValue, paramArrayType, ref startIndex, count));
 }
예제 #24
0
 /*
  * Registers the indexing function of CLR objects
  * passed to Lua
  */
 private void CreateIndexingMetaFunction(LuaState luaState)
 {
     luaState.PushString("luaNet_indexfunction");
     luaState.DoString(MetaFunctions.LuaIndexFunction);
     luaState.RawSet(LuaRegistry.Index);
 }
예제 #25
0
 public static void GetRef(this LuaState luaState, int reference)
 {
     luaState.RawGetInteger(LuaRegistry.Index, reference);
 }
예제 #26
0
        /*
         * Gets the CLR object in the index positon of the Lua stack. Returns
         * delegates as Lua functions.
         */
        internal object GetNetObject(LuaState luaState, int index)
        {
            int idx = luaState.ToNetObject(index, Tag);

            return(idx != -1 ? _objects[idx] : null);
        }
예제 #27
0
 // ReSharper disable once IdentifierTypo
 public static void Unref(this LuaState luaState, int reference)
 {
     luaState.Unref(LuaRegistry.Index, reference);
 }
예제 #28
0
 public static bool AreEqual(this LuaState luaState, int ref1, int ref2)
 {
     return(luaState.Compare(ref1, ref2, LuaCompare.Equal));
 }
예제 #29
0
        /*
         * Gets the CLR object in the index position of the Lua stack. Returns
         * delegates as is.
         */
        internal object GetRawNetObject(LuaState luaState, int index)
        {
            int udata = luaState.RawNetObj(index);

            return(udata != -1 ? _objects[udata] : null);
        }
예제 #30
0
 /*
  * Pushes the object into the Lua stack according to its type.
  */
 internal void Push(LuaState luaState, object o)
 {
     if (o == null)
     {
         luaState.PushNil();
     }
     else if (o is sbyte sb)
     {
         luaState.PushInteger(sb);
     }
     else if (o is byte bt)
     {
         luaState.PushInteger(bt);
     }
     else if (o is short s)
     {
         luaState.PushInteger(s);
     }
     else if (o is ushort us)
     {
         luaState.PushInteger(us);
     }
     else if (o is int i)
     {
         luaState.PushInteger(i);
     }
     else if (o is uint ui)
     {
         luaState.PushInteger(ui);
     }
     else if (o is long l)
     {
         luaState.PushInteger(l);
     }
     else if (o is ulong ul)
     {
         luaState.PushInteger((long)ul);
     }
     else if (o is char ch)
     {
         luaState.PushInteger(ch);
     }
     else if (o is float fl)
     {
         luaState.PushNumber(fl);
     }
     else if (o is decimal dc)
     {
         luaState.PushNumber((double)dc);
     }
     else if (o is double db)
     {
         luaState.PushNumber(db);
     }
     else if (o is string str)
     {
         luaState.PushString(str);
     }
     else if (o is bool b)
     {
         luaState.PushBoolean(b);
     }
     else if (IsILua(o))
     {
         ((ILuaGeneratedType)o).LuaInterfaceGetLuaTable().Push(luaState);
     }
     else if (o is LuaTable table)
     {
         table.Push(luaState);
     }
     else if (o is LuaNativeFunction nativeFunction)
     {
         PushFunction(luaState, nativeFunction);
     }
     else if (o is LuaFunction luaFunction)
     {
         luaFunction.Push(luaState);
     }
     else
     {
         PushObject(luaState, o, "luaNet_metatable");
     }
 }