diff --git a/src/lj_func.c b/src/lj_func.c index abb7afd5..231701db 100644 --- a/src/lj_func.c +++ b/src/lj_func.c @@ -51,7 +51,7 @@ void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) pt->sizekn*(MSize)sizeof(lua_Number); lj_mem_free(g, pt->k.gc - nkgc, sizek); lj_mem_freevec(g, pt->bc, pt->sizebc, BCIns); - lj_mem_freevec(g, pt->uv, pt->sizeuv, int16_t); + lj_mem_freevec(g, pt->uv, pt->sizeuv, uint16_t); lj_mem_freevec(g, pt->lineinfo, pt->sizelineinfo, int32_t); lj_mem_freevec(g, pt->varinfo, pt->sizevarinfo, struct VarInfo); lj_mem_freevec(g, pt->uvname, pt->sizeuvname, GCstr *); @@ -170,7 +170,12 @@ GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent) base = L->base; for (i = 0; i < nuv; i++) { ptrdiff_t v = pt->uv[i]; - GCupval *uv = v < 0 ? &gcref(puv[~v])->uv : func_finduv(L, base + v); + GCupval *uv; + if ((v & 0x8000)) { + uv = func_finduv(L, base + (v & 0xff)); + } else { + uv = &gcref(puv[v])->uv; + } setgcref(fn->l.uvptr[i], obj2gco(uv)); } return fn; diff --git a/src/lj_gc.c b/src/lj_gc.c index ffe5d4b1..cd99f249 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -329,7 +329,7 @@ static size_t propagatemark(global_State *g) return sizeof(GCproto) + sizeof(BCIns) * pt->sizebc + sizeof(GCRef) * pt->sizekgc + sizeof(lua_Number) * pt->sizekn + - sizeof(int16_t) * pt->sizeuv + + sizeof(uint16_t) * pt->sizeuv + sizeof(int32_t) * pt->sizelineinfo + sizeof(VarInfo) * pt->sizevarinfo + sizeof(GCstr *) * pt->sizeuvname; diff --git a/src/lj_obj.h b/src/lj_obj.h index c237ebf5..85d904f3 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -358,7 +358,7 @@ typedef struct GCproto { GCRef gclist; ProtoK k; /* Split constant array (points to the middle). */ BCIns *bc; /* Array of bytecode instructions. */ - int16_t *uv; /* Upvalue list. local >= 0. parent uv < 0. */ + uint16_t *uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ MSize sizekgc; /* Number of collectable constants. */ MSize sizekn; /* Number of lua_Number constants. */ uint8_t sizeuv; /* Number of upvalues. */ diff --git a/src/lj_parse.c b/src/lj_parse.c index 81416f0f..8e94faa4 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -1014,7 +1014,7 @@ static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) uint32_t i; GCproto *pt = fs->pt; for (i = 0; i < fs->nuv; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { + if (fs->upvalues[i].info == v->u.s.info && fs->upvalues[i].k == v->k) { lua_assert(pt->uvname[i] == name); return i; } @@ -1171,12 +1171,12 @@ static void collectk(FuncState *fs, GCproto *pt) static void collectuv(FuncState *fs, GCproto *pt) { uint32_t i; - pt->uv = lj_mem_newvec(fs->L, fs->nuv, int16_t); + pt->uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); pt->sizeuv = fs->nuv; for (i = 0; i < pt->sizeuv; i++) { uint32_t v = fs->upvalues[i].info; - if (fs->upvalues[i].k == VUPVAL) v = ~v; - pt->uv[i] = (int16_t)v; + if (fs->upvalues[i].k == VLOCAL) v |= 0x8000; + pt->uv[i] = (uint16_t)v; } }