diff options
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 1a596d72..864f9e20 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -1017,20 +1017,23 @@ static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) | |||
1017 | { | 1017 | { |
1018 | uint32_t i; | 1018 | uint32_t i; |
1019 | GCproto *pt = fs->pt; | 1019 | GCproto *pt = fs->pt; |
1020 | GCRef *uvname; | ||
1020 | for (i = 0; i < fs->nuv; i++) { | 1021 | for (i = 0; i < fs->nuv; i++) { |
1021 | if (fs->upvalues[i].info == v->u.s.info && fs->upvalues[i].k == v->k) { | 1022 | if (fs->upvalues[i].info == v->u.s.info && fs->upvalues[i].k == v->k) { |
1022 | lua_assert(pt->uvname[i] == name); | 1023 | lua_assert(gco2str(proto_uvname(pt, i)) == name); |
1023 | return i; | 1024 | return i; |
1024 | } | 1025 | } |
1025 | } | 1026 | } |
1026 | /* Not found, create a new upvalue for this name. */ | 1027 | /* Not found, create a new upvalue for this name. */ |
1028 | uvname = mref(pt->uvname, GCRef); | ||
1027 | if (LJ_UNLIKELY(fs->nuv >= pt->sizeuvname)) { | 1029 | if (LJ_UNLIKELY(fs->nuv >= pt->sizeuvname)) { |
1028 | MSize oldsize = pt->sizeuvname; | 1030 | MSize oldsize = pt->sizeuvname; |
1029 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); | 1031 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); |
1030 | lj_mem_growvec(fs->L, pt->uvname, pt->sizeuvname, LJ_MAX_UPVAL, GCstr *); | 1032 | lj_mem_growvec(fs->L, uvname, pt->sizeuvname, LJ_MAX_UPVAL, GCRef); |
1031 | while (oldsize < pt->sizeuvname) pt->uvname[oldsize++] = NULL; | 1033 | setmref(pt->uvname, uvname); |
1034 | while (oldsize < pt->sizeuvname) setgcrefnull(uvname[oldsize++]); | ||
1032 | } | 1035 | } |
1033 | pt->uvname[fs->nuv] = name; | 1036 | setgcref(uvname[fs->nuv], obj2gco(name)); |
1034 | lj_gc_objbarrier(fs->L, pt, name); | 1037 | lj_gc_objbarrier(fs->L, pt, name); |
1035 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | 1038 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); |
1036 | fs->upvalues[fs->nuv].k = cast_byte(v->k); | 1039 | fs->upvalues[fs->nuv].k = cast_byte(v->k); |
@@ -1123,7 +1126,7 @@ static void open_func(LexState *ls, FuncState *fs) | |||
1123 | fs->nactvar = 0; | 1126 | fs->nactvar = 0; |
1124 | fs->nuv = 0; | 1127 | fs->nuv = 0; |
1125 | fs->bl = NULL; | 1128 | fs->bl = NULL; |
1126 | pt->chunkname = ls->chunkname; | 1129 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); |
1127 | pt->framesize = 2; /* registers 0/1 are always valid */ | 1130 | pt->framesize = 2; /* registers 0/1 are always valid */ |
1128 | fs->kt = lj_tab_new(L, 0, 0); | 1131 | fs->kt = lj_tab_new(L, 0, 0); |
1129 | /* anchor table of constants and prototype (to avoid being collected) */ | 1132 | /* anchor table of constants and prototype (to avoid being collected) */ |
@@ -1176,12 +1179,13 @@ static void collectk(FuncState *fs, GCproto *pt) | |||
1176 | static void collectuv(FuncState *fs, GCproto *pt) | 1179 | static void collectuv(FuncState *fs, GCproto *pt) |
1177 | { | 1180 | { |
1178 | uint32_t i; | 1181 | uint32_t i; |
1179 | pt->uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); | 1182 | uint16_t *uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); |
1183 | setmref(pt->uv, uv); | ||
1180 | pt->sizeuv = fs->nuv; | 1184 | pt->sizeuv = fs->nuv; |
1181 | for (i = 0; i < pt->sizeuv; i++) { | 1185 | for (i = 0; i < pt->sizeuv; i++) { |
1182 | uint32_t v = fs->upvalues[i].info; | 1186 | uint32_t v = fs->upvalues[i].info; |
1183 | if (fs->upvalues[i].k == VLOCAL) v |= 0x8000; | 1187 | if (fs->upvalues[i].k == VLOCAL) v |= 0x8000; |
1184 | pt->uv[i] = (uint16_t)v; | 1188 | uv[i] = (uint16_t)v; |
1185 | } | 1189 | } |
1186 | } | 1190 | } |
1187 | 1191 | ||
@@ -1228,6 +1232,7 @@ static void close_func(LexState *ls) | |||
1228 | FuncState *fs = ls->fs; | 1232 | FuncState *fs = ls->fs; |
1229 | GCproto *pt = fs->pt; | 1233 | GCproto *pt = fs->pt; |
1230 | BCIns *bc; | 1234 | BCIns *bc; |
1235 | GCRef *uvname; | ||
1231 | removevars(ls, 0); | 1236 | removevars(ls, 0); |
1232 | finalret(fs, pt); | 1237 | finalret(fs, pt); |
1233 | bc = proto_bc(pt); | 1238 | bc = proto_bc(pt); |
@@ -1240,7 +1245,9 @@ static void close_func(LexState *ls) | |||
1240 | pt->sizelineinfo = fs->pc; | 1245 | pt->sizelineinfo = fs->pc; |
1241 | lj_mem_reallocvec(L, pt->varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); | 1246 | lj_mem_reallocvec(L, pt->varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); |
1242 | pt->sizevarinfo = fs->nlocvars; | 1247 | pt->sizevarinfo = fs->nlocvars; |
1243 | lj_mem_reallocvec(L, pt->uvname, pt->sizeuvname, fs->nuv, GCstr *); | 1248 | uvname = mref(pt->uvname, GCRef); |
1249 | lj_mem_reallocvec(L, uvname, pt->sizeuvname, fs->nuv, GCRef); | ||
1250 | setmref(pt->uvname, uvname); | ||
1244 | pt->sizeuvname = fs->nuv; | 1251 | pt->sizeuvname = fs->nuv; |
1245 | lua_assert(fs->bl == NULL); | 1252 | lua_assert(fs->bl == NULL); |
1246 | lj_vmevent_send(L, BC, | 1253 | lj_vmevent_send(L, BC, |