Browse Source

Fix write barrier for lua_setupvalue() and debug.setupvalue().

Mike Pall 5 years ago
parent
commit
e613105ca9
3 changed files with 12 additions and 6 deletions
  1. 5 3
      src/lj_api.c
  2. 5 2
      src/lj_debug.c
  3. 2 1
      src/lj_debug.h

+ 5 - 3
src/lj_api.c

@@ -841,7 +841,8 @@ LUA_API int lua_next(lua_State *L, int idx)
 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
 {
 {
   TValue *val;
   TValue *val;
-  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val);
+  GCobj *o;
+  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
   if (name) {
   if (name) {
     copyTV(L, L->top, val);
     copyTV(L, L->top, val);
     incr_top(L);
     incr_top(L);
@@ -1014,13 +1015,14 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
 {
 {
   cTValue *f = index2adr(L, idx);
   cTValue *f = index2adr(L, idx);
   TValue *val;
   TValue *val;
+  GCobj *o;
   const char *name;
   const char *name;
   api_checknelems(L, 1);
   api_checknelems(L, 1);
-  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val);
+  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
   if (name) {
   if (name) {
     L->top--;
     L->top--;
     copyTV(L, val, L->top);
     copyTV(L, val, L->top);
-    lj_gc_barrier(L, funcV(f), L->top);
+    lj_gc_barrier(L, o, L->top);
   }
   }
   return name;
   return name;
 }
 }

+ 5 - 2
src/lj_debug.c

@@ -235,19 +235,22 @@ const char *lj_debug_uvname(GCproto *pt, uint32_t idx)
 }
 }
 
 
 /* Get name and value of upvalue. */
 /* Get name and value of upvalue. */
-const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp)
+const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp, GCobj **op)
 {
 {
   if (tvisfunc(o)) {
   if (tvisfunc(o)) {
     GCfunc *fn = funcV(o);
     GCfunc *fn = funcV(o);
     if (isluafunc(fn)) {
     if (isluafunc(fn)) {
       GCproto *pt = funcproto(fn);
       GCproto *pt = funcproto(fn);
       if (idx < pt->sizeuv) {
       if (idx < pt->sizeuv) {
-	*tvp = uvval(&gcref(fn->l.uvptr[idx])->uv);
+	GCobj *uvo = gcref(fn->l.uvptr[idx]);
+	*tvp = uvval(&uvo->uv);
+	*op = uvo;
 	return lj_debug_uvname(pt, idx);
 	return lj_debug_uvname(pt, idx);
       }
       }
     } else {
     } else {
       if (idx < fn->c.nupvalues) {
       if (idx < fn->c.nupvalues) {
 	*tvp = &fn->c.upvalue[idx];
 	*tvp = &fn->c.upvalue[idx];
+	*op = obj2gco(fn);
 	return "";
 	return "";
       }
       }
     }
     }

+ 2 - 1
src/lj_debug.h

@@ -29,7 +29,8 @@ typedef struct lj_Debug {
 LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
 LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
 LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
 LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
 LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
 LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
-LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp);
+LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp,
+				     GCobj **op);
 LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
 LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
 				      BCReg slot, const char **name);
 				      BCReg slot, const char **name);
 LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
 LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,