diff options
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; |
