summaryrefslogtreecommitdiffhomepage
path: root/contrib/package/ucode-mod-lua
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-09-15 16:25:27 +0200
committerJo-Philipp Wich <jo@mein.io>2022-10-25 01:03:36 +0200
commitc1ceeebdd037e0d3e591fff1241482f118eef286 (patch)
tree64c9a3c7e2e2c9f51f1e650c527ef197e2637d88 /contrib/package/ucode-mod-lua
parent1738749188202c3ecd468b851e000e8c7ede4ded (diff)
ucode-mod-lua: improve error reporting
Avoid redundancies in generated exception messages and include Lua tracebacks when catching exceptions in protected calls. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'contrib/package/ucode-mod-lua')
-rw-r--r--contrib/package/ucode-mod-lua/src/lua.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/contrib/package/ucode-mod-lua/src/lua.c b/contrib/package/ucode-mod-lua/src/lua.c
index ff94d60d8b..d02c6dc867 100644
--- a/contrib/package/ucode-mod-lua/src/lua.c
+++ b/contrib/package/ucode-mod-lua/src/lua.c
@@ -502,17 +502,17 @@ static const luaL_reg ucode_ud_methods[] = {
static uc_value_t *
uc_lua_vm_claim_result(uc_vm_t *vm, lua_State *L, int oldtop)
{
- int nargs = lua_gettop(L) - oldtop, i;
+ int nargs = lua_gettop(L) - oldtop - 1, i;
uc_value_t *uv;
if (nargs > 1) {
uv = ucv_array_new_length(vm, nargs);
- for (i = 1; i <= nargs; i++)
+ for (i = 2; i <= nargs; i++)
ucv_array_push(uv, lua_to_ucv(L, oldtop + i, vm, NULL));
}
else if (nargs == 1) {
- uv = lua_to_ucv(L, oldtop + 1, vm, NULL);
+ uv = lua_to_ucv(L, oldtop + 2, vm, NULL);
}
else {
uv = NULL;
@@ -521,18 +521,57 @@ uc_lua_vm_claim_result(uc_vm_t *vm, lua_State *L, int oldtop)
return uv;
}
+static int
+uc_lua_vm_pcall_error_cb(lua_State *L)
+{
+ const char *message = luaL_checkstring(L, 1);
+ uc_stringbuf_t *buf = xprintbuf_new();
+ lua_Debug ar;
+ int level;
+
+ ucv_stringbuf_printf(buf, "%s\n", message);
+
+ for (level = 1; lua_getstack(L, level, &ar) == 1; level++) {
+ if (lua_getinfo(L, "Snl", &ar) == 0)
+ continue;
+
+ if (level == 1) {
+ ucv_stringbuf_printf(buf, "\nIn %s(), file %s",
+ ar.name ? ar.name : "[anonymous function]", ar.short_src);
+
+ if (ar.currentline > -1)
+ ucv_stringbuf_printf(buf, ", line %d", ar.currentline);
+
+ ucv_stringbuf_append(buf, "\n");
+ }
+ else {
+ ucv_stringbuf_printf(buf, " called from function %s (%s",
+ ar.name ? ar.name : "[anonymous function]", ar.short_src);
+
+ if (ar.currentline > -1)
+ ucv_stringbuf_printf(buf, ":%d", ar.currentline);
+
+ ucv_stringbuf_append(buf, ")\n");
+ }
+ }
+
+ lua_pushstring(L, buf->buf);
+ printbuf_free(buf);
+
+ return 1;
+}
+
static uc_value_t *
uc_lua_vm_pcall(uc_vm_t *vm, lua_State *L, int oldtop)
{
uc_value_t *uv;
- switch (lua_pcall(L, lua_gettop(L) - oldtop - 1, LUA_MULTRET, 0)) {
+ switch (lua_pcall(L, lua_gettop(L) - oldtop - 2, LUA_MULTRET, oldtop + 1)) {
case LUA_ERRRUN:
case LUA_ERRMEM:
case LUA_ERRERR:
uc_vm_raise_exception(vm, EXCEPTION_RUNTIME,
- "Lua raised runtime exception: %s",
- lua_tostring(L, -1));
+ "%s", lua_tostring(L, -1));
uv = NULL;
break;
@@ -559,6 +598,7 @@ uc_lua_vm_invoke(uc_vm_t *vm, size_t nargs)
top = lua_gettop(*L);
+ lua_pushcfunction(*L, uc_lua_vm_pcall_error_cb);
lua_getglobal(*L, ucv_string_get(name));
for (i = 1; i < nargs; i++) {
@@ -586,11 +626,12 @@ uc_lua_vm_eval(uc_vm_t *vm, size_t nargs)
top = lua_gettop(*L);
+ lua_pushcfunction(*L, uc_lua_vm_pcall_error_cb);
+
switch (luaL_loadstring(*L, ucv_string_get(source))) {
case LUA_ERRSYNTAX:
uc_vm_raise_exception(vm, EXCEPTION_SYNTAX,
- "Syntax error while compiling Lua code: %s",
- lua_tostring(*L, -1));
+ "%s", lua_tostring(*L, -1));
break;
@@ -624,6 +665,8 @@ uc_lua_vm_include(uc_vm_t *vm, size_t nargs)
top = lua_gettop(*L);
+ lua_pushcfunction(*L, uc_lua_vm_pcall_error_cb);
+
switch (luaL_loadfile(*L, ucv_string_get(path))) {
case LUA_ERRSYNTAX:
uc_vm_raise_exception(vm, EXCEPTION_SYNTAX,
@@ -750,6 +793,7 @@ uc_lua_lv_call(uc_vm_t *vm, size_t nargs)
oldtop = lua_gettop(L);
+ lua_pushcfunction(L, uc_lua_vm_pcall_error_cb);
lua_rawgeti(L, LUA_REGISTRYINDEX, (*lv)->ref);
for (i = 0; i < nargs; i++)
@@ -777,6 +821,7 @@ uc_lua_lv_invoke(uc_vm_t *vm, size_t nargs)
oldtop = lua_gettop(L);
+ lua_pushcfunction(L, uc_lua_vm_pcall_error_cb);
lua_rawgeti(L, LUA_REGISTRYINDEX, (*lv)->ref);
ucv_to_lua(vm, method, L, NULL);
lua_gettable(L, -2);