// lockCallback, unlockCallback; used by debug code commented out for now public LuaInterface() { luaState = LuaDLL.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone) luaState.initializing = true; //LuaDLL.luaopen_base(luaState); // steffenj: luaopen_* no longer used LuaDLL.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here) LuaDLL.lua_pushstring(luaState, "LUAINTERFACE LOADED"); LuaDLL.lua_pushboolean(luaState, true); LuaDLL.lua_settable(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_newtable(luaState); LuaDLL.lua_setglobal(luaState, "luanet"); LuaDLL.lua_pushvalue(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.lua_getglobal(luaState, "luanet"); LuaDLL.lua_pushstring(luaState, "getmetatable"); LuaDLL.lua_getglobal(luaState, "getmetatable"); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); translator = new ObjectTranslator(this, luaState); LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); tracebackFunction = new SharpLua.Lua.lua_CFunction(traceback); // We need to keep this in a managed reference so the delegate doesn't get garbage collected panicCallback = new SharpLua.Lua.lua_CFunction(PanicCallback); Lua.lua_CFunction oldpanicFunc = //LuaDLL.lua_atpanic(luaState, tracebackFunction); LuaDLL.lua_atpanic(luaState, panicCallback); DoString(ScriptStrings.InitLuaNet, "LuaNet"); DoString(ScriptStrings.InitClrLib, "ClrLib"); DoString(ScriptStrings.InitExtLib, "ExtLib"); luaState.initializing = false; luaState.SetInterface(this); }
/* * CAUTION: LuaInterface.Lua instances can't share the same lua state! */ public LuaInterface(SharpLua.Lua.LuaState lState) { LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); if (LuaDLL.lua_toboolean(lState, -1)) { LuaDLL.lua_settop(lState, -2); throw new LuaException("There is already a LuaInterface associated with this LuaState"); } else { LuaDLL.lua_settop(lState, -2); LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_pushboolean(lState, true); LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); this.luaState = lState; LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.lua_getglobal(lState, "luanet"); LuaDLL.lua_pushstring(lState, "getmetatable"); LuaDLL.lua_getglobal(lState, "getmetatable"); LuaDLL.lua_settable(lState, -3); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); translator = new ObjectTranslator(this, this.luaState); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.luaL_dostring(lState, ScriptStrings.InitLuaNet); // steffenj: lua_dostring renamed to luaL_dostring LuaDLL.luaL_dostring(luaState, ScriptStrings.InitClrLib); LuaDLL.luaL_dostring(luaState, ScriptStrings.InitExtLib); } _StatePassed = true; }
private object getAsChar(SharpLua.Lua.LuaState luaState, int stackPos) { if (LuaDLL.lua_isstring(luaState, stackPos)) { string s = LuaDLL.lua_tostring(luaState, stackPos); if (s.Length == 0) // return a null char { return('\0'); } else { if (s.Length > 1) { System.Diagnostics.Debug.WriteLine("String Length was greater than 1! Truncating..."); } return(s[0]); } } char retVal = (char)LuaDLL.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDLL.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private bool _IsParamsArray(SharpLua.Lua.LuaState luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue) { extractValue = null; if (currentNetParam.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) { LuaTypes luaType; try { luaType = LuaDLL.lua_type(luaState, currentLuaParam); } catch (Exception ex) { Debug.WriteLine("Could not retrieve lua type while attempting to determine params Array Status." + ex.ToString()); Debug.WriteLine(ex.Message); extractValue = null; return(false); } if (luaType == LuaTypes.LUA_TTABLE) { try { extractValue = translator.typeChecker.getExtractor(typeof(LuaTable)); } catch (Exception ex) { Debug.WriteLine("An error occurred during an attempt to retrieve a LuaTable extractor while checking for params array status." + ex.ToString()); } if (extractValue != null) { return(true); } } else { Type paramElementType = currentNetParam.ParameterType.GetElementType(); try { extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, paramElementType); } catch (Exception ex) { Debug.WriteLine(string.Format("An error occurred during an attempt to retrieve an extractor ({0}) while checking for params array status:{1}", paramElementType.FullName, ex.ToString())); } if (extractValue != null) { return(true); } } } Debug.WriteLine("Type wasn't Params object."); return(false); }
/* * __index metafunction of type references, works on static members. */ private int getClassMethod(SharpLua.Lua.LuaState luaState) { IReflect klass; object obj = translator.getRawNetObject(luaState, 1); if (obj == null || !(obj is IReflect)) { translator.throwError(luaState, "trying to index an invalid type reference"); LuaDLL.lua_pushnil(luaState); return(1); } else { klass = (IReflect)obj; } if (LuaDLL.lua_isnumber(luaState, 2)) { int size = (int)LuaDLL.lua_tonumber(luaState, 2); translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size)); return(1); } else { string methodName = LuaDLL.lua_tostring(luaState, 2); if (methodName == null) { LuaDLL.lua_pushnil(luaState); return(1); } //CP: Ignore case else { return(getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase)); } } }
/* * Implementation of get_constructor_bysig. Returns nil * if no matching constructor is found. */ private int getConstructorSignature(SharpLua.Lua.LuaState luaState) { IReflect klass = null; int udata = LuaDLL.luanet_checkudata(luaState, 1, "luaNet_class"); if (udata != -1) { klass = (IReflect)objects[udata]; } if (klass == null) { throwError(luaState, "get_constructor_bysig: first arg is invalid type reference"); } Type[] signature = new Type[LuaDLL.lua_gettop(luaState) - 1]; for (int i = 0; i < signature.Length; i++) { signature[i] = FindType(LuaDLL.lua_tostring(luaState, i + 2)); } try { ConstructorInfo constructor = klass.UnderlyingSystemType.GetConstructor(signature); pushFunction(luaState, new SharpLua.Lua.lua_CFunction((new LuaMethodWrapper(this, null, klass, constructor)).call)); } catch (Exception e) { throwError(luaState, e); LuaDLL.lua_pushnil(luaState); } return(1); }
// lockCallback, unlockCallback; used by debug code commented out for now public LuaInterface() { luaState = LuaDLL.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone) //LuaDLL.luaopen_base(luaState); // steffenj: luaopen_* no longer used LuaDLL.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here) LuaDLL.lua_pushstring(luaState, "LUAINTERFACE LOADED"); LuaDLL.lua_pushboolean(luaState, true); LuaDLL.lua_settable(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_newtable(luaState); LuaDLL.lua_setglobal(luaState, "luanet"); LuaDLL.lua_pushvalue(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.lua_getglobal(luaState, "luanet"); LuaDLL.lua_pushstring(luaState, "getmetatable"); LuaDLL.lua_getglobal(luaState, "getmetatable"); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); translator = new ObjectTranslator(this, luaState); LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.luaL_dostring(luaState, ScriptStrings.InitLuaNet); // steffenj: lua_dostring renamed to luaL_dostring tracebackFunction = new SharpLua.Lua.lua_CFunction(traceback); // We need to keep this in a managed reference so the delegate doesn't get garbage collected panicCallback = new SharpLua.Lua.lua_CFunction(PanicCallback); Lua.lua_CFunction oldpanicFunc = //LuaDLL.lua_atpanic(luaState, tracebackFunction); LuaDLL.lua_atpanic(luaState, panicCallback); LuaDLL.luaL_dostring(luaState, ScriptStrings.InitClrLib); LuaDLL.luaL_dostring(luaState, ScriptStrings.InitExtLib); luaState.SetInterface(this); }
/* * __index metafunction of base classes (the base field of Lua tables). * Adds a prefix to the method name to call the base version of the method. */ private int getBaseMethod(SharpLua.Lua.LuaState luaState) { object obj = translator.getRawNetObject(luaState, 1); if (obj == null) { translator.throwError(luaState, "trying to index an invalid object reference"); LuaDLL.lua_pushnil(luaState); LuaDLL.lua_pushboolean(luaState, false); return(2); } string methodName = LuaDLL.lua_tostring(luaState, 2); if (methodName == null) { LuaDLL.lua_pushnil(luaState); LuaDLL.lua_pushboolean(luaState, false); return(2); } getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); LuaDLL.lua_settop(luaState, -2); if (LuaDLL.lua_type(luaState, -1) == LuaTypes.LUA_TNIL) { LuaDLL.lua_settop(luaState, -2); return(getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase)); } LuaDLL.lua_pushboolean(luaState, false); return(2); }
private static object checkudata_raw(SharpLua.Lua.LuaState L, int ud, string tname) { object p = SharpLua.Lua.lua_touserdata(L, ud); if (p != null) { /* value is a userdata? */ if (SharpLua.Lua.lua_getmetatable(L, ud) != 0) { bool isEqual; /* does it have a metatable? */ SharpLua.Lua.lua_getfield(L, (int)LuaIndexes.LUA_REGISTRYINDEX, tname); /* get correct metatable */ isEqual = SharpLua.Lua.lua_rawequal(L, -1, -2) != 0; // NASTY - we need our own version of the lua_pop macro // lua_pop(L, 2); /* remove both metatables */ SharpLua.Lua.lua_settop(L, -(2) - 1); if (isEqual) /* does it have the correct mt? */ { return(p); } } } return(null); }
/* * 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(SharpLua.Lua.LuaState luaState, int oldTop, Type[] popTypes) { int newTop = LuaDLL.lua_gettop(luaState); if (oldTop == newTop) { return(null); } else { int iTypes; ArrayList 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++; } LuaDLL.lua_settop(luaState, oldTop); return(returnValues.ToArray()); } }
//[DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] public static int luanet_tonetobject(SharpLua.Lua.LuaState luaState, int index) { byte[] udata; if (lua_type(luaState, index) == LuaTypes.LUA_TUSERDATA) { if (luaL_checkmetatable(luaState, index)) { udata = lua_touserdata(luaState, index) as byte[]; if (udata != null) { return(fourBytesToInt(udata)); } } udata = checkudata_raw(luaState, index, "luaNet_class") as byte[]; if (udata != null) { return(fourBytesToInt(udata)); } udata = checkudata_raw(luaState, index, "luaNet_searchbase") as byte[]; if (udata != null) { return(fourBytesToInt(udata)); } udata = checkudata_raw(luaState, index, "luaNet_function") as byte[]; if (udata != null) { return(fourBytesToInt(udata)); } } return(-1); }
/* * Registers the indexing function of CLR objects * passed to Lua */ private void createIndexingMetaFunction(SharpLua.Lua.LuaState luaState) { LuaDLL.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDLL.luaL_dostring(luaState, MetaFunctions.luaIndexFunction); // steffenj: lua_dostring renamed to luaL_dostring //LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction); LuaDLL.lua_rawset(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); }
/* * Implementation of load_assembly. Throws an error * if the assembly is not found. */ private int loadAssembly(SharpLua.Lua.LuaState luaState) { try { string assemblyName = LuaDLL.lua_tostring(luaState, 1); Assembly assembly = null; try { assembly = Assembly.LoadWithPartialName(assemblyName); } catch (BadImageFormatException) { // The assemblyName was invalid. It is most likely a path. } if (assembly == null) { assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName)); } } catch (Exception e) { throwError(luaState, e); } return(0); }
private int traceback(SharpLua.Lua.LuaState luaState) { LuaDLL.lua_getglobal(luaState, "debug"); LuaDLL.lua_getfield(luaState, -1, "traceback"); LuaDLL.lua_pushvalue(luaState, 1); LuaDLL.lua_pushnumber(luaState, 2); LuaDLL.lua_call(luaState, 2, 1); return(1); }
private object getAsDecimal(SharpLua.Lua.LuaState luaState, int stackPos) { decimal retVal = (decimal)LuaDLL.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDLL.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsString(SharpLua.Lua.LuaState luaState, int stackPos) { string retVal = LuaDLL.lua_tostring(luaState, stackPos); if (retVal == "" && !LuaDLL.lua_isstring(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsFloat(SharpLua.Lua.LuaState luaState, int stackPos) { float retVal = (float)LuaDLL.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDLL.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
private object getAsChar(SharpLua.Lua.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(SharpLua.Lua.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(SharpLua.Lua.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 getAsByte(SharpLua.Lua.LuaState luaState, int stackPos) { byte retVal = (byte)LuaDLL.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDLL.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
//[DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] public static int luanet_checkudata(SharpLua.Lua.LuaState luaState, int ud, string tname) { object udata = checkudata_raw(luaState, ud, tname); if (udata != null) { return(fourBytesToInt(udata as byte[])); } return(-1); }
/* * Gets the CLR object in the index positon of the Lua stack. Returns * delegates as is. */ internal object getRawNetObject(SharpLua.Lua.LuaState luaState, int index) { int udata = LuaDLL.luanet_rawnetobj(luaState, index); if (udata != -1) { return(objects[udata]); } return(null); }
/* * Gets an object from the Lua stack with the desired type, if it matches, otherwise * returns null. */ internal object getAsType(SharpLua.Lua.LuaState luaState, int stackPos, Type paramType) { ExtractValue extractor = typeChecker.checkType(luaState, stackPos, paramType); if (extractor != null) { return(extractor(luaState, stackPos)); } return(null); }
static int PanicCallback(SharpLua.Lua.LuaState luaState) { // string desc = LuaDLL.lua_tostring(luaState, 1); // string desc = LuaDLL.lua_tostring(luaState, 1); string reason = String.Format("unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(luaState, -1)); // lua_tostring(L, -1); throw new LuaException(reason); }
public static int luaL_dostring(SharpLua.Lua.LuaState luaState, string chunk) { int result = LuaDLL.luaL_loadstring(luaState, chunk); if (result != 0) { return(result); } return(LuaDLL.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) //[DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] public static int luaL_dofile(SharpLua.Lua.LuaState luaState, string fileName) { int result = LuaDLL.luaL_loadfile(luaState, fileName); if (result != 0) { return(result); } return(LuaDLL.lua_pcall(luaState, 0, -1, 0)); }
/* * Sets up the list of objects in the Lua side */ private void createLuaObjectList(SharpLua.Lua.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); }
private int ctype(SharpLua.Lua.LuaState luaState) { Type t = typeOf(luaState, 1); if (t == null) { return(pushError(luaState, "not a CLR class")); } pushObject(luaState, t, "luaNet_metatable"); return(1); }
/* * Creates the metatable for delegates */ private void createFunctionMetatable(SharpLua.Lua.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); }
public static int lua_ref(SharpLua.Lua.LuaState luaState, int lockRef) { if (lockRef != 0) { return(LuaDLL.luaL_ref(luaState, LuaIndexes.LUA_REGISTRYINDEX)); } else { return(0); } }
/// <summary> /// CAUTION: LuaInterface's can't share the same lua state! /// </summary> /// <param name="lState"></param> public LuaInterface(SharpLua.Lua.LuaState lState) { lState.initializing = true; LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); if (LuaDLL.lua_toboolean(lState, -1)) { LuaDLL.lua_settop(lState, -2); throw new LuaException("There is already a LuaInterface associated with this LuaState"); } else { LuaDLL.lua_settop(lState, -2); LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_pushboolean(lState, true); LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); this.luaState = lState; LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.lua_getglobal(lState, "luanet"); LuaDLL.lua_pushstring(lState, "getmetatable"); LuaDLL.lua_getglobal(lState, "getmetatable"); LuaDLL.lua_settable(lState, -3); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); translator = new ObjectTranslator(this, this.luaState); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); DoString(ScriptStrings.InitLuaNet, "LuaNet"); DoString(ScriptStrings.InitClrLib, "ClrLib"); DoString(ScriptStrings.InitExtLib, "ExtLib"); } _StatePassed = true; lState.initializing = false; }
public void Close() { if (_StatePassed) return; if (luaState != null) LuaDLL.lua_close(luaState); luaState = null; //luaState = IntPtr.Zero; <- suggested by Christopher Cebulski http://luaforge.net/forum/forum.php?thread_id=44593&forum_id=146 }