/// <summary> /// <para>Return a debug.traceback() call result (a multi-line string, containing a full stack trace, including C calls.</para> /// <para>Note: it won't return anything unless the interpreter is in the middle of execution - that is, it only makes sense to call it from a method called from Lua, or during a coroutine yield.</para> /// </summary> public string GetDebugTraceback() { var oldTop = _luaState.GetTop(); _luaState.GetGlobal("debug"); // stack: debug _luaState.GetField(-1, "traceback"); // stack: debug,traceback _luaState.Remove(-2); // stack: traceback _luaState.PCall(0, -1, 0); return(_translator.PopValues(_luaState, oldTop)[0] as string); }
/* * 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(LuaState luaState, int oldTop, Type[] popTypes) { int newTop = luaState.GetTop(); if (oldTop == newTop) { return(null); } int iTypes; var returnValues = new List <object>(); 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++; } luaState.SetTop(oldTop); return(returnValues.ToArray()); }
private int GetMethodSignatureInternal(LuaState luaState) { ProxyType klass; object target; int udata = luaState.CheckUObject(1, "luaNet_class"); if (udata != -1) { klass = (ProxyType)_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"); luaState.PushNil(); return(1); } klass = new ProxyType(target.GetType()); } string methodName = luaState.ToString(2, false); var signature = new Type[luaState.GetTop() - 2]; for (int i = 0; i < signature.Length; i++) { signature[i] = FindType(luaState.ToString(i + 3, false)); } try { var method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance, signature); var wrapper = new LuaMethodWrapper(this, target, klass, method); LuaNativeFunction invokeDelegate = wrapper.InvokeFunction; PushFunction(luaState, invokeDelegate); } catch (Exception e) { ThrowError(luaState, e); luaState.PushNil(); } return(1); }
/* * Passes errors (argument e) to the Lua interpreter */ internal void ThrowError(LuaState luaState, object e) { // We use this to remove anything pushed by luaL_where int oldTop = luaState.GetTop(); // Stack frame #1 is our C# wrapper, so not very interesting to the user // Stack frame #2 must be the lua code that called us, so that's what we want to use luaState.Where(1); var curlev = PopValues(luaState, oldTop); // Determine the position in the script where the exception was triggered string errLocation = string.Empty; if (curlev.Length > 0) { errLocation = curlev[0].ToString(); } string message = e as string; if (message != null) { // Wrap Lua error (just a string) and store the error location if (interpreter.UseTraceback) { message += Environment.NewLine + interpreter.GetDebugTraceback(); } e = new LuaScriptException(message, errLocation); } else { var ex = e as Exception; if (ex != null) { // Wrap generic .NET exception as an InnerException and store the error location if (interpreter.UseTraceback) { ex.Data["Traceback"] = interpreter.GetDebugTraceback(); } e = new LuaScriptException(ex, errLocation); } } Push(luaState, e); //luaState.Error(); }
/* * Gets the values from the provided index to * the top of the stack and returns them in an array. */ internal object[] PopValues(LuaState luaState, int oldTop) { int newTop = luaState.GetTop(); if (oldTop == newTop) { return(null); } var returnValues = new List <object>(); for (int i = oldTop + 1; i <= newTop; i++) { returnValues.Add(GetObject(luaState, i)); } luaState.SetTop(oldTop); return(returnValues.ToArray()); }
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); }