aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lapi.c105
1 files changed, 66 insertions, 39 deletions
diff --git a/lapi.c b/lapi.c
index 332e97d1..767fa55e 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
1110LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { 1119LUA_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) {
1285LUA_API void lua_concat (lua_State *L, int n) { 1311LUA_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