Browse Source

Add traceback information to the error string generated if a thread causes a Lua error.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
74d9bc7faf
3 changed files with 34 additions and 1 deletions
  1. 25 0
      src/common/runtime.cpp
  2. 5 0
      src/common/runtime.h
  3. 4 1
      src/modules/thread/LuaThread.cpp

+ 25 - 0
src/common/runtime.cpp

@@ -130,6 +130,31 @@ void luax_printstack(lua_State *L)
 		std::cout << i << " - " << luaL_typename(L, i) << std::endl;
 }
 
+int luax_traceback(lua_State *L)
+{
+	if (!lua_isstring(L, 1))  // 'message' not a string?
+		return 1; // keep it intact
+
+	lua_getfield(L, LUA_GLOBALSINDEX, "debug");
+	if (!lua_istable(L, -1))
+	{
+		lua_pop(L, 1);
+		return 1;
+	}
+
+	lua_getfield(L, -1, "traceback");
+	if (!lua_isfunction(L, -1))
+	{
+		lua_pop(L, 2);
+		return 1;
+	}
+
+	lua_pushvalue(L, 1); // pass error message
+	lua_pushinteger(L, 2); // skip this function and traceback
+	lua_call(L, 2, 1); // call debug.traceback
+	return 1;
+}
+
 bool luax_isarrayoftables(lua_State *L, int idx)
 {
 	if (!lua_istable(L, idx))

+ 5 - 0
src/common/runtime.h

@@ -106,6 +106,11 @@ Reference *luax_refif(lua_State *L, int type);
  **/
 void luax_printstack(lua_State *L);
 
+/**
+ * Traceback function for use with lua_pcall. Calls debug.traceback.
+ **/
+int luax_traceback(lua_State *L);
+
 /**
  * Gets whether the value at idx is an array of tables.
  **/

+ 4 - 1
src/modules/thread/LuaThread.cpp

@@ -66,6 +66,9 @@ void LuaThread::threadFunction()
 	luax_require(L, "love.filesystem");
 	lua_pop(L, 1);
 
+	lua_pushcfunction(L, luax_traceback);
+	int tracebackidx = lua_gettop(L);
+
 	if (luaL_loadbuffer(L, (const char *) code->getData(), code->getSize(), name.c_str()) != 0)
 		error = luax_tostring(L, -1);
 	else
@@ -77,7 +80,7 @@ void LuaThread::threadFunction()
 
 		args.clear();
 
-		if (lua_pcall(L, pushedargs, 0, 0) != 0)
+		if (lua_pcall(L, pushedargs, 0, tracebackidx) != 0)
 			error = luax_tostring(L, -1);
 	}