diff options
Diffstat (limited to '')
-rw-r--r-- | lapi.c | 105 |
1 files changed, 66 insertions, 39 deletions
@@ -1107,16 +1107,37 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |||
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | 1109 | ||
1110 | /* | ||
1111 | ** Dump a function, calling 'writer' to write its parts. Because the | ||
1112 | ** writer can use the stack in unkown ways, this function should not | ||
1113 | ** push things on the stack, but it must anchor an auxiliary table | ||
1114 | ** used by 'luaU_dump'. To do so, it creates the table, anchors the | ||
1115 | ** function that is on the stack in the table, and substitutes the | ||
1116 | ** table for the function in the stack. | ||
1117 | */ | ||
1118 | |||
1110 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { | 1119 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { |
1111 | int status; | 1120 | int status; |
1121 | StkId fstk; /* pointer to function */ | ||
1112 | TValue *o; | 1122 | TValue *o; |
1113 | lua_lock(L); | 1123 | lua_lock(L); |
1114 | api_checknelems(L, 1); | 1124 | api_checknelems(L, 1); |
1115 | o = s2v(L->top.p - 1); | 1125 | fstk = L->top.p - 1; |
1116 | if (isLfunction(o)) | 1126 | o = s2v(fstk); |
1117 | status = luaU_dump(L, getproto(o), writer, data, strip); | 1127 | if (!isLfunction(o)) |
1118 | else | ||
1119 | status = 1; | 1128 | status = 1; |
1129 | else { | ||
1130 | LClosure *f = clLvalue(o); | ||
1131 | ptrdiff_t fidx = savestack(L, fstk); /* function index */ | ||
1132 | Table *h = luaH_new(L); /* auxiliary table used by 'luaU_dump' */ | ||
1133 | sethvalue2s(L, L->top.p, h); /* anchor it (luaH_set may call GC) */ | ||
1134 | L->top.p++; /* (assume extra slot) */ | ||
1135 | luaH_set(L, h, o, o); /* anchor function into table */ | ||
1136 | setobjs2s(L, fstk, L->top.p - 1); /* move table over function */ | ||
1137 | L->top.p--; /* stack back to initial size */ | ||
1138 | status = luaU_dump(L, f->p, writer, data, strip, h); | ||
1139 | setclLvalue2s(L, restorestack(L, fidx), f); /* put function back */ | ||
1140 | } | ||
1120 | lua_unlock(L); | 1141 | lua_unlock(L); |
1121 | return status; | 1142 | return status; |
1122 | } | 1143 | } |
@@ -1145,7 +1166,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { | |||
1145 | } | 1166 | } |
1146 | case LUA_GCRESTART: { | 1167 | case LUA_GCRESTART: { |
1147 | luaE_setdebt(g, 0); | 1168 | luaE_setdebt(g, 0); |
1148 | g->gcstp = 0; /* (GCSTPGC must be already zero here) */ | 1169 | g->gcstp = 0; /* (bit GCSTPGC must be zero here) */ |
1149 | break; | 1170 | break; |
1150 | } | 1171 | } |
1151 | case LUA_GCCOLLECT: { | 1172 | case LUA_GCCOLLECT: { |
@@ -1154,42 +1175,46 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { | |||
1154 | } | 1175 | } |
1155 | case LUA_GCCOUNT: { | 1176 | case LUA_GCCOUNT: { |
1156 | /* GC values are expressed in Kbytes: #bytes/2^10 */ | 1177 | /* GC values are expressed in Kbytes: #bytes/2^10 */ |
1157 | res = cast_int(gettotalbytes(g) >> 10); | 1178 | res = cast_int(g->totalbytes >> 10); |
1158 | break; | 1179 | break; |
1159 | } | 1180 | } |
1160 | case LUA_GCCOUNTB: { | 1181 | case LUA_GCCOUNTB: { |
1161 | res = cast_int(gettotalbytes(g) & 0x3ff); | 1182 | res = cast_int(g->totalbytes & 0x3ff); |
1162 | break; | 1183 | break; |
1163 | } | 1184 | } |
1164 | case LUA_GCSTEP: { | 1185 | case LUA_GCSTEP: { |
1165 | int data = va_arg(argp, int); | 1186 | int todo = va_arg(argp, int); /* work to be done */ |
1166 | l_mem debt = 1; /* =1 to signal that it did an actual step */ | 1187 | int didsomething = 0; |
1167 | lu_byte oldstp = g->gcstp; | 1188 | lu_byte oldstp = g->gcstp; |
1168 | g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ | 1189 | g->gcstp = 0; /* allow GC to run (bit GCSTPGC must be zero here) */ |
1169 | if (data == 0) { | 1190 | if (todo == 0) |
1170 | luaE_setdebt(g, 0); /* do a basic step */ | 1191 | todo = 1 << g->gcstepsize; /* standard step size */ |
1171 | luaC_step(L); | 1192 | while (todo >= g->GCdebt) { /* enough to run a step? */ |
1172 | } | 1193 | todo -= g->GCdebt; /* decrement 'todo' */ |
1173 | else { /* add 'data' to total debt */ | 1194 | luaC_step(L); /* run one basic step */ |
1174 | debt = cast(l_mem, data) * 1024 + g->GCdebt; | 1195 | didsomething = 1; |
1175 | luaE_setdebt(g, debt); | 1196 | if (g->gckind == KGC_GEN) /* minor collections? */ |
1176 | luaC_checkGC(L); | 1197 | todo = 0; /* doesn't make sense to repeat in this case */ |
1198 | else if (g->gcstate == GCSpause) | ||
1199 | break; /* don't run more than one cycle */ | ||
1177 | } | 1200 | } |
1201 | /* remove remaining 'todo' from total debt */ | ||
1202 | luaE_setdebt(g, g->GCdebt - todo); | ||
1178 | g->gcstp = oldstp; /* restore previous state */ | 1203 | g->gcstp = oldstp; /* restore previous state */ |
1179 | if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ | 1204 | if (didsomething && g->gcstate == GCSpause) /* end of cycle? */ |
1180 | res = 1; /* signal it */ | 1205 | res = 1; /* signal it */ |
1181 | break; | 1206 | break; |
1182 | } | 1207 | } |
1183 | case LUA_GCSETPAUSE: { | 1208 | case LUA_GCSETPAUSE: { |
1184 | int data = va_arg(argp, int); | 1209 | unsigned int data = va_arg(argp, unsigned int); |
1185 | res = getgcparam(g->gcpause); | 1210 | res = applygcparam(g, gcpause, 100); |
1186 | setgcparam(g->gcpause, data); | 1211 | setgcparam(g, gcpause, data); |
1187 | break; | 1212 | break; |
1188 | } | 1213 | } |
1189 | case LUA_GCSETSTEPMUL: { | 1214 | case LUA_GCSETSTEPMUL: { |
1190 | int data = va_arg(argp, int); | 1215 | unsigned int data = va_arg(argp, unsigned int); |
1191 | res = getgcparam(g->gcstepmul); | 1216 | res = applygcparam(g, gcstepmul, 100); |
1192 | setgcparam(g->gcstepmul, data); | 1217 | setgcparam(g, gcstepmul, data); |
1193 | break; | 1218 | break; |
1194 | } | 1219 | } |
1195 | case LUA_GCISRUNNING: { | 1220 | case LUA_GCISRUNNING: { |
@@ -1197,27 +1222,28 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { | |||
1197 | break; | 1222 | break; |
1198 | } | 1223 | } |
1199 | case LUA_GCGEN: { | 1224 | case LUA_GCGEN: { |
1200 | int minormul = va_arg(argp, int); | 1225 | unsigned int minormul = va_arg(argp, unsigned int); |
1201 | int majormul = va_arg(argp, int); | 1226 | unsigned int majormul = va_arg(argp, unsigned int); |
1202 | res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; | 1227 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; |
1203 | if (minormul != 0) | 1228 | if (minormul != 0) |
1204 | g->genminormul = minormul; | 1229 | setgcparam(g, genminormul, minormul); |
1205 | if (majormul != 0) | 1230 | if (majormul != 0) |
1206 | setgcparam(g->genmajormul, majormul); | 1231 | setgcparam(g, genmajormul, majormul); |
1207 | luaC_changemode(L, KGC_GEN); | 1232 | luaC_changemode(L, KGC_GEN); |
1208 | break; | 1233 | break; |
1209 | } | 1234 | } |
1210 | case LUA_GCINC: { | 1235 | case LUA_GCINC: { |
1211 | int pause = va_arg(argp, int); | 1236 | unsigned int pause = va_arg(argp, unsigned int); |
1212 | int stepmul = va_arg(argp, int); | 1237 | unsigned int stepmul = va_arg(argp, unsigned int); |
1213 | int stepsize = va_arg(argp, int); | 1238 | unsigned int stepsize = va_arg(argp, unsigned int); |
1214 | res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; | 1239 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; |
1215 | if (pause != 0) | 1240 | if (pause != 0) |
1216 | setgcparam(g->gcpause, pause); | 1241 | setgcparam(g, gcpause, pause); |
1217 | if (stepmul != 0) | 1242 | if (stepmul != 0) |
1218 | setgcparam(g->gcstepmul, stepmul); | 1243 | setgcparam(g, gcstepmul, stepmul); |
1219 | if (stepsize != 0) | 1244 | if (stepsize != 0) |
1220 | g->gcstepsize = stepsize; | 1245 | g->gcstepsize = (stepsize <= log2maxs(l_obj)) ? stepsize |
1246 | : log2maxs(l_obj); | ||
1221 | luaC_changemode(L, KGC_INC); | 1247 | luaC_changemode(L, KGC_INC); |
1222 | break; | 1248 | break; |
1223 | } | 1249 | } |
@@ -1285,13 +1311,14 @@ LUA_API void lua_toclose (lua_State *L, int idx) { | |||
1285 | LUA_API void lua_concat (lua_State *L, int n) { | 1311 | LUA_API void lua_concat (lua_State *L, int n) { |
1286 | lua_lock(L); | 1312 | lua_lock(L); |
1287 | api_checknelems(L, n); | 1313 | api_checknelems(L, n); |
1288 | if (n > 0) | 1314 | if (n > 0) { |
1289 | luaV_concat(L, n); | 1315 | luaV_concat(L, n); |
1316 | luaC_checkGC(L); | ||
1317 | } | ||
1290 | else { /* nothing to concatenate */ | 1318 | else { /* nothing to concatenate */ |
1291 | setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */ | 1319 | setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */ |
1292 | api_incr_top(L); | 1320 | api_incr_top(L); |
1293 | } | 1321 | } |
1294 | luaC_checkGC(L); | ||
1295 | lua_unlock(L); | 1322 | lua_unlock(L); |
1296 | } | 1323 | } |
1297 | 1324 | ||