Esempio n. 1
0
        /*
         * __call metafunction of type references. Searches for and calls
         * a constructor for the type. Returns nil if the constructor is not
         * found or if the arguments are invalid. Throws an error if the constructor
         * generates an exception.
         */
        private int callConstructor(LuaCore.lua_State luaState)
        {
            var      validConstructor = new MethodCache();
            IReflect klass;
            object   obj = translator.getRawNetObject(luaState, 1);

            if (obj.IsNull() || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaLib.lua_pushnil(luaState);
                return(1);
            }
            else
            {
                klass = (IReflect)obj;
            }

            LuaLib.lua_remove(luaState, 1);
            var constructors = klass.UnderlyingSystemType.GetConstructors();

            foreach (var constructor in constructors)
            {
                bool isConstructor = matchParameters(luaState, constructor, ref validConstructor);

                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        ThrowError(luaState, e);
                        LuaLib.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaLib.lua_pushnil(luaState);
                    }

                    return(1);
                }
            }

            string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;

            translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
                                                          klass.UnderlyingSystemType, constructorName));
            LuaLib.lua_pushnil(luaState);
            return(1);
        }
Esempio n. 2
0
        /*
         * Pushes a new object into the Lua stack with the provided
         * metatable
         */
        private void pushNewObject(LuaCore.lua_State luaState, object o, int index, string metatable)
        {
            if (metatable == "luaNet_metatable")
            {
                // Gets or creates the metatable for the object's type
                LuaLib.luaL_getmetatable(luaState, o.GetType().AssemblyQualifiedName);

                if (LuaLib.lua_isnil(luaState, -1))
                {
                    LuaLib.lua_settop(luaState, -2);
                    LuaLib.luaL_newmetatable(luaState, o.GetType().AssemblyQualifiedName);
                    LuaLib.lua_pushstring(luaState, "cache");
                    LuaLib.lua_newtable(luaState);
                    LuaLib.lua_rawset(luaState, -3);
                    LuaLib.lua_pushlightuserdata(luaState, LuaLib.luanet_gettag());
                    LuaLib.lua_pushnumber(luaState, 1);
                    LuaLib.lua_rawset(luaState, -3);
                    LuaLib.lua_pushstring(luaState, "__index");
                    LuaLib.lua_pushstring(luaState, "luaNet_indexfunction");
                    LuaLib.lua_rawget(luaState, (int)LuaIndexes.Registry);
                    LuaLib.lua_rawset(luaState, -3);
                    LuaLib.lua_pushstring(luaState, "__gc");
                    LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction);
                    LuaLib.lua_rawset(luaState, -3);
                    LuaLib.lua_pushstring(luaState, "__tostring");
                    LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction);
                    LuaLib.lua_rawset(luaState, -3);
                    LuaLib.lua_pushstring(luaState, "__newindex");
                    LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction);
                    LuaLib.lua_rawset(luaState, -3);
                }
            }
            else
            {
                LuaLib.luaL_getmetatable(luaState, metatable);
            }

            // Stores the object index in the Lua list and pushes the
            // index into the Lua stack
            LuaLib.luaL_getmetatable(luaState, "luaNet_objects");
            LuaLib.luanet_newudata(luaState, index);
            LuaLib.lua_pushvalue(luaState, -3);
            LuaLib.lua_remove(luaState, -4);
            LuaLib.lua_setmetatable(luaState, -2);
            LuaLib.lua_pushvalue(luaState, -1);
            LuaLib.lua_rawseti(luaState, -3, index);
            LuaLib.lua_remove(luaState, -2);
        }
Esempio n. 3
0
        /*
         * Pushes a CLR object into the Lua stack as an userdata
         * with the provided metatable
         */
        internal void pushObject(LuaCore.lua_State luaState, object o, string metatable)
        {
            int index = -1;

            // Pushes nil
            if (o.IsNull())
            {
                LuaLib.lua_pushnil(luaState);
                return;
            }

            // Object already in the list of Lua objects? Push the stored reference.
            bool found = objectsBackMap.TryGetValue(o, out index);

            if (found)
            {
                LuaLib.luaL_getmetatable(luaState, "luaNet_objects");
                LuaLib.lua_rawgeti(luaState, -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 = LuaLib.lua_type(luaState, -1);
                if (type != LuaTypes.Nil)
                {
                    LuaLib.lua_remove(luaState, -2);                             // drop the metatable - we're going to leave our object on the stack
                    return;
                }

                // MetaFunctions.dumpStack(this, luaState);
                LuaLib.lua_remove(luaState, -1);                        // remove the nil object value
                LuaLib.lua_remove(luaState, -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);
        }
Esempio n. 4
0
        public object getAsObject(LuaCore.lua_State luaState, int stackPos)
        {
            if (LuaLib.lua_type(luaState, stackPos) == LuaTypes.Table)
            {
                if (LuaLib.luaL_getmetafield(luaState, stackPos, "__index"))
                {
                    if (LuaLib.luaL_checkmetatable(luaState, -1))
                    {
                        LuaLib.lua_insert(luaState, stackPos);
                        LuaLib.lua_remove(luaState, stackPos + 1);
                    }
                    else
                    {
                        LuaLib.lua_settop(luaState, -2);
                    }
                }
            }

            object obj = translator.getObject(luaState, stackPos);

            return(obj);
        }
Esempio n. 5
0
 /*
  * __call metafunction of CLR delegates, retrieves and calls the delegate.
  */
 private int runFunctionDelegate(LuaCore.lua_State luaState)
 {
     LuaCore.lua_CFunction func = (LuaCore.lua_CFunction)translator.getRawNetObject(luaState, 1);
     LuaLib.lua_remove(luaState, 1);
     return(func(luaState));
 }