/* * Implementation of get_constructor_bysig. Returns nil * if no matching constructor is found. */ private int getConstructorSignature(KopiLua.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 KopiLua.LuaNativeFunction((new LuaMethodWrapper(this, null, klass, constructor)).call)); } catch (Exception e) { throwError(luaState, e); LuaDll.lua_pushnil(luaState); } return(1); }
public void lua_registerTest() { bool wasCalled = false; LuaDll.lua_CFunction testFunctionDelegate = delegate(lua_State state) { wasCalled = true; LuaDll.lua_pushstring(state, "Success!"); return(1); }; // Create a new state var L = LuaDll.luaL_newstate(); // Register the given function by name LuaDll.lua_register(L, "test_function", testFunctionDelegate); // Call the function by name var result = LuaDll.luaL_dostring(L, "return test_function()"); Assert.AreEqual(0, result); Assert.IsTrue(wasCalled); // Check that the function returned the same string. var resultIndex = LuaDll.lua_gettop(L); var resultString = LuaDll.lua_tostring(L, resultIndex); Assert.AreEqual("Success!", resultString); }
/* * __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(KopiLua.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); 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)); } LuaDll.lua_pushboolean(luaState, false); return(2); }
public Lua() { 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, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring // We need to keep this in a managed reference so the delegate doesn't get garbage collected panicCallback = new KopiLua.LuaNativeFunction(PanicCallback); LuaDll.lua_atpanic(luaState, panicCallback); // LuaDLL.lua_atlock(luaState, lockCallback = new KopiLua.LuaNativeFunction(LockCallback)); // LuaDLL.lua_atunlock(luaState, unlockCallback = new KopiLua.LuaNativeFunction(UnlockCallback)); }
/* * 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(KopiLua.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()); } }
/* * __index metafunction of type references, works on static members. */ private int getClassMethod(KopiLua.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); } else { return(getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static)); } } }
/* * Calls the object as a function with the provided arguments and * casting returned values to the types in returnTypes before returning * them in an array */ internal object[] callFunction(object function, object[] args, Type[] returnTypes) { int nArgs = 0; int oldTop = LuaDll.lua_gettop(luaState); if (!LuaDll.lua_checkstack(luaState, args.Length + 6)) { throw new LuaException("Lua stack overflow"); } translator.push(luaState, function); if (args != null) { nArgs = args.Length; for (int i = 0; i < args.Length; i++) { translator.push(luaState, args[i]); } } int error = LuaDll.lua_pcall(luaState, nArgs, -1, 0); if (error != 0) { ThrowExceptionFromError(oldTop); } if (returnTypes != null) { return(translator.popValues(luaState, oldTop, returnTypes)); } else { return(translator.popValues(luaState, oldTop)); } }
/* * CAUTION: LuaInterface.Lua instances can't share the same lua state! */ public Lua(KopiLua.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.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 } }
/* * Registers the indexing function of CLR objects * passed to Lua */ private void createIndexingMetaFunction(KopiLua.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); }
/* * Sets a field of the table or userdata corresponding the the provided reference * to the provided value */ internal void setObject(int reference, string field, object val) { int oldTop = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, reference); setObject(field.Split(new char[] { '.' }), val); LuaDll.lua_settop(luaState, oldTop); }
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 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); }
private object getAsString(KopiLua.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(KopiLua.LuaState luaState, int stackPos) { float retVal = (float)LuaDll.lua_tonumber(luaState, stackPos); if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos)) { return(null); } return(retVal); }
/* * Gets a field of the table or userdata corresponding to the provided reference */ internal object getObject(int reference, string field) { int oldTop = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, reference); object returnValue = getObject(field.Split(new char[] { '.' })); LuaDll.lua_settop(luaState, oldTop); return(returnValue); }
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); }
/* * Sets a numeric field of the table or userdata corresponding the the provided reference * to the provided value */ internal void setObject(int reference, object field, object val) { int oldTop = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, reference); translator.push(luaState, field); translator.push(luaState, val); LuaDll.lua_settable(luaState, -3); LuaDll.lua_settop(luaState, oldTop); }
private object getAsDecimal(KopiLua.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 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 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); }
/* * Gets the CLR object in the index positon of the Lua stack. Returns * delegates as is. */ internal object getRawNetObject(KopiLua.LuaState luaState, int index) { int udata = LuaDll.luanet_rawnetobj(luaState, index); if (udata != -1) { return(objects[udata]); } return(null); }
/* * Navigates a table to set the value of one of its fields */ internal void setObject(string[] remainingPath, object val) { for (int i = 0; i < remainingPath.Length - 1; i++) { LuaDll.lua_pushstring(luaState, remainingPath[i]); LuaDll.lua_gettable(luaState, -2); } LuaDll.lua_pushstring(luaState, remainingPath[remainingPath.Length - 1]); translator.push(luaState, val); LuaDll.lua_settable(luaState, -3); }
/* * Compares the two values referenced by ref1 and ref2 for equality */ internal bool compareRef(int ref1, int ref2) { int top = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, ref1); LuaDll.lua_getref(luaState, ref2); int equal = LuaDll.lua_equal(luaState, -1, -2); LuaDll.lua_settop(luaState, top); return(equal != 0); }
/* * 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); } }
/* * 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); }
/* * Gets a field of the table corresponding to the provided reference * using rawget (do not use metatables) */ internal object rawGetObject(int reference, string field) { int oldTop = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, reference); LuaDll.lua_pushstring(luaState, field); LuaDll.lua_rawget(luaState, -2); object obj = translator.getObject(luaState, -1); LuaDll.lua_settop(luaState, oldTop); return(obj); }
/* * Gets a numeric field of the table or userdata corresponding the the provided reference */ internal object getObject(int reference, object field) { int oldTop = LuaDll.lua_gettop(luaState); LuaDll.lua_getref(luaState, reference); translator.push(luaState, field); LuaDll.lua_gettable(luaState, -2); object returnValue = translator.getObject(luaState, -1); LuaDll.lua_settop(luaState, oldTop); return(returnValue); }
/* * 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); } }
/* * __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); }