diff --git a/src/lj_api.c b/src/lj_api.c index 3bedb39f..ad17a972 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -1018,6 +1018,10 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n) api_checknelems(L, 1); name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val); if (name) { + /* Flush cache, as the upvalue might have PROTO_UV_IMMUTABLE set, which + doesn't take the debug library into account. But not during __gc. */ + if (lj_trace_flushall(L)) + lj_err_caller(L, LJ_ERR_NOGCMM); L->top--; copyTV(L, val, L->top); lj_gc_barrier(L, funcV(f), L->top); diff --git a/src/lj_debug.c b/src/lj_debug.c index bd2fa1f5..64757f00 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c @@ -13,6 +13,7 @@ #include "lj_tab.h" #include "lj_state.h" #include "lj_frame.h" +#include "lj_trace.h" #include "lj_bc.h" #include "lj_vm.h" #if LJ_HASJIT @@ -426,8 +427,14 @@ LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n) { const char *name = NULL; TValue *o = debug_localname(L, ar, &name, (BCReg)n); - if (name) + if (name) { + /* Flush cache, as the local might be aliased by an upvalue with + PROTO_UV_IMMUTABLE set, and said flag doesn't take the debug library + into account. But not during __gc. */ + if (lj_trace_flushall(L)) + lj_err_caller(L, LJ_ERR_NOGCMM); copyTV(L, o, L->top-1); + } L->top--; return name; }