/* * Registers the indexing function of CLR objects * passed to Lua */ private void createIndexingMetaFunction(KopiLua.Lua.lua_State 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); }
/* * Sets up the list of objects in the Lua side */ private void createLuaObjectList(KopiLua.Lua.lua_State 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); }
/* * Creates the metatable for superclasses (the base * field of registered tables) */ private void createBaseClassMetatable(KopiLua.Lua.lua_State 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); }
public object getAsObject(KopiLua.Lua.lua_State luaState,int stackPos) { if(LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) { if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) { if(LuaDLL.luaL_checkmetatable(luaState,-1)) { LuaDLL.lua_insert(luaState,stackPos); LuaDLL.lua_remove(luaState,stackPos+1); } else { LuaDLL.lua_settop(luaState,-2); } } } object obj=translator.getObject(luaState,stackPos); return obj; }
public ObjectTranslator(Lua interpreter,KopiLua.Lua.lua_State luaState) { this.interpreter=interpreter; typeChecker=new CheckType(this); metaFunctions=new MetaFunctions(this); assemblies=new List<Assembly>(); importTypeFunction=new KopiLua.Lua.lua_CFunction(this.importType); loadAssemblyFunction=new KopiLua.Lua.lua_CFunction(this.loadAssembly); registerTableFunction=new KopiLua.Lua.lua_CFunction(this.registerTable); unregisterTableFunction=new KopiLua.Lua.lua_CFunction(this.unregisterTable); getMethodSigFunction=new KopiLua.Lua.lua_CFunction(this.getMethodSignature); getConstructorSigFunction=new KopiLua.Lua.lua_CFunction(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.Lua.lua_State 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); } }
private int traceback(KopiLua.Lua.lua_State 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; }
static int PanicCallback(KopiLua.Lua.lua_State 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); }
/* * CAUTION: LuaInterface.Lua instances can't share the same lua state! */ public Lua(KopiLua.Lua.lua_State lState) { //IntPtr lState = new IntPtr(luaState); 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.Lua instance associated with this Lua state"); } 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, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring } _StatePassed = true; }
private object getAsUserdata(KopiLua.Lua.lua_State luaState,int stackPos) { return translator.getUserData(luaState,stackPos); }
private object getAsString(KopiLua.Lua.lua_State luaState,int stackPos) { string retVal=LuaDLL.lua_tostring(luaState,stackPos); if(retVal=="" && !LuaDLL.lua_isstring(luaState,stackPos)) return null; return retVal; }
internal static void luaL_getmetatable(KopiLua.LuaState state, string n) { Lua.LuaLGetMetatable(state, n); }
internal static int abs_index(KopiLua.LuaState state, int i) { return Lua.AbsIndex(state, i); }
internal static LuaType lua_type(KopiLua.LuaState state, int idx) { return (LuaType)Lua.LuaType(state, idx); }
internal static object lua_touserdata(KopiLua.LuaState state, int idx) { return Lua.LuaToUserData(state, idx); }
private object getAsLong(KopiLua.Lua.lua_State luaState,int stackPos) { long retVal=(long)LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
/* * The following functions return the value in the Lua stack * index stackPos as the desired type if it can, or null * otherwise. */ private object getAsSbyte(KopiLua.Lua.lua_State luaState,int stackPos) { sbyte retVal=(sbyte)LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
internal static int luaL_loadbuffer(KopiLua.LuaState state, byte[] bytes, int size, string name) { return Lua.LuaLLoadBuffer(state, bytes, (uint)size, name); }
private object getAsTable(KopiLua.Lua.lua_State luaState,int stackPos) { return translator.getTable(luaState,stackPos); }
static int Func(KopiLua.Lua.lua_State L) { int n = KopiLua.Lua.lua_gettop(L); KopiLua.Lua.lua_pushnumber(L, n * 2); return 1; }
private object getAsUshort(KopiLua.Lua.lua_State luaState,int stackPos) { ushort retVal=(ushort)LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
private object getAsBoolean(KopiLua.Lua.lua_State luaState,int stackPos) { return LuaDLL.lua_toboolean(luaState,stackPos); }
internal ExtractValue checkType(KopiLua.Lua.lua_State luaState,int stackPos,Type paramType) { LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); if(paramType.IsByRef) paramType=paramType.GetElementType(); Type underlyingType = Nullable.GetUnderlyingType(paramType); if (underlyingType != null) { paramType = underlyingType; // Silently convert nullable types to their non null requics } long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); if (paramType.Equals(typeof(object))) return extractValues[runtimeHandleValue]; if (LuaDLL.lua_isnumber(luaState, stackPos)) return extractValues[runtimeHandleValue]; if (paramType == typeof(bool)) { if (LuaDLL.lua_isboolean(luaState, stackPos)) return extractValues[runtimeHandleValue]; } else if (paramType == typeof(string)) { if (LuaDLL.lua_isstring(luaState, stackPos)) return extractValues[runtimeHandleValue]; else if (luatype == LuaTypes.LUA_TNIL) return extractNetObject; // kevinh - silently convert nil to a null string pointer } else if (paramType == typeof(LuaTable)) { if (luatype == LuaTypes.LUA_TTABLE) return extractValues[runtimeHandleValue]; } else if (paramType == typeof(LuaUserData)) { if (luatype == LuaTypes.LUA_TUSERDATA) return extractValues[runtimeHandleValue]; } else if (paramType == typeof(LuaFunction)) { if (luatype == LuaTypes.LUA_TFUNCTION) return extractValues[runtimeHandleValue]; } else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) { return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); } else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) { return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); } else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) { // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found return extractNetObject; } else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) { if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) { object obj = translator.getNetObject(luaState, -1); LuaDLL.lua_settop(luaState, -2); if (obj != null && paramType.IsAssignableFrom(obj.GetType())) return extractNetObject; } else return null; } else { object obj = translator.getNetObject(luaState, stackPos); if (obj != null && paramType.IsAssignableFrom(obj.GetType())) return extractNetObject; } return null; }
private object getAsChar(KopiLua.Lua.lua_State luaState,int stackPos) { char retVal=(char)LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
internal void pushCSFunction(KopiLua.Lua.lua_CFunction function) { translator.pushFunction(luaState,function); }
private object getAsDecimal(KopiLua.Lua.lua_State luaState,int stackPos) { decimal retVal=(decimal)LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
/// <summary> /// Called for each lua_lock call /// </summary> /// <param name="luaState"></param> /// Not yet used int LockCallback(KopiLua.Lua.lua_State luaState) { return 0; }
private object getAsDouble(KopiLua.Lua.lua_State luaState,int stackPos) { double retVal=LuaDLL.lua_tonumber(luaState,stackPos); if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; return retVal; }
/// <summary> /// Called for each lua_unlock call /// </summary> /// <param name="luaState"></param> /// Not yet used int UnlockCallback(KopiLua.Lua.lua_State luaState) { // Monitor.Exit(luaLock); return 0; }
private object getAsFunction(KopiLua.Lua.lua_State luaState,int stackPos) { return translator.getFunction(luaState,stackPos); }