aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/ldo.c b/ldo.c
index 12e0364b..ec360ee8 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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*/
1131static void f_parser (lua_State *L, void *ud) { 1135static 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*/
1170void 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
1153TStatus luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 1179TStatus 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;