diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2026-04-23 17:57:42 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2026-04-23 17:57:42 -0300 |
| commit | 3228a97c6a953dcf397944161bb64b12f1ff5384 (patch) | |
| tree | 6497f6f8e93ba3bb381c0b48aed71646fca3f9b0 /ldo.c | |
| parent | 0c16a42d61d08266033ff63bc5dfade6312b7359 (diff) | |
| download | lua-3228a97c6a953dcf397944161bb64b12f1ff5384.tar.gz lua-3228a97c6a953dcf397944161bb64b12f1ff5384.tar.bz2 lua-3228a97c6a953dcf397944161bb64b12f1ff5384.zip | |
Bug: 'lua_load' does not preserve the stack
'lua_load' does not preserve the stack through the calls to the
reader function, as it should. Immediately after the first call (to
detect whether chunk is binary) it adds stuff, and it also adds a new
table when starting the compilation of each new function.
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 32 |
1 files changed, 29 insertions, 3 deletions
| @@ -1128,28 +1128,54 @@ static void checkmode (lua_State *L, const char *mode, const char *x) { | |||
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
| 1130 | 1130 | ||
| 1131 | /* | ||
| 1132 | ** Before the first call to the reader function, Lua reserves a slot | ||
| 1133 | ** with a table for anchoring stuff. | ||
| 1134 | */ | ||
| 1131 | static void f_parser (lua_State *L, void *ud) { | 1135 | static void f_parser (lua_State *L, void *ud) { |
| 1132 | LClosure *cl; | 1136 | LClosure *cl; |
| 1133 | struct SParser *p = cast(struct SParser *, ud); | 1137 | struct SParser *p = cast(struct SParser *, ud); |
| 1134 | const char *mode = p->mode ? p->mode : "bt"; | 1138 | const char *mode = p->mode ? p->mode : "bt"; |
| 1135 | int c = zgetc(p->z); /* read first character */ | 1139 | int c; |
| 1140 | Table *anchor; | ||
| 1141 | ptrdiff_t otop = savestack(L, L->top.p); /* original top */ | ||
| 1142 | luaD_checkstack(L, 2); | ||
| 1143 | anchor = luaH_new(L); /* create the anchor table */ | ||
| 1144 | sethvalue2s(L, L->top.p++, anchor); /* anchor the anchor table */ | ||
| 1145 | c = zgetc(p->z); /* read first character */ | ||
| 1136 | if (c == LUA_SIGNATURE[0]) { | 1146 | if (c == LUA_SIGNATURE[0]) { |
| 1137 | int fixed = 0; | 1147 | int fixed = 0; |
| 1138 | if (strchr(mode, 'B') != NULL) | 1148 | if (strchr(mode, 'B') != NULL) |
| 1139 | fixed = 1; | 1149 | fixed = 1; |
| 1140 | else | 1150 | else |
| 1141 | checkmode(L, mode, "binary"); | 1151 | checkmode(L, mode, "binary"); |
| 1142 | cl = luaU_undump(L, p->z, p->name, fixed); | 1152 | cl = luaU_undump(L, p->z, anchor, p->name, fixed); |
| 1143 | } | 1153 | } |
| 1144 | else { | 1154 | else { |
| 1145 | checkmode(L, mode, "text"); | 1155 | checkmode(L, mode, "text"); |
| 1146 | cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); | 1156 | cl = luaY_parser(L, p->z, anchor, &p->buff, &p->dyd, p->name, c); |
| 1147 | } | 1157 | } |
| 1158 | L->top.p = restorestack(L, otop); /* restore stack */ | ||
| 1159 | setclLvalue2s(L, L->top.p++, cl); /* push closure */ | ||
| 1148 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | 1160 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); |
| 1149 | luaF_initupvals(L, cl); | 1161 | luaF_initupvals(L, cl); |
| 1150 | } | 1162 | } |
| 1151 | 1163 | ||
| 1152 | 1164 | ||
| 1165 | /* | ||
| 1166 | ** Anchor an object in a table in the stack. First, anchor the object | ||
| 1167 | ** temporarily in the stack, as luaH_set may call an emergency GC. | ||
| 1168 | ** Then, add it in the table with itself as its key. | ||
| 1169 | */ | ||
| 1170 | void luaD_anchorobj (lua_State *L, Table *anchor, GCObject *obj) { | ||
| 1171 | setgcovalue(L, s2v(L->top.p++), obj); /* temporary anchor in the stack */ | ||
| 1172 | luaH_set(L, anchor, s2v(L->top.p - 1), s2v(L->top.p - 1)); | ||
| 1173 | /* Because this is a new key, luaH_set will call the GC barrier, so | ||
| 1174 | we don't need to call the barrier again here */ | ||
| 1175 | L->top.p--; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | |||
| 1153 | TStatus luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | 1179 | TStatus luaD_protectedparser (lua_State *L, ZIO *z, const char *name, |
| 1154 | const char *mode) { | 1180 | const char *mode) { |
| 1155 | struct SParser p; | 1181 | struct SParser p; |
