public void Remove(LuaState luaState) { if (!translators.ContainsKey (luaState)) return; translators.Remove (luaState); }
public ObjectTranslator Find(LuaState luaState) { if (!translators.ContainsKey(luaState)) return null; return translators [luaState]; }
private object getAsChar(KopiLua.LuaState luaState, int stackPos) { char retVal = (char)LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsDouble(KopiLua.LuaState luaState, int stackPos) { double retVal = LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsUlong(KopiLua.LuaState luaState, int stackPos) { ulong retVal = (ulong)LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsInt(KopiLua.LuaState luaState, int stackPos) { int retVal = (int)LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsByte(KopiLua.LuaState luaState, int stackPos) { byte retVal = (byte)LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
/* * Creates the metatable for delegates */ private void createFunctionMetatable(KopiLua.LuaState luaState) { LuaDll.luaL_newmetatable(luaState, "luaNet_function"); LuaDll.lua_pushstring(luaState, "__gc"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__call"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.execDelegateFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_settop(luaState, -2); }
/* * Sets up the list of objects in the Lua side */ private void createLuaObjectList(KopiLua.LuaState luaState) { LuaDll.lua_pushstring(luaState, "luaNet_objects"); LuaDll.lua_newtable(luaState); LuaDll.lua_newtable(luaState); LuaDll.lua_pushstring(luaState, "__mode"); LuaDll.lua_pushstring(luaState, "v"); LuaDll.lua_settable(luaState, -3); LuaDll.lua_setmetatable(luaState, -2); LuaDll.lua_settable(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); }
/* * Pushes the function into the Lua stack */ internal void push(KopiLua.LuaState luaState) { if (reference != 0) { LuaDll.lua_getref(luaState, reference); } else { interpreter.pushCSFunction(function); } }
/* * Writes to fields or properties, either static or instance. Throws an error * if the operation is invalid. */ private int setMember(KopiLua.LuaState luaState, IReflect targetType, object target, BindingFlags bindingType) { string detail; bool success = trySetMember(luaState, targetType, target, bindingType, out detail); if (!success) { translator.throwError(luaState, detail); } return(0); }
/// <summary> /// Convert a C# exception into a Lua error /// </summary> /// <param name="e"></param> /// We try to look into the exception to give the most meaningful description void ThrowError(KopiLua.LuaState luaState, Exception e) { // If we got inside a reflection show what really happened TargetInvocationException te = e as TargetInvocationException; if (te != null) { e = te.InnerException; } translator.throwError(luaState, e); }
public ObjectTranslator Find(LuaState luaState) { if (translators.ContainsKey (luaState)) return translators [luaState]; LuaState main = LuaCore.LuaNetGetMainState (luaState); if (translators.ContainsKey (main)) return translators [main]; return null; }
/* * Gets the CLR object in the index positon of the Lua stack. Returns * delegates as Lua functions. */ internal object getNetObject(KopiLua.LuaState luaState, int index) { int idx = LuaDll.luanet_tonetobject(luaState, index); if (idx != -1) { return(objects[idx]); } else { return(null); } }
/* * __gc metafunction of CLR objects. */ private int collectObject(KopiLua.LuaState luaState) { int udata = LuaDll.luanet_rawnetobj(luaState, 1); if (udata != -1) { translator.collectObject(udata); } else { // Debug.WriteLine("not found: " + udata); } return(0); }
/* * __tostring metafunction of CLR objects. */ private int toString(KopiLua.LuaState luaState) { object obj = translator.getRawNetObject(luaState, 1); if (obj != null) { translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode()); } else { LuaDll.lua_pushnil(luaState); } return(1); }
/* * Pushes the object into the Lua stack according to its type. */ internal void push(KopiLua.LuaState luaState, object o) { if (o == null) { LuaDll.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); LuaDll.lua_pushnumber(luaState, d); } else if (o is char) { double d = (char)o; LuaDll.lua_pushnumber(luaState, d); } else if (o is string) { string str = (string)o; LuaDll.lua_pushstring(luaState, str); } else if (o is bool) { bool b = (bool)o; LuaDll.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 KopiLua.LuaNativeFunction) { pushFunction(luaState, (KopiLua.LuaNativeFunction)o); } else if (o is LuaFunction) { ((LuaFunction)o).push(luaState); } else { pushObject(luaState, o, "luaNet_metatable"); } }
/* * Pushes the entire array into the Lua stack and returns the number * of elements pushed. */ internal int returnValues(KopiLua.LuaState luaState, object[] returnValues) { if (LuaDll.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 import_type. Returns nil if the * type is not found. */ private int importType(KopiLua.LuaState luaState) { string className = LuaDll.lua_tostring(luaState, 1); Type klass = FindType(className); if (klass != null) { pushType(luaState, klass); } else { LuaDll.lua_pushnil(luaState); } return(1); }
/* * Gets an object from the Lua stack according to its Lua type. */ internal object getObject(KopiLua.LuaState luaState, int index) { LuaTypes type = LuaDll.lua_type(luaState, index); switch (type) { case LuaTypes.LUA_TNUMBER: { return(LuaDll.lua_tonumber(luaState, index)); } case LuaTypes.LUA_TSTRING: { return(LuaDll.lua_tostring(luaState, index)); } case LuaTypes.LUA_TBOOLEAN: { return(LuaDll.lua_toboolean(luaState, index)); } case LuaTypes.LUA_TTABLE: { return(getTable(luaState, index)); } case LuaTypes.LUA_TFUNCTION: { return(getFunction(luaState, index)); } case LuaTypes.LUA_TUSERDATA: { int udata = LuaDll.luanet_tonetobject(luaState, index); if (udata != -1) { return(objects[udata]); } else { return(getUserData(luaState, index)); } } default: return(null); } }
/* * Pushes a new object into the Lua stack with the provided * metatable */ private void pushNewObject(KopiLua.LuaState luaState, object o, int index, string metatable) { if (metatable == "luaNet_metatable") { // Gets or creates the metatable for the object's type LuaDll.luaL_getmetatable(luaState, o.GetType().AssemblyQualifiedName); if (LuaDll.lua_isnil(luaState, -1)) { LuaDll.lua_settop(luaState, -2); LuaDll.luaL_newmetatable(luaState, o.GetType().AssemblyQualifiedName); LuaDll.lua_pushstring(luaState, "cache"); LuaDll.lua_newtable(luaState); LuaDll.lua_rawset(luaState, -3); LuaDll.lua_pushlightuserdata(luaState, LuaDll.luanet_gettag()); LuaDll.lua_pushnumber(luaState, 1); LuaDll.lua_rawset(luaState, -3); LuaDll.lua_pushstring(luaState, "__index"); LuaDll.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDll.lua_rawget(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDll.lua_rawset(luaState, -3); LuaDll.lua_pushstring(luaState, "__gc"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDll.lua_rawset(luaState, -3); LuaDll.lua_pushstring(luaState, "__tostring"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDll.lua_rawset(luaState, -3); LuaDll.lua_pushstring(luaState, "__newindex"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDll.lua_rawset(luaState, -3); } } else { LuaDll.luaL_getmetatable(luaState, metatable); } // Stores the object index in the Lua list and pushes the // index into the Lua stack LuaDll.luaL_getmetatable(luaState, "luaNet_objects"); LuaDll.luanet_newudata(luaState, index); LuaDll.lua_pushvalue(luaState, -3); LuaDll.lua_remove(luaState, -4); LuaDll.lua_setmetatable(luaState, -2); LuaDll.lua_pushvalue(luaState, -1); LuaDll.lua_rawseti(luaState, -3, index); LuaDll.lua_remove(luaState, -2); }
/* * __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(KopiLua.LuaState luaState) { MethodCache validConstructor = new MethodCache(); IReflect klass; object obj = translator.getRawNetObject(luaState, 1); if (obj == null || !(obj is IReflect)) { translator.throwError(luaState, "trying to call constructor on an invalid type reference"); LuaDll.lua_pushnil(luaState); return(1); } else { klass = (IReflect)obj; } LuaDll.lua_remove(luaState, 1); ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors(); foreach (ConstructorInfo 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); LuaDll.lua_pushnil(luaState); } catch { LuaDll.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)); LuaDll.lua_pushnil(luaState); return(1); }
/* * __newindex function of type references, works on static members. */ private int setClassFieldOrProperty(KopiLua.LuaState luaState) { IReflect target; object obj = translator.getRawNetObject(luaState, 1); if (obj == null || !(obj is IReflect)) { translator.throwError(luaState, "trying to index an invalid type reference"); return(0); } else { target = (IReflect)obj; } return(setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static)); }
/* * Implementation of load_assembly. Throws an error * if the assembly is not found. */ private int loadAssembly(KopiLua.LuaState luaState) { string assemblyName = LuaDll.lua_tostring(luaState, 1); try { if (assemblyName == "System.Windows.Forms") { assemblyName = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } if (assemblyName == "System.Drawing") { assemblyName = "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; } if (assemblyName == "UnityEngine") { assemblyName = "UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; } Assembly assembly = null; try { assembly = Assembly.Load(assemblyName); // If we couldn't find it based on a name, see if we can use it as a filename and find it if (assembly == null) { assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName)); } } catch (Exception) { // ignore - it might not even be a filename } if (assembly != null && !assemblies.Contains(assembly)) { assemblies.Add(assembly); } } catch (Exception e) { throwError(luaState, e); } return(0); }
/* * Implementation of get_method_bysig. Returns nil * if no matching method is not found. */ private int getMethodSignature(KopiLua.LuaState luaState) { IReflect klass; object target; int udata = LuaDll.luanet_checkudata(luaState, 1, "luaNet_class"); if (udata != -1) { klass = (IReflect)objects[udata]; target = null; } else { target = getRawNetObject(luaState, 1); if (target == null) { throwError(luaState, "get_method_bysig: first arg is not type or object reference"); LuaDll.lua_pushnil(luaState); return(1); } klass = target.GetType(); } string methodName = LuaDll.lua_tostring(luaState, 2); Type[] signature = new Type[LuaDll.lua_gettop(luaState) - 2]; for (int i = 0; i < signature.Length; i++) { string typeName = LuaDll.lua_tostring(luaState, i + 3); signature[i] = FindType(typeName); if (signature[i] == null) { throwError(luaState, string.Format("Type not found: {0}", typeName)); } } try { MethodInfo method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy, null, signature, null); pushFunction(luaState, new KopiLua.LuaNativeFunction((new LuaMethodWrapper(this, target, klass, method)).call)); } catch (Exception e) { throwError(luaState, e); LuaDll.lua_pushnil(luaState); } return(1); }
/* * Registers the global functions used by LuaInterface */ private void setGlobalFunctions(KopiLua.LuaState luaState) { LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.indexFunction); LuaDll.lua_setglobal(luaState, "get_object_member"); LuaDll.lua_pushstdcallcfunction(luaState, importTypeFunction); LuaDll.lua_setglobal(luaState, "import_type"); LuaDll.lua_pushstdcallcfunction(luaState, loadAssemblyFunction); LuaDll.lua_setglobal(luaState, "load_assembly"); LuaDll.lua_pushstdcallcfunction(luaState, registerTableFunction); LuaDll.lua_setglobal(luaState, "make_object"); LuaDll.lua_pushstdcallcfunction(luaState, unregisterTableFunction); LuaDll.lua_setglobal(luaState, "free_object"); LuaDll.lua_pushstdcallcfunction(luaState, getMethodSigFunction); LuaDll.lua_setglobal(luaState, "get_method_bysig"); LuaDll.lua_pushstdcallcfunction(luaState, getConstructorSigFunction); LuaDll.lua_setglobal(luaState, "get_constructor_bysig"); }
/* * Creates the metatable for superclasses (the base * field of registered tables) */ private void createBaseClassMetatable(KopiLua.LuaState luaState) { LuaDll.luaL_newmetatable(luaState, "luaNet_searchbase"); LuaDll.lua_pushstring(luaState, "__gc"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__tostring"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__index"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.baseIndexFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__newindex"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_settop(luaState, -2); }
/* * 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(KopiLua.LuaState luaState) { if (LuaDll.lua_type(luaState, 1) == LuaTypes.LUA_TTABLE) { LuaTable luaTable = getTable(luaState, 1); string superclassName = LuaDll.lua_tostring(luaState, 2); if (superclassName != null) { Type klass = FindType(superclassName); if (klass != null) { // 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"); LuaDll.lua_newtable(luaState); LuaDll.lua_pushstring(luaState, "__index"); LuaDll.lua_pushvalue(luaState, -3); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__newindex"); LuaDll.lua_pushvalue(luaState, -3); LuaDll.lua_settable(luaState, -3); LuaDll.lua_setmetatable(luaState, 1); // Pushes the object again, this time as the base field // of the table and with the luaNet_searchbase metatable LuaDll.lua_pushstring(luaState, "base"); int index = addObject(obj); pushNewObject(luaState, obj, index, "luaNet_searchbase"); LuaDll.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); }
/* * Gets the values from the provided index to * the top of the stack and returns them in an array. */ internal object[] popValues(KopiLua.LuaState luaState, int oldTop) { int newTop = LuaDll.lua_gettop(luaState); if (oldTop == newTop) { return(null); } else { ArrayList returnValues = new ArrayList(); for (int i = oldTop + 1; i <= newTop; i++) { returnValues.Add(getObject(luaState, i)); } LuaDll.lua_settop(luaState, oldTop); return(returnValues.ToArray()); } }
/* * Pushes a CLR object into the Lua stack as an userdata * with the provided metatable */ internal void pushObject(KopiLua.LuaState luaState, object o, string metatable) { int index = -1; // Pushes nil if (o == null) { LuaDll.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) { LuaDll.luaL_getmetatable(luaState, "luaNet_objects"); LuaDll.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 LuaTypes type = LuaDll.lua_type(luaState, -1); if (type != LuaTypes.LUA_TNIL) { LuaDll.lua_remove(luaState, -2); // drop the metatable - we're going to leave our object on the stack return; } // MetaFunctions.dumpStack(this, luaState); LuaDll.lua_remove(luaState, -1); // remove the nil object value LuaDll.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); }
/* * Creates the metatable for type references */ private void createClassMetatable(KopiLua.LuaState luaState) { LuaDll.luaL_newmetatable(luaState, "luaNet_class"); LuaDll.lua_pushstring(luaState, "__gc"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__tostring"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__index"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.classIndexFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__newindex"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.classNewindexFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_pushstring(luaState, "__call"); LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.callConstructorFunction); LuaDll.lua_settable(luaState, -3); LuaDll.lua_settop(luaState, -2); }
public ObjectTranslator(Lua interpreter, KopiLua.LuaState luaState) { this.interpreter = interpreter; typeChecker = new CheckType(this); metaFunctions = new MetaFunctions(this); assemblies = new List <Assembly>(); importTypeFunction = new KopiLua.LuaNativeFunction(this.importType); loadAssemblyFunction = new KopiLua.LuaNativeFunction(this.loadAssembly); registerTableFunction = new KopiLua.LuaNativeFunction(this.registerTable); unregisterTableFunction = new KopiLua.LuaNativeFunction(this.unregisterTable); getMethodSigFunction = new KopiLua.LuaNativeFunction(this.getMethodSignature); getConstructorSigFunction = new KopiLua.LuaNativeFunction(this.getConstructorSignature); createLuaObjectList(luaState); createIndexingMetaFunction(luaState); createBaseClassMetatable(luaState); createClassMetatable(luaState); createFunctionMetatable(luaState); setGlobalFunctions(luaState); }
/// <summary> /// Debug tool to dump the lua stack /// </summary> /// FIXME, move somewhere else public static void dumpStack(ObjectTranslator translator, KopiLua.LuaState luaState) { int depth = LuaDll.lua_gettop(luaState); Debug.WriteLine("lua stack depth: " + depth); for (int i = 1; i <= depth; i++) { LuaTypes type = LuaDll.lua_type(luaState, i); // we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types string typestr = (type == LuaTypes.LUA_TTABLE) ? "table" : LuaDll.lua_typename(luaState, type); string strrep = LuaDll.lua_tostring(luaState, i); if (type == LuaTypes.LUA_TUSERDATA) { object obj = translator.getRawNetObject(luaState, i); strrep = obj.ToString(); } Debug.Print("{0}: ({1}) {2}", i, typestr, strrep); } }
public static void LuaGetField(LuaState luaState, int stackPos, string meta) { LuaCore.LuaGetField (luaState, stackPos, meta); }
public static int LuaGC(LuaState luaState, GCOptions what, int data) { return LuaCore.LuaGC (luaState, (int)what, data); }
public static void LuaError(LuaState luaState) { LuaCore.LuaError (luaState); }
public static LuaNativeFunction LuaToCFunction(LuaState luaState, int index) { return LuaCore.LuaToCFunction (luaState, index); }
public static void LuaRawSetI(LuaState luaState, int tableIndex, int index) { LuaCore.LuaRawSetI (luaState, tableIndex, index); }
public object ExtractGenerated(LuaState luaState, int stackPos) { return CodeGeneration.Instance.GetClassInstance (klass, translator.GetTable (luaState, stackPos)); }
public static void LuaUnref(LuaState luaState, int reference) { LuaCore.LuaLUnref (luaState, (int)LuaIndexes.Registry, reference); }
public static void LuaAtPanic(LuaState luaState, LuaNativeFunction panicf) { LuaCore.LuaAtPanic (luaState, (LuaNativeFunction)panicf); }
public static LuaTypes LuaType(LuaState luaState, int index) { return (LuaTypes)LuaCore.LuaType (luaState, index); }
public static string LuaTypeName(LuaState luaState, LuaTypes type) { return LuaCore.LuaTypeName (luaState, (int)type).ToString (); }
public static void LuaReplace(LuaState luaState, int index) { LuaCore.LuaReplace (luaState, index); }
public static void LuaSetTop(LuaState luaState, int newTop) { LuaCore.LuaSetTop (luaState, newTop); }
public static double LuaToNumber(LuaState luaState, int index) { return LuaCore.LuaNetToNumber (luaState, index); }
public static void LuaGetGlobal(LuaState luaState, string name) { LuaCore.LuaNetGetGlobal (luaState, name); }
public static void LuaCall(LuaState luaState, int nArgs, int nResults) { LuaCore.LuaCall (luaState, nArgs, nResults); }
/* * Pushes this table into the Lua stack */ internal void Push(LuaState luaState) { LuaLib.LuaGetRef (luaState, _Reference); }
public static bool LuaCheckStack(LuaState luaState, int extra) { return LuaCore.LuaCheckStack (luaState, extra) != 0; }
/* * Calls the method. Receives the arguments from the Lua stack * and returns values in it. */ int Call(LuaState luaState) { var methodToCall = _Method; object targetObject = _Target; bool failedCall = true; int nReturnValues = 0; if (!LuaLib.LuaCheckStack (luaState, 5)) throw new LuaException ("Lua stack overflow"); bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; SetPendingException (null); if (methodToCall == null) { // Method from name if (isStatic) targetObject = null; else targetObject = _ExtractTarget (luaState, 1); if (_LastCalledMethod.cachedMethod != null) { // Cached? int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject int numArgsPassed = LuaLib.LuaGetTop (luaState) - numStackToSkip; MethodBase method = _LastCalledMethod.cachedMethod; if (numArgsPassed == _LastCalledMethod.argTypes.Length) { // No. of args match? if (!LuaLib.LuaCheckStack (luaState, _LastCalledMethod.outList.Length + 6)) throw new LuaException ("Lua stack overflow"); object [] args = _LastCalledMethod.args; try { for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) { MethodArgs type = _LastCalledMethod.argTypes [i]; int index = i + 1 + numStackToSkip; Func<int, object> valueExtractor = (currentParam) => { return type.extractValue (luaState, currentParam); }; if (_LastCalledMethod.argTypes [i].isParamsArray) { int count = index - _LastCalledMethod.argTypes.Length; Array paramArray = _Translator.TableToArray (valueExtractor, type.paramsArrayType, index, count); args [_LastCalledMethod.argTypes [i].index] = paramArray; } else { args [type.index] = valueExtractor (index); } if (_LastCalledMethod.args [_LastCalledMethod.argTypes [i].index] == null && !LuaLib.LuaIsNil (luaState, i + 1 + numStackToSkip)) throw new LuaException (string.Format("argument number {0} is invalid",(i + 1))); } if ((_BindingType & BindingFlags.Static) == BindingFlags.Static) _Translator.Push (luaState, method.Invoke (null, _LastCalledMethod.args)); else { if (method.IsConstructor) _Translator.Push (luaState, ((ConstructorInfo)method).Invoke (_LastCalledMethod.args)); else _Translator.Push (luaState, method.Invoke (targetObject, _LastCalledMethod.args)); } failedCall = false; } catch (TargetInvocationException e) { // Failure of method invocation return SetPendingException (e.GetBaseException ()); } catch (Exception e) { if (_Members.Length == 1) // Is the method overloaded? // No, throw error return SetPendingException (e); } } } // Cache miss if (failedCall) { // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); // If we are running an instance variable, we can now pop the targetObject from the stack if (!isStatic) { if (targetObject == null) { _Translator.ThrowError (luaState, String.Format ("instance method '{0}' requires a non null target object", _MethodName)); LuaLib.LuaPushNil (luaState); return 1; } LuaLib.LuaRemove (luaState, 1); // Pops the receiver } bool hasMatch = false; string candidateName = null; foreach (var member in _Members) { candidateName = member.ReflectedType.Name + "." + member.Name; var m = (MethodInfo)member; bool isMethod = _Translator.MatchParameters (luaState, m, ref _LastCalledMethod); if (isMethod) { hasMatch = true; break; } } if (!hasMatch) { string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName); _Translator.ThrowError (luaState, msg); LuaLib.LuaPushNil (luaState); return 1; } } } else { // Method from MethodBase instance if (methodToCall.ContainsGenericParameters) { _Translator.MatchParameters (luaState, methodToCall, ref _LastCalledMethod); if (methodToCall.IsGenericMethodDefinition) { //need to make a concrete type of the generic method definition var typeArgs = new List<Type> (); foreach (object arg in _LastCalledMethod.args) typeArgs.Add (arg.GetType ()); var concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod (typeArgs.ToArray ()); _Translator.Push (luaState, concreteMethod.Invoke (targetObject, _LastCalledMethod.args)); failedCall = false; } else if (methodToCall.ContainsGenericParameters) { _Translator.ThrowError (luaState, "unable to invoke method on generic class as the current method is an open generic method"); LuaLib.LuaPushNil (luaState); return 1; } } else { if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) { targetObject = _ExtractTarget (luaState, 1); LuaLib.LuaRemove (luaState, 1); // Pops the receiver } if (!_Translator.MatchParameters (luaState, methodToCall, ref _LastCalledMethod)) { _Translator.ThrowError (luaState, "invalid arguments to method call"); LuaLib.LuaPushNil (luaState); return 1; } } } if (failedCall) { if (!LuaLib.LuaCheckStack (luaState, _LastCalledMethod.outList.Length + 6)) throw new LuaException ("Lua stack overflow"); try { if (isStatic) _Translator.Push (luaState, _LastCalledMethod.cachedMethod.Invoke (null, _LastCalledMethod.args)); else { if (_LastCalledMethod.cachedMethod.IsConstructor) _Translator.Push (luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke (_LastCalledMethod.args)); else _Translator.Push (luaState, _LastCalledMethod.cachedMethod.Invoke (targetObject, _LastCalledMethod.args)); } } catch (TargetInvocationException e) { return SetPendingException (e.GetBaseException ()); } catch (Exception e) { return SetPendingException (e); } } // Pushes out and ref return values for (int index = 0; index < _LastCalledMethod.outList.Length; index++) { nReturnValues++; _Translator.Push (luaState, _LastCalledMethod.args [_LastCalledMethod.outList [index]]); } //by isSingle 2010-09-10 11:26:31 //Desc: // if not return void,we need add 1, // or we will lost the function's return value // when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) nReturnValues++; return nReturnValues < 1 ? 1 : nReturnValues; }
public static void LuaCreateTable(LuaState luaState, int narr, int nrec) { LuaCore.LuaCreateTable (luaState, narr, nrec); }
public static int LuaRef(LuaState luaState, int lockRef) { return lockRef != 0 ? LuaLRef (luaState, (int)LuaIndexes.Registry) : 0; }
public static int LuaEqual(LuaState luaState, int index1, int index2) { return LuaCore.LuaNetEqual (luaState, index1, index2); }
public static string LuaToString(LuaState luaState, int index) { // FIXME use the same format string as lua i.e. LUA_NUMBER_FMT var t = LuaType (luaState, index); if (t == LuaTypes.Number) return string.Format ("{0}", LuaToNumber (luaState, index)); else if (t == LuaTypes.String) { uint strlen; // Changed 2013-05-18 by Dirk Weltz // Changed because binary chunks, which are also transfered as strings // get corrupted by conversion to strings because of the encoding. // So we use the ToString method with string length, so it could be checked, // if string is a binary chunk and if, could transfered to string without // encoding. return LuaCore.LuaToLString (luaState, index, out strlen).ToString ((int)strlen); } else if (t == LuaTypes.Nil) return null; // treat lua nulls to as C# nulls else return "0"; // Because luaV_tostring does this }
public static bool LuaToBoolean(LuaState luaState, int index) { return LuaCore.LuaToBoolean (luaState, index) != 0; }
public static void LuaSetMetatable(LuaState luaState, int objIndex) { LuaCore.LuaSetMetatable (luaState, objIndex); }
public static object LuaToUserData(LuaState luaState, int index) { return LuaCore.LuaToUserData (luaState, index); }
/* * Pushes the function into the Lua stack */ internal void Push(LuaState luaState) { if (_Reference != 0) LuaLib.LuaGetRef (luaState, _Reference); else _Interpreter.PushCSFunction (function); }
public static void LuaSetTable(LuaState luaState, int index) { LuaCore.LuaSetTable (luaState, index); }