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