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 76c9d31b..34b335fd 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
1104LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { 1113LUA_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) {
1279LUA_API void lua_concat (lua_State *L, int n) { 1305LUA_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