public ObjectTranslator Find(LuaCore.lua_State luaState) { if (!translators.ContainsKey(luaState)) return null; return translators [luaState]; }
public void Remove(LuaCore.lua_State luaState) { if (!translators.ContainsKey (luaState)) return; translators.Remove (luaState); }
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); }
// 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); }
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); }
/* * 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); }
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); }
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); }