Exemple #1
0
        public ObjectTranslator Find(LuaCore.lua_State luaState)
        {
            if (!translators.ContainsKey(luaState))
                return null;

            return translators [luaState];
        }
Exemple #2
0
        public void Remove(LuaCore.lua_State luaState)
        {
            if (!translators.ContainsKey (luaState))
                return;

            translators.Remove (luaState);
        }
Exemple #3
0
        public static int luaL_dostring(LuaCore.lua_State luaState, string chunk)
        {
            int result = luaL_loadstring (luaState, chunk);
            if (result != 0)
                return result;

            return lua_pcall (luaState, 0, -1, 0);
        }
Exemple #4
0
        // steffenj: END Lua 5.1.1 API change (lua_newtable is gone, lua_createtable is new)
        // steffenj: BEGIN Lua 5.1.1 API change (lua_dofile now in LuaLib as luaL_dofile macro)
        public static int luaL_dofile(LuaCore.lua_State luaState, string fileName)
        {
            int result = LuaCore.luaL_loadfile (luaState, fileName);
            if (result != 0)
                return result;

            return LuaCore.lua_pcall (luaState, 0, -1, 0);
        }
Exemple #5
0
        public static bool luaL_checkmetatable(LuaCore.lua_State luaState,int index)
        {
            bool retVal = false;

            if(lua_getmetatable(luaState, index) != 0)
            {
                lua_pushlightuserdata(luaState, tag);
                lua_rawget(luaState, -2);
                retVal = !lua_isnil(luaState, -1);
                lua_settop(luaState, -3);
            }

            return retVal;
        }
        public ObjectTranslator(Lua interpreter, LuaCore.lua_State luaState)
        {
            this.interpreter = interpreter;
            typeChecker = new CheckType(this);
            metaFunctions = new MetaFunctions(this);
            assemblies = new List<Assembly>();

            importTypeFunction = new LuaCore.lua_CFunction(this.importType);
            loadAssemblyFunction = new LuaCore.lua_CFunction(this.loadAssembly);
            registerTableFunction = new LuaCore.lua_CFunction(this.registerTable);
            unregisterTableFunction = new LuaCore.lua_CFunction(this.unregisterTable);
            getMethodSigFunction = new LuaCore.lua_CFunction(this.getMethodSignature);
            getConstructorSigFunction = new LuaCore.lua_CFunction(this.getConstructorSignature);

            createLuaObjectList(luaState);
            createIndexingMetaFunction(luaState);
            createBaseClassMetatable(luaState);
            createClassMetatable(luaState);
            createFunctionMetatable(luaState);
            setGlobalFunctions(luaState);
        }
Exemple #7
0
 /*
  * Pushes the function into the Lua stack
  */
 internal void push(LuaCore.lua_State luaState)
 {
     if(_Reference != 0)
         LuaLib.lua_getref(luaState, _Reference);
     else
         _Interpreter.pushCSFunction(function);
 }
        /*
         * Implementation of free_object. Clears the metatable and the
         * base field, freeing the created object for garbage-collection
         */
        private int unregisterTable(LuaCore.lua_State luaState)
        {
            try
            {
                if(LuaLib.lua_getmetatable(luaState, 1) != 0)
                {
                    LuaLib.lua_pushstring(luaState, "__index");
                    LuaLib.lua_gettable(luaState, -2);
                    object obj = getRawNetObject(luaState, -1);

                    if(obj.IsNull())
                        throwError(luaState, "unregister_table: arg is not valid table");

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

                    if(luaTableField.IsNull())
                        throwError(luaState, "unregister_table: arg is not valid table");

                    luaTableField.SetValue(obj, null);
                    LuaLib.lua_pushnil(luaState);
                    LuaLib.lua_setmetatable(luaState, 1);
                    LuaLib.lua_pushstring(luaState, "base");
                    LuaLib.lua_pushnil(luaState);
                    LuaLib.lua_settable(luaState, 1);
                }
                else
                    throwError(luaState, "unregister_table: arg is not valid table");
            }
            catch(Exception e)
            {
                throwError(luaState, e.Message);
            }

            return 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);
        }
        /*
         * Implementation of import_type. Returns nil if the
         * type is not found.
         */
        private int importType(LuaCore.lua_State luaState)
        {
            string className = LuaLib.lua_tostring(luaState, 1).ToString();
            var klass = FindType(className);

            if(!klass.IsNull())
                pushType(luaState, klass);
            else
                LuaLib.lua_pushnil(luaState);

            return 1;
        }
        /*
         * Implementation of get_constructor_bysig. Returns nil
         * if no matching constructor is found.
         */
        private int getConstructorSignature(LuaCore.lua_State luaState)
        {
            IReflect klass = null;
            int udata = LuaLib.luanet_checkudata(luaState, 1, "luaNet_class");

            if(udata != -1)
                klass = (IReflect)objects[udata];

            if(klass.IsNull())
                throwError(luaState, "get_constructor_bysig: first arg is invalid type reference");

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

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

            try
            {
                ConstructorInfo constructor = klass.UnderlyingSystemType.GetConstructor(signature);
                pushFunction(luaState, new LuaCore.lua_CFunction((new LuaMethodWrapper(this, null, klass, constructor)).call));
            }
            catch(Exception e)
            {
                throwError(luaState, e);
                LuaLib.lua_pushnil(luaState);
            }

            return 1;
        }
 /*
  * Pushes a delegate into the stack
  */
 internal void pushFunction(LuaCore.lua_State luaState, LuaCore.lua_CFunction func)
 {
     pushObject(luaState, func, "luaNet_function");
 }
 /*
  * Pushes the object into the Lua stack according to its type.
  */
 internal void push(LuaCore.lua_State luaState, object o)
 {
     if(o.IsNull())
         LuaLib.lua_pushnil(luaState);
     else if(o is sbyte || o is byte || o is short || o is ushort ||
         o is int || o is uint || o is long || o is float ||
         o is ulong || o is decimal || o is double)
     {
         double d = Convert.ToDouble(o);
         LuaLib.lua_pushnumber(luaState, d);
     }
     else if(o is char)
     {
         double d = (char)o;
         LuaLib.lua_pushnumber(luaState, d);
     }
     else if(o is string)
     {
         string str = (string)o;
         LuaLib.lua_pushstring(luaState, str);
     }
     else if(o is bool)
     {
         bool b = (bool)o;
         LuaLib.lua_pushboolean(luaState, b);
     }
     else if(IsILua(o))
         (((ILuaGeneratedType)o).__luaInterface_getLuaTable()).push(luaState);
     else if(o is LuaTable)
         ((LuaTable)o).push(luaState);
     else if(o is LuaCore.lua_CFunction)
         pushFunction(luaState, (LuaCore.lua_CFunction)o);
     else if(o is LuaFunction)
         ((LuaFunction)o).push(luaState);
     else
         pushObject(luaState, o, "luaNet_metatable");
 }
        /*
         * Gets the values from the provided index to
         * the top of the stack and returns them in an array, casting
         * them to the provided types.
         */
        internal object[] popValues(LuaCore.lua_State luaState, int oldTop, Type[] popTypes)
        {
            int newTop = LuaLib.lua_gettop(luaState);

            if(oldTop == newTop)
                return null;
            else
            {
                int iTypes;
                var returnValues = new ArrayList();

                if(popTypes[0] == typeof(void))
                    iTypes = 1;
                else
                    iTypes = 0;

                for(int i = oldTop+1; i <= newTop; i++)
                {
                    returnValues.Add(getAsType(luaState, i, popTypes[iTypes]));
                    iTypes++;
                }

                LuaLib.lua_settop(luaState, oldTop);
                return returnValues.ToArray();
            }
        }
        /*
         * Gets the values from the provided index to
         * the top of the stack and returns them in an array.
         */
        internal object[] popValues(LuaCore.lua_State luaState, int oldTop)
        {
            int newTop = LuaLib.lua_gettop(luaState);

            if(oldTop == newTop)
                return null;
            else
            {
                var returnValues = new ArrayList();
                for(int i = oldTop+1; i <= newTop; i++)
                    returnValues.Add(getObject(luaState, i));

                LuaLib.lua_settop(luaState, oldTop);
                return returnValues.ToArray();
            }
        }
 /*
  * Registers the indexing function of CLR objects
  * passed to Lua
  */
 private void createIndexingMetaFunction(LuaCore.lua_State luaState)
 {
     LuaLib.lua_pushstring(luaState, "luaNet_indexfunction");
     LuaLib.luaL_dostring(luaState, MetaFunctions.luaIndexFunction);	// steffenj: lua_dostring renamed to luaL_dostring
     //LuaLib.lua_pushstdcallcfunction(luaState, indexFunction);
     LuaLib.lua_rawset(luaState, (int)LuaIndexes.Registry);
 }
 /*
  * Sets up the list of objects in the Lua side
  */
 private void createLuaObjectList(LuaCore.lua_State luaState)
 {
     LuaLib.lua_pushstring(luaState, "luaNet_objects");
     LuaLib.lua_newtable(luaState);
     LuaLib.lua_newtable(luaState);
     LuaLib.lua_pushstring(luaState, "__mode");
     LuaLib.lua_pushstring(luaState, "v");
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_setmetatable(luaState, -2);
     LuaLib.lua_settable(luaState, (int)LuaIndexes.Registry);
 }
        /*
         * 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);
        }
        /*
         * Implementation of get_method_bysig. Returns nil
         * if no matching method is not found.
         */
        private int getMethodSignature(LuaCore.lua_State luaState)
        {
            IReflect klass;
            object target;
            int udata = LuaLib.luanet_checkudata(luaState, 1, "luaNet_class");

            if(udata != -1)
            {
                klass = (IReflect)objects[udata];
                target = null;
            }
            else
            {
                target = getRawNetObject(luaState, 1);

                if(target.IsNull())
                {
                    throwError(luaState, "get_method_bysig: first arg is not type or object reference");
                    LuaLib.lua_pushnil(luaState);
                    return 1;
                }

                klass = target.GetType();
            }

            string methodName = LuaLib.lua_tostring(luaState, 2).ToString();
            var signature = new Type[LuaLib.lua_gettop(luaState)-2];

            for(int i = 0; i < signature.Length; i++)
                signature[i] = FindType(LuaLib.lua_tostring(luaState, i+3).ToString());

            try
            {
                //CP: Added ignore case
                var method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static |
                    BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase, null, signature, null);
                pushFunction(luaState, new LuaCore.lua_CFunction((new LuaMethodWrapper(this, target, klass, method)).call));
            }
            catch(Exception e)
            {
                throwError(luaState, e);
                LuaLib.lua_pushnil(luaState);
            }

            return 1;
        }
 /*
  * Pushes a type reference into the stack
  */
 internal void pushType(LuaCore.lua_State luaState, Type t)
 {
     pushObject(luaState, new ProxyType(t), "luaNet_class");
 }
        /*
         * Implementation of load_assembly. Throws an error
         * if the assembly is not found.
         */
        private int loadAssembly(LuaCore.lua_State luaState)
        {
            try
            {
                string assemblyName = LuaLib.lua_tostring(luaState, 1).ToString();
                Assembly assembly = null;

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

                if(assembly.IsNull())
                    assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));

                if(!assembly.IsNull() && !assemblies.Contains(assembly))
                    assemblies.Add(assembly);
            }
            catch(Exception e)
            {
                throwError(luaState, e);
            }

            return 0;
        }
        /*
         * Pushes the entire array into the Lua stack and returns the number
         * of elements pushed.
         */
        internal int returnValues(LuaCore.lua_State luaState, object[] returnValues)
        {
            if(LuaLib.lua_checkstack(luaState, returnValues.Length+5))
            {
                for(int i = 0; i < returnValues.Length; i++)
                    push(luaState, returnValues[i]);

                return returnValues.Length;
            }
            else
                return 0;
        }
        /*
         * Implementation of make_object. Registers a table (first
         * argument in the stack) as an object subclassing the
         * type passed as second argument in the stack.
         */
        private int registerTable(LuaCore.lua_State luaState)
        {
            if(LuaLib.lua_type(luaState, 1) == LuaTypes.Table)
            {
                var luaTable = getTable(luaState, 1);
                string superclassName = LuaLib.lua_tostring(luaState, 2).ToString();

                if(!superclassName.IsNull())
                {
                    var klass = FindType(superclassName);

                    if(!klass.IsNull())
                    {
                        // Creates and pushes the object in the stack, setting
                        // it as the  metatable of the first argument
                        object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
                        pushObject(luaState, obj, "luaNet_metatable");
                        LuaLib.lua_newtable(luaState);
                        LuaLib.lua_pushstring(luaState, "__index");
                        LuaLib.lua_pushvalue(luaState, -3);
                        LuaLib.lua_settable(luaState, -3);
                        LuaLib.lua_pushstring(luaState, "__newindex");
                        LuaLib.lua_pushvalue(luaState, -3);
                        LuaLib.lua_settable(luaState, -3);
                        LuaLib.lua_setmetatable(luaState, 1);
                        // Pushes the object again, this time as the base field
                        // of the table and with the luaNet_searchbase metatable
                        LuaLib.lua_pushstring(luaState, "base");
                        int index = addObject(obj);
                        pushNewObject(luaState, obj, index, "luaNet_searchbase");
                        LuaLib.lua_rawset(luaState, 1);
                    }
                    else
                        throwError(luaState, "register_table: can not find superclass '" + superclassName + "'");
                }
                else
                    throwError(luaState, "register_table: superclass name can not be null");
            }
            else
                throwError(luaState, "register_table: first arg is not a table");

            return 0;
        }
        /*
         * Passes errors (argument e) to the Lua interpreter
         */
        internal void throwError(LuaCore.lua_State luaState, object e)
        {
            // We use this to remove anything pushed by luaL_where
            int oldTop = LuaLib.lua_gettop(luaState);

            // Stack frame #1 is our C# wrapper, so not very interesting to the user
            // Stack frame #2 must be the lua code that called us, so that's what we want to use
            LuaLib.luaL_where(luaState, 1);
            var curlev = popValues(luaState, oldTop);

            // Determine the position in the script where the exception was triggered
            string errLocation = string.Empty;

            if(curlev.Length > 0)
                errLocation = curlev[0].ToString();

            string message = e as string;

            if(!message.IsNull())
            {
                // Wrap Lua error (just a string) and store the error location
                e = new LuaScriptException(message, errLocation);
            }
            else
            {
                var ex = e as Exception;

                if(!ex.IsNull())
                {
                    // Wrap generic .NET exception as an InnerException and store the error location
                    e = new LuaScriptException(ex, errLocation);
                }
            }

            push(luaState, e);
            LuaLib.lua_error(luaState);
        }
 /*
  * Registers the global functions used by LuaInterface
  */
 private void setGlobalFunctions(LuaCore.lua_State luaState)
 {
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.indexFunction);
     LuaLib.lua_setglobal(luaState, "get_object_member");
     LuaLib.lua_pushstdcallcfunction(luaState, importTypeFunction);
     LuaLib.lua_setglobal(luaState, "import_type");
     LuaLib.lua_pushstdcallcfunction(luaState, loadAssemblyFunction);
     LuaLib.lua_setglobal(luaState, "load_assembly");
     LuaLib.lua_pushstdcallcfunction(luaState, registerTableFunction);
     LuaLib.lua_setglobal(luaState, "make_object");
     LuaLib.lua_pushstdcallcfunction(luaState, unregisterTableFunction);
     LuaLib.lua_setglobal(luaState, "free_object");
     LuaLib.lua_pushstdcallcfunction(luaState, getMethodSigFunction);
     LuaLib.lua_setglobal(luaState, "get_method_bysig");
     LuaLib.lua_pushstdcallcfunction(luaState, getConstructorSigFunction);
     LuaLib.lua_setglobal(luaState, "get_constructor_bysig");
 }
 /*
  * Creates the metatable for superclasses (the base
  * field of registered tables)
  */
 private void createBaseClassMetatable(LuaCore.lua_State luaState)
 {
     LuaLib.luaL_newmetatable(luaState, "luaNet_searchbase");
     LuaLib.lua_pushstring(luaState, "__gc");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__tostring");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__index");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.baseIndexFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__newindex");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_settop(luaState, -2);
 }
Exemple #27
0
 public object extractGenerated(LuaCore.lua_State luaState, int stackPos)
 {
     return CodeGeneration.Instance.GetDelegate (delegateType, translator.getFunction (luaState, stackPos));
 }
 /*
  * Creates the metatable for type references
  */
 private void createClassMetatable(LuaCore.lua_State luaState)
 {
     LuaLib.luaL_newmetatable(luaState, "luaNet_class");
     LuaLib.lua_pushstring(luaState, "__gc");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__tostring");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__index");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.classIndexFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__newindex");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.classNewindexFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__call");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.callConstructorFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_settop(luaState, -2);
 }
Exemple #29
0
 public LuaFunction(LuaCore.lua_CFunction function, Lua interpreter)
 {
     _Reference = 0;
     this.function = function;
     _Interpreter = interpreter;
 }
 /*
  * Creates the metatable for delegates
  */
 private void createFunctionMetatable(LuaCore.lua_State luaState)
 {
     LuaLib.luaL_newmetatable(luaState, "luaNet_function");
     LuaLib.lua_pushstring(luaState, "__gc");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_pushstring(luaState, "__call");
     LuaLib.lua_pushstdcallcfunction(luaState, metaFunctions.execDelegateFunction);
     LuaLib.lua_settable(luaState, -3);
     LuaLib.lua_settop(luaState, -2);
 }