/* * 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); }
/* * 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); } }
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); }
/* * 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); } }
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); }
/* * 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"); }
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); }
/* * 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); }
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); }
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); }
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); } }
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); }
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); }
/* * 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); }
/* * 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)); }
/* * Pushes a delegate into the stack */ internal void PushFunction(LuaState luaState, LuaNativeFunction func) { PushObject(luaState, func, "luaNet_function"); }
/* * Pushes a type reference into the stack */ internal void PushType(LuaState luaState, Type t) { PushObject(luaState, new ProxyType(t), "luaNet_class"); }
public static void NewUData(this LuaState state, int val) { IntPtr pointer = state.NewUserData(Marshal.SizeOf(typeof(int))); Marshal.WriteInt32(pointer, val); }
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); }
static int PushError(LuaState luaState, string msg) { luaState.PushNil(); luaState.PushString(msg); return(2); }
public static bool IsNumericType(this LuaState state, int index) { return(state.Type(index) == LuaType.Number); }
/* * 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)); }
internal Array TableToArray(LuaState luaState, ExtractValue extractValue, Type paramArrayType, int startIndex, int count) { return(metaFunctions.TableToArray(luaState, extractValue, paramArrayType, ref startIndex, count)); }
/* * 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); }
public static void GetRef(this LuaState luaState, int reference) { luaState.RawGetInteger(LuaRegistry.Index, reference); }
/* * 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); }
// ReSharper disable once IdentifierTypo public static void Unref(this LuaState luaState, int reference) { luaState.Unref(LuaRegistry.Index, reference); }
public static bool AreEqual(this LuaState luaState, int ref1, int ref2) { return(luaState.Compare(ref1, ref2, LuaCompare.Equal)); }
/* * 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); }
/* * 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"); } }