aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c105
-rw-r--r--ldo.c8
-rw-r--r--ldo.h12
-rw-r--r--ldump.c49
-rw-r--r--lgc.c416
-rw-r--r--lgc.h58
-rw-r--r--linit.c51
-rw-r--r--llimits.h21
-rw-r--r--lmem.c8
-rw-r--r--lmem.h2
-rw-r--r--lobject.h1
-rw-r--r--lparser.c53
-rw-r--r--lstate.c28
-rw-r--r--lstate.h21
-rw-r--r--lstrlib.c1
-rw-r--r--ltable.c80
-rw-r--r--ltable.h14
-rw-r--r--ltests.c54
-rw-r--r--ltests.h4
-rw-r--r--ltm.c2
-rw-r--r--ltm.h4
-rw-r--r--lua.c6
-rw-r--r--lua.h8
-rw-r--r--lualib.h39
-rw-r--r--lundump.c30
-rw-r--r--lundump.h2
-rw-r--r--lvm.c90
-rw-r--r--manual/manual.of139
-rw-r--r--testes/all.lua2
-rw-r--r--testes/api.lua14
-rw-r--r--testes/attrib.lua2
-rw-r--r--testes/calls.lua27
-rw-r--r--testes/closure.lua19
-rw-r--r--testes/coroutine.lua2
-rw-r--r--testes/files.lua4
-rw-r--r--testes/main.lua6
-rw-r--r--testes/nextvar.lua14
37 files changed, 700 insertions, 696 deletions
diff --git a/lapi.c b/lapi.c
index 34e64af1..a1eb7dc6 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
diff --git a/ldo.c b/ldo.c
index c30cde76..54518aff 100644
--- a/ldo.c
+++ b/ldo.c
@@ -416,7 +416,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
416StkId luaD_tryfuncTM (lua_State *L, StkId func) { 416StkId luaD_tryfuncTM (lua_State *L, StkId func) {
417 const TValue *tm; 417 const TValue *tm;
418 StkId p; 418 StkId p;
419 checkstackGCp(L, 1, func); /* space for metamethod */ 419 checkstackp(L, 1, func); /* space for metamethod */
420 tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ 420 tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */
421 if (l_unlikely(ttisnil(tm))) 421 if (l_unlikely(ttisnil(tm)))
422 luaG_callerror(L, s2v(func)); /* nothing to call */ 422 luaG_callerror(L, s2v(func)); /* nothing to call */
@@ -521,7 +521,7 @@ l_sinline int precallC (lua_State *L, StkId func, int nresults,
521 lua_CFunction f) { 521 lua_CFunction f) {
522 int n; /* number of returns */ 522 int n; /* number of returns */
523 CallInfo *ci; 523 CallInfo *ci;
524 checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ 524 checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
525 L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, 525 L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
526 L->top.p + LUA_MINSTACK); 526 L->top.p + LUA_MINSTACK);
527 lua_assert(ci->top.p <= L->stack_last.p); 527 lua_assert(ci->top.p <= L->stack_last.p);
@@ -557,7 +557,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
557 int fsize = p->maxstacksize; /* frame size */ 557 int fsize = p->maxstacksize; /* frame size */
558 int nfixparams = p->numparams; 558 int nfixparams = p->numparams;
559 int i; 559 int i;
560 checkstackGCp(L, fsize - delta, func); 560 checkstackp(L, fsize - delta, func);
561 ci->func.p -= delta; /* restore 'func' (if vararg) */ 561 ci->func.p -= delta; /* restore 'func' (if vararg) */
562 for (i = 0; i < narg1; i++) /* move down function and arguments */ 562 for (i = 0; i < narg1; i++) /* move down function and arguments */
563 setobjs2s(L, ci->func.p + i, func + i); 563 setobjs2s(L, ci->func.p + i, func + i);
@@ -604,7 +604,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
604 int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */ 604 int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */
605 int nfixparams = p->numparams; 605 int nfixparams = p->numparams;
606 int fsize = p->maxstacksize; /* frame size */ 606 int fsize = p->maxstacksize; /* frame size */
607 checkstackGCp(L, fsize, func); 607 checkstackp(L, fsize, func);
608 L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize); 608 L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
609 ci->u.l.savedpc = p->code; /* starting point */ 609 ci->u.l.savedpc = p->code; /* starting point */
610 for (; narg < nfixparams; narg++) 610 for (; narg < nfixparams; narg++)
diff --git a/ldo.h b/ldo.h
index 1aa446ad..b050fc08 100644
--- a/ldo.h
+++ b/ldo.h
@@ -44,18 +44,6 @@
44 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 44 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
45 45
46 46
47/* macro to check stack size and GC, preserving 'p' */
48#define checkstackGCp(L,n,p) \
49 luaD_checkstackaux(L, n, \
50 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
51 luaC_checkGC(L), /* stack grow uses memory */ \
52 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
53
54
55/* macro to check stack size and GC */
56#define checkstackGC(L,fsize) \
57 luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
58
59 47
60/* type of protected functions, to be ran by 'runprotected' */ 48/* type of protected functions, to be ran by 'runprotected' */
61typedef void (*Pfunc) (lua_State *L, void *ud); 49typedef void (*Pfunc) (lua_State *L, void *ud);
diff --git a/ldump.c b/ldump.c
index f848b669..a99d7ec5 100644
--- a/ldump.c
+++ b/ldump.c
@@ -14,8 +14,10 @@
14 14
15#include "lua.h" 15#include "lua.h"
16 16
17#include "lgc.h"
17#include "lobject.h" 18#include "lobject.h"
18#include "lstate.h" 19#include "lstate.h"
20#include "ltable.h"
19#include "lundump.h" 21#include "lundump.h"
20 22
21 23
@@ -25,6 +27,8 @@ typedef struct {
25 void *data; 27 void *data;
26 int strip; 28 int strip;
27 int status; 29 int status;
30 Table *h; /* table to track saved strings */
31 lua_Integer nstr; /* counter to number saved strings */
28} DumpState; 32} DumpState;
29 33
30 34
@@ -85,14 +89,33 @@ static void dumpInteger (DumpState *D, lua_Integer x) {
85} 89}
86 90
87 91
88static void dumpString (DumpState *D, const TString *s) { 92/*
93** Dump a String. First dump its "size": size==0 means NULL;
94** size==1 is followed by an index and means "reuse saved string with
95** that index"; size>=2 is followed by the string contents with real
96** size==size-2 and means that string, which will be saved with
97** the next available index.
98*/
99static void dumpString (DumpState *D, TString *s) {
89 if (s == NULL) 100 if (s == NULL)
90 dumpSize(D, 0); 101 dumpSize(D, 0);
91 else { 102 else {
92 size_t size = tsslen(s); 103 const TValue *idx = luaH_getstr(D->h, s);
93 const char *str = getstr(s); 104 if (ttisinteger(idx)) { /* string already saved? */
94 dumpSize(D, size + 1); 105 dumpSize(D, 1); /* reuse a saved string */
95 dumpVector(D, str, size); 106 dumpInt(D, ivalue(idx)); /* index of saved string */
107 }
108 else { /* must write and save the string */
109 TValue key, value; /* to save the string in the hash */
110 size_t size = tsslen(s);
111 dumpSize(D, size + 2);
112 dumpVector(D, getstr(s), size);
113 D->nstr++; /* one more saved string */
114 setsvalue(D->L, &key, s); /* the string is the key */
115 setivalue(&value, D->nstr); /* its index is the value */
116 luaH_finishset(D->L, D->h, &key, idx, &value); /* h[s] = nstr */
117 /* integer value does not need barrier */
118 }
96 } 119 }
97} 120}
98 121
@@ -103,7 +126,7 @@ static void dumpCode (DumpState *D, const Proto *f) {
103} 126}
104 127
105 128
106static void dumpFunction(DumpState *D, const Proto *f, TString *psource); 129static void dumpFunction(DumpState *D, const Proto *f);
107 130
108static void dumpConstants (DumpState *D, const Proto *f) { 131static void dumpConstants (DumpState *D, const Proto *f) {
109 int i; 132 int i;
@@ -136,7 +159,7 @@ static void dumpProtos (DumpState *D, const Proto *f) {
136 int n = f->sizep; 159 int n = f->sizep;
137 dumpInt(D, n); 160 dumpInt(D, n);
138 for (i = 0; i < n; i++) 161 for (i = 0; i < n; i++)
139 dumpFunction(D, f->p[i], f->source); 162 dumpFunction(D, f->p[i]);
140} 163}
141 164
142 165
@@ -176,9 +199,9 @@ static void dumpDebug (DumpState *D, const Proto *f) {
176} 199}
177 200
178 201
179static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { 202static void dumpFunction (DumpState *D, const Proto *f) {
180 if (D->strip || f->source == psource) 203 if (D->strip)
181 dumpString(D, NULL); /* no debug info or same source as its parent */ 204 dumpString(D, NULL); /* no debug info */
182 else 205 else
183 dumpString(D, f->source); 206 dumpString(D, f->source);
184 dumpInt(D, f->linedefined); 207 dumpInt(D, f->linedefined);
@@ -211,16 +234,18 @@ static void dumpHeader (DumpState *D) {
211** dump Lua function as precompiled chunk 234** dump Lua function as precompiled chunk
212*/ 235*/
213int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 236int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
214 int strip) { 237 int strip, Table *h) {
215 DumpState D; 238 DumpState D;
216 D.L = L; 239 D.L = L;
217 D.writer = w; 240 D.writer = w;
218 D.data = data; 241 D.data = data;
219 D.strip = strip; 242 D.strip = strip;
220 D.status = 0; 243 D.status = 0;
244 D.h = h;
245 D.nstr = 0;
221 dumpHeader(&D); 246 dumpHeader(&D);
222 dumpByte(&D, f->sizeupvalues); 247 dumpByte(&D, f->sizeupvalues);
223 dumpFunction(&D, f, NULL); 248 dumpFunction(&D, f);
224 return D.status; 249 return D.status;
225} 250}
226 251
diff --git a/lgc.c b/lgc.c
index a3094ff5..f68c5af0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -9,7 +9,6 @@
9 9
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12#include <stdio.h>
13#include <string.h> 12#include <string.h>
14 13
15 14
@@ -19,6 +18,7 @@
19#include "ldo.h" 18#include "ldo.h"
20#include "lfunc.h" 19#include "lfunc.h"
21#include "lgc.h" 20#include "lgc.h"
21#include "llex.h"
22#include "lmem.h" 22#include "lmem.h"
23#include "lobject.h" 23#include "lobject.h"
24#include "lstate.h" 24#include "lstate.h"
@@ -28,36 +28,18 @@
28 28
29 29
30/* 30/*
31** Maximum number of elements to sweep in each single step. 31** Number of fixed (luaC_fix) objects in a Lua state: metafield names,
32** (Large enough to dissipate fixed overheads but small enough 32** plus reserved words, plus "_ENV", plus the memory-error message.
33** to allow small steps for the collector.)
34*/
35#define GCSWEEPMAX 100
36
37/*
38** Maximum number of finalizers to call in each single step.
39*/
40#define GCFINMAX 10
41
42
43/*
44** Cost of calling one finalizer.
45*/
46#define GCFINALIZECOST 50
47
48
49/*
50** The equivalent, in bytes, of one unit of "work" (visiting a slot,
51** sweeping an object, etc.)
52*/ 33*/
53#define WORK2MEM sizeof(TValue) 34#define NFIXED (TM_N + NUM_RESERVED + 2)
54 35
55 36
56/* 37/*
57** macro to adjust 'pause': 'pause' is actually used like 38** Maximum number of elements to sweep in each single step.
58** 'pause / PAUSEADJ' (value chosen by tests) 39** (Large enough to dissipate fixed overheads but small enough
40** to allow small steps for the collector.)
59*/ 41*/
60#define PAUSEADJ 100 42#define GCSWEEPMAX 20
61 43
62 44
63/* mask with all color bits */ 45/* mask with all color bits */
@@ -105,7 +87,7 @@
105#define markobjectN(g,t) { if (t) markobject(g,t); } 87#define markobjectN(g,t) { if (t) markobject(g,t); }
106 88
107static void reallymarkobject (global_State *g, GCObject *o); 89static void reallymarkobject (global_State *g, GCObject *o);
108static lu_mem atomic (lua_State *L); 90static l_obj atomic (lua_State *L);
109static void entersweep (lua_State *L); 91static void entersweep (lua_State *L);
110 92
111 93
@@ -217,7 +199,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
217 } 199 }
218 else { /* sweep phase */ 200 else { /* sweep phase */
219 lua_assert(issweepphase(g)); 201 lua_assert(issweepphase(g));
220 if (g->gckind == KGC_INC) /* incremental mode? */ 202 if (g->gckind != KGC_GEN) /* incremental mode? */
221 makewhite(g, o); /* mark 'o' as white to avoid other barriers */ 203 makewhite(g, o); /* mark 'o' as white to avoid other barriers */
222 } 204 }
223} 205}
@@ -259,6 +241,7 @@ GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) {
259 global_State *g = G(L); 241 global_State *g = G(L);
260 char *p = cast_charp(luaM_newobject(L, novariant(tt), sz)); 242 char *p = cast_charp(luaM_newobject(L, novariant(tt), sz));
261 GCObject *o = cast(GCObject *, p + offset); 243 GCObject *o = cast(GCObject *, p + offset);
244 g->GCdebt--;
262 o->marked = luaC_white(g); 245 o->marked = luaC_white(g);
263 o->tt = tt; 246 o->tt = tt;
264 o->next = g->allgc; 247 o->next = g->allgc;
@@ -267,6 +250,9 @@ GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) {
267} 250}
268 251
269 252
253/*
254** create a new collectable object with no offset.
255*/
270GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { 256GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
271 return luaC_newobjdt(L, tt, sz, 0); 257 return luaC_newobjdt(L, tt, sz, 0);
272} 258}
@@ -295,6 +281,7 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
295** (only closures can), and a userdata's metatable must be a table. 281** (only closures can), and a userdata's metatable must be a table.
296*/ 282*/
297static void reallymarkobject (global_State *g, GCObject *o) { 283static void reallymarkobject (global_State *g, GCObject *o) {
284 g->marked++;
298 switch (o->tt) { 285 switch (o->tt) {
299 case LUA_VSHRSTR: 286 case LUA_VSHRSTR:
300 case LUA_VLNGSTR: { 287 case LUA_VLNGSTR: {
@@ -342,9 +329,9 @@ static void markmt (global_State *g) {
342/* 329/*
343** mark all objects in list of being-finalized 330** mark all objects in list of being-finalized
344*/ 331*/
345static lu_mem markbeingfnz (global_State *g) { 332static l_obj markbeingfnz (global_State *g) {
346 GCObject *o; 333 GCObject *o;
347 lu_mem count = 0; 334 l_obj count = 0;
348 for (o = g->tobefnz; o != NULL; o = o->next) { 335 for (o = g->tobefnz; o != NULL; o = o->next) {
349 count++; 336 count++;
350 markobject(g, o); 337 markobject(g, o);
@@ -364,12 +351,11 @@ static lu_mem markbeingfnz (global_State *g) {
364** upvalues, as they have nothing to be checked. (If the thread gets an 351** upvalues, as they have nothing to be checked. (If the thread gets an
365** upvalue later, it will be linked in the list again.) 352** upvalue later, it will be linked in the list again.)
366*/ 353*/
367static int remarkupvals (global_State *g) { 354static l_obj remarkupvals (global_State *g) {
355 l_obj work = 0;
368 lua_State *thread; 356 lua_State *thread;
369 lua_State **p = &g->twups; 357 lua_State **p = &g->twups;
370 int work = 0; /* estimate of how much work was done here */
371 while ((thread = *p) != NULL) { 358 while ((thread = *p) != NULL) {
372 work++;
373 if (!iswhite(thread) && thread->openupval != NULL) 359 if (!iswhite(thread) && thread->openupval != NULL)
374 p = &thread->twups; /* keep marked thread with upvalues in the list */ 360 p = &thread->twups; /* keep marked thread with upvalues in the list */
375 else { /* thread is not marked or without upvalues */ 361 else { /* thread is not marked or without upvalues */
@@ -379,13 +365,13 @@ static int remarkupvals (global_State *g) {
379 thread->twups = thread; /* mark that it is out of list */ 365 thread->twups = thread; /* mark that it is out of list */
380 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { 366 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
381 lua_assert(getage(uv) <= getage(thread)); 367 lua_assert(getage(uv) <= getage(thread));
382 work++;
383 if (!iswhite(uv)) { /* upvalue already visited? */ 368 if (!iswhite(uv)) { /* upvalue already visited? */
384 lua_assert(upisopen(uv) && isgray(uv)); 369 lua_assert(upisopen(uv) && isgray(uv));
385 markvalue(g, uv->v.p); /* mark its value */ 370 markvalue(g, uv->v.p); /* mark its value */
386 } 371 }
387 } 372 }
388 } 373 }
374 work++;
389 } 375 }
390 return work; 376 return work;
391} 377}
@@ -398,10 +384,15 @@ static void cleargraylists (global_State *g) {
398 384
399 385
400/* 386/*
401** mark root set and reset all gray lists, to start a new collection 387** mark root set and reset all gray lists, to start a new collection.
388** 'marked' is initialized with the number of fixed objects in the state,
389** to count the total number of live objects during a cycle. (That is
390** the metafield names, plus the reserved words, plus "_ENV" plus the
391** memory-error message.)
402*/ 392*/
403static void restartcollection (global_State *g) { 393static void restartcollection (global_State *g) {
404 cleargraylists(g); 394 cleargraylists(g);
395 g->marked = NFIXED;
405 markobject(g, g->mainthread); 396 markobject(g, g->mainthread);
406 markvalue(g, &g->l_registry); 397 markvalue(g, &g->l_registry);
407 markmt(g); 398 markmt(g);
@@ -539,7 +530,7 @@ static void traversestrongtable (global_State *g, Table *h) {
539} 530}
540 531
541 532
542static lu_mem traversetable (global_State *g, Table *h) { 533static void traversetable (global_State *g, Table *h) {
543 const char *weakkey, *weakvalue; 534 const char *weakkey, *weakvalue;
544 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); 535 const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
545 markobjectN(g, h->metatable); 536 markobjectN(g, h->metatable);
@@ -556,17 +547,15 @@ static lu_mem traversetable (global_State *g, Table *h) {
556 } 547 }
557 else /* not weak */ 548 else /* not weak */
558 traversestrongtable(g, h); 549 traversestrongtable(g, h);
559 return 1 + h->alimit + 2 * allocsizenode(h);
560} 550}
561 551
562 552
563static int traverseudata (global_State *g, Udata *u) { 553static void traverseudata (global_State *g, Udata *u) {
564 int i; 554 int i;
565 markobjectN(g, u->metatable); /* mark its metatable */ 555 markobjectN(g, u->metatable); /* mark its metatable */
566 for (i = 0; i < u->nuvalue; i++) 556 for (i = 0; i < u->nuvalue; i++)
567 markvalue(g, &u->uv[i].uv); 557 markvalue(g, &u->uv[i].uv);
568 genlink(g, obj2gco(u)); 558 genlink(g, obj2gco(u));
569 return 1 + u->nuvalue;
570} 559}
571 560
572 561
@@ -575,7 +564,7 @@ static int traverseudata (global_State *g, Udata *u) {
575** arrays can be larger than needed; the extra slots are filled with 564** arrays can be larger than needed; the extra slots are filled with
576** NULL, so the use of 'markobjectN') 565** NULL, so the use of 'markobjectN')
577*/ 566*/
578static int traverseproto (global_State *g, Proto *f) { 567static void traverseproto (global_State *g, Proto *f) {
579 int i; 568 int i;
580 markobjectN(g, f->source); 569 markobjectN(g, f->source);
581 for (i = 0; i < f->sizek; i++) /* mark literals */ 570 for (i = 0; i < f->sizek; i++) /* mark literals */
@@ -586,29 +575,26 @@ static int traverseproto (global_State *g, Proto *f) {
586 markobjectN(g, f->p[i]); 575 markobjectN(g, f->p[i]);
587 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 576 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
588 markobjectN(g, f->locvars[i].varname); 577 markobjectN(g, f->locvars[i].varname);
589 return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars;
590} 578}
591 579
592 580
593static int traverseCclosure (global_State *g, CClosure *cl) { 581static void traverseCclosure (global_State *g, CClosure *cl) {
594 int i; 582 int i;
595 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ 583 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
596 markvalue(g, &cl->upvalue[i]); 584 markvalue(g, &cl->upvalue[i]);
597 return 1 + cl->nupvalues;
598} 585}
599 586
600/* 587/*
601** Traverse a Lua closure, marking its prototype and its upvalues. 588** Traverse a Lua closure, marking its prototype and its upvalues.
602** (Both can be NULL while closure is being created.) 589** (Both can be NULL while closure is being created.)
603*/ 590*/
604static int traverseLclosure (global_State *g, LClosure *cl) { 591static void traverseLclosure (global_State *g, LClosure *cl) {
605 int i; 592 int i;
606 markobjectN(g, cl->p); /* mark its prototype */ 593 markobjectN(g, cl->p); /* mark its prototype */
607 for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ 594 for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */
608 UpVal *uv = cl->upvals[i]; 595 UpVal *uv = cl->upvals[i];
609 markobjectN(g, uv); /* mark upvalue */ 596 markobjectN(g, uv); /* mark upvalue */
610 } 597 }
611 return 1 + cl->nupvalues;
612} 598}
613 599
614 600
@@ -624,13 +610,13 @@ static int traverseLclosure (global_State *g, LClosure *cl) {
624** (which can only happen in generational mode) or if the traverse is in 610** (which can only happen in generational mode) or if the traverse is in
625** the propagate phase (which can only happen in incremental mode). 611** the propagate phase (which can only happen in incremental mode).
626*/ 612*/
627static int traversethread (global_State *g, lua_State *th) { 613static void traversethread (global_State *g, lua_State *th) {
628 UpVal *uv; 614 UpVal *uv;
629 StkId o = th->stack.p; 615 StkId o = th->stack.p;
630 if (isold(th) || g->gcstate == GCSpropagate) 616 if (isold(th) || g->gcstate == GCSpropagate)
631 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ 617 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
632 if (o == NULL) 618 if (o == NULL)
633 return 1; /* stack not completely built yet */ 619 return; /* stack not completely built yet */
634 lua_assert(g->gcstate == GCSatomic || 620 lua_assert(g->gcstate == GCSatomic ||
635 th->openupval == NULL || isintwups(th)); 621 th->openupval == NULL || isintwups(th));
636 for (; o < th->top.p; o++) /* mark live elements in the stack */ 622 for (; o < th->top.p; o++) /* mark live elements in the stack */
@@ -648,34 +634,35 @@ static int traversethread (global_State *g, lua_State *th) {
648 } 634 }
649 else if (!g->gcemergency) 635 else if (!g->gcemergency)
650 luaD_shrinkstack(th); /* do not change stack in emergency cycle */ 636 luaD_shrinkstack(th); /* do not change stack in emergency cycle */
651 return 1 + stacksize(th);
652} 637}
653 638
654 639
655/* 640/*
656** traverse one gray object, turning it to black. 641** traverse one gray object, turning it to black.
657*/ 642*/
658static lu_mem propagatemark (global_State *g) { 643static void propagatemark (global_State *g) {
659 GCObject *o = g->gray; 644 GCObject *o = g->gray;
660 nw2black(o); 645 nw2black(o);
661 g->gray = *getgclist(o); /* remove from 'gray' list */ 646 g->gray = *getgclist(o); /* remove from 'gray' list */
662 switch (o->tt) { 647 switch (o->tt) {
663 case LUA_VTABLE: return traversetable(g, gco2t(o)); 648 case LUA_VTABLE: traversetable(g, gco2t(o)); break;
664 case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); 649 case LUA_VUSERDATA: traverseudata(g, gco2u(o)); break;
665 case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); 650 case LUA_VLCL: traverseLclosure(g, gco2lcl(o)); break;
666 case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); 651 case LUA_VCCL: traverseCclosure(g, gco2ccl(o)); break;
667 case LUA_VPROTO: return traverseproto(g, gco2p(o)); 652 case LUA_VPROTO: traverseproto(g, gco2p(o)); break;
668 case LUA_VTHREAD: return traversethread(g, gco2th(o)); 653 case LUA_VTHREAD: traversethread(g, gco2th(o)); break;
669 default: lua_assert(0); return 0; 654 default: lua_assert(0);
670 } 655 }
671} 656}
672 657
673 658
674static lu_mem propagateall (global_State *g) { 659static l_obj propagateall (global_State *g) {
675 lu_mem tot = 0; 660 l_obj work = 0;
676 while (g->gray) 661 while (g->gray) {
677 tot += propagatemark(g); 662 propagatemark(g);
678 return tot; 663 work++;
664 }
665 return work;
679} 666}
680 667
681 668
@@ -684,10 +671,10 @@ static lu_mem propagateall (global_State *g) {
684** Repeat until it converges, that is, nothing new is marked. 'dir' 671** Repeat until it converges, that is, nothing new is marked. 'dir'
685** inverts the direction of the traversals, trying to speed up 672** inverts the direction of the traversals, trying to speed up
686** convergence on chains in the same table. 673** convergence on chains in the same table.
687**
688*/ 674*/
689static void convergeephemerons (global_State *g) { 675static l_obj convergeephemerons (global_State *g) {
690 int changed; 676 int changed;
677 l_obj work = 0;
691 int dir = 0; 678 int dir = 0;
692 do { 679 do {
693 GCObject *w; 680 GCObject *w;
@@ -702,9 +689,11 @@ static void convergeephemerons (global_State *g) {
702 propagateall(g); /* propagate changes */ 689 propagateall(g); /* propagate changes */
703 changed = 1; /* will have to revisit all ephemeron tables */ 690 changed = 1; /* will have to revisit all ephemeron tables */
704 } 691 }
692 work++;
705 } 693 }
706 dir = !dir; /* invert direction next time */ 694 dir = !dir; /* invert direction next time */
707 } while (changed); /* repeat until no more changes */ 695 } while (changed); /* repeat until no more changes */
696 return work;
708} 697}
709 698
710/* }====================================================== */ 699/* }====================================================== */
@@ -720,7 +709,8 @@ static void convergeephemerons (global_State *g) {
720/* 709/*
721** clear entries with unmarked keys from all weaktables in list 'l' 710** clear entries with unmarked keys from all weaktables in list 'l'
722*/ 711*/
723static void clearbykeys (global_State *g, GCObject *l) { 712static l_obj clearbykeys (global_State *g, GCObject *l) {
713 l_obj work = 0;
724 for (; l; l = gco2t(l)->gclist) { 714 for (; l; l = gco2t(l)->gclist) {
725 Table *h = gco2t(l); 715 Table *h = gco2t(l);
726 Node *limit = gnodelast(h); 716 Node *limit = gnodelast(h);
@@ -731,7 +721,9 @@ static void clearbykeys (global_State *g, GCObject *l) {
731 if (isempty(gval(n))) /* is entry empty? */ 721 if (isempty(gval(n))) /* is entry empty? */
732 clearkey(n); /* clear its key */ 722 clearkey(n); /* clear its key */
733 } 723 }
724 work++;
734 } 725 }
726 return work;
735} 727}
736 728
737 729
@@ -739,7 +731,8 @@ static void clearbykeys (global_State *g, GCObject *l) {
739** clear entries with unmarked values from all weaktables in list 'l' up 731** clear entries with unmarked values from all weaktables in list 'l' up
740** to element 'f' 732** to element 'f'
741*/ 733*/
742static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { 734static l_obj clearbyvalues (global_State *g, GCObject *l, GCObject *f) {
735 l_obj work = 0;
743 for (; l != f; l = gco2t(l)->gclist) { 736 for (; l != f; l = gco2t(l)->gclist) {
744 Table *h = gco2t(l); 737 Table *h = gco2t(l);
745 Node *n, *limit = gnodelast(h); 738 Node *n, *limit = gnodelast(h);
@@ -756,7 +749,9 @@ static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) {
756 if (isempty(gval(n))) /* is entry empty? */ 749 if (isempty(gval(n))) /* is entry empty? */
757 clearkey(n); /* clear its key */ 750 clearkey(n); /* clear its key */
758 } 751 }
752 work++;
759 } 753 }
754 return work;
760} 755}
761 756
762 757
@@ -768,6 +763,7 @@ static void freeupval (lua_State *L, UpVal *uv) {
768 763
769 764
770static void freeobj (lua_State *L, GCObject *o) { 765static void freeobj (lua_State *L, GCObject *o) {
766 G(L)->totalobjs--;
771 switch (o->tt) { 767 switch (o->tt) {
772 case LUA_VPROTO: 768 case LUA_VPROTO:
773 luaF_freeproto(L, gco2p(o)); 769 luaF_freeproto(L, gco2p(o));
@@ -817,10 +813,9 @@ static void freeobj (lua_State *L, GCObject *o) {
817** objects, where a dead object is one marked with the old (non current) 813** objects, where a dead object is one marked with the old (non current)
818** white; change all non-dead objects back to white, preparing for next 814** white; change all non-dead objects back to white, preparing for next
819** collection cycle. Return where to continue the traversal or NULL if 815** collection cycle. Return where to continue the traversal or NULL if
820** list is finished. ('*countout' gets the number of elements traversed.) 816** list is finished.
821*/ 817*/
822static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, 818static GCObject **sweeplist (lua_State *L, GCObject **p, int countin) {
823 int *countout) {
824 global_State *g = G(L); 819 global_State *g = G(L);
825 int ow = otherwhite(g); 820 int ow = otherwhite(g);
826 int i; 821 int i;
@@ -837,8 +832,6 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int countin,
837 p = &curr->next; /* go to next element */ 832 p = &curr->next; /* go to next element */
838 } 833 }
839 } 834 }
840 if (countout)
841 *countout = i; /* number of elements traversed */
842 return (*p == NULL) ? NULL : p; 835 return (*p == NULL) ? NULL : p;
843} 836}
844 837
@@ -849,7 +842,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int countin,
849static GCObject **sweeptolive (lua_State *L, GCObject **p) { 842static GCObject **sweeptolive (lua_State *L, GCObject **p) {
850 GCObject **old = p; 843 GCObject **old = p;
851 do { 844 do {
852 p = sweeplist(L, p, 1, NULL); 845 p = sweeplist(L, p, 1);
853 } while (p == old); 846 } while (p == old);
854 return p; 847 return p;
855} 848}
@@ -868,11 +861,8 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p) {
868*/ 861*/
869static void checkSizes (lua_State *L, global_State *g) { 862static void checkSizes (lua_State *L, global_State *g) {
870 if (!g->gcemergency) { 863 if (!g->gcemergency) {
871 if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ 864 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
872 l_mem olddebt = g->GCdebt;
873 luaS_resize(L, g->strt.size / 2); 865 luaS_resize(L, g->strt.size / 2);
874 g->GCestimate += g->GCdebt - olddebt; /* correct estimate */
875 }
876 } 866 }
877} 867}
878 868
@@ -931,18 +921,6 @@ static void GCTM (lua_State *L) {
931 921
932 922
933/* 923/*
934** Call a few finalizers
935*/
936static int runafewfinalizers (lua_State *L, int n) {
937 global_State *g = G(L);
938 int i;
939 for (i = 0; i < n && g->tobefnz; i++)
940 GCTM(L); /* call one finalizer */
941 return i;
942}
943
944
945/*
946** call all pending finalizers 924** call all pending finalizers
947*/ 925*/
948static void callallpendingfinalizers (lua_State *L) { 926static void callallpendingfinalizers (lua_State *L) {
@@ -1050,20 +1028,13 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
1050 1028
1051/* 1029/*
1052** Set the "time" to wait before starting a new GC cycle; cycle will 1030** Set the "time" to wait before starting a new GC cycle; cycle will
1053** start when memory use hits the threshold of ('estimate' * pause / 1031** start when number of objects in use hits the threshold of
1054** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, 1032** approximately (marked * pause / 100).
1055** because Lua cannot even start with less than PAUSEADJ bytes).
1056*/ 1033*/
1057static void setpause (global_State *g) { 1034static void setpause (global_State *g) {
1058 l_mem threshold, debt; 1035 l_obj threshold = applygcparam(g, gcpause, g->marked);
1059 int pause = getgcparam(g->gcpause); 1036 l_obj debt = threshold - gettotalobjs(g);
1060 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ 1037 if (debt < 0) debt = 0;
1061 lua_assert(estimate > 0);
1062 threshold = (pause < MAX_LMEM / estimate) /* overflow? */
1063 ? estimate * pause /* no overflow */
1064 : MAX_LMEM; /* overflow; truncate to maximum */
1065 debt = gettotalbytes(g) - threshold;
1066 if (debt > 0) debt = 0;
1067 luaE_setdebt(g, debt); 1038 luaE_setdebt(g, debt);
1068} 1039}
1069 1040
@@ -1303,18 +1274,17 @@ static void atomic2gen (lua_State *L, global_State *g) {
1303 sweep2old(L, &g->tobefnz); 1274 sweep2old(L, &g->tobefnz);
1304 1275
1305 g->gckind = KGC_GEN; 1276 g->gckind = KGC_GEN;
1306 g->lastatomic = 0; 1277 g->GClastmajor = gettotalobjs(g); /* base for memory control */
1307 g->GCestimate = gettotalbytes(g); /* base for memory control */
1308 finishgencycle(L, g); 1278 finishgencycle(L, g);
1309} 1279}
1310 1280
1311 1281
1312/* 1282/*
1313** Set debt for the next minor collection, which will happen when 1283** Set debt for the next minor collection, which will happen when
1314** memory grows 'genminormul'%. 1284** total number of objects grows 'genminormul'%.
1315*/ 1285*/
1316static void setminordebt (global_State *g) { 1286static void setminordebt (global_State *g) {
1317 luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); 1287 luaE_setdebt(g, applygcparam(g, genminormul, gettotalobjs(g)));
1318} 1288}
1319 1289
1320 1290
@@ -1324,14 +1294,12 @@ static void setminordebt (global_State *g) {
1324** are cleared. Then, turn all objects into old and finishes the 1294** are cleared. Then, turn all objects into old and finishes the
1325** collection. 1295** collection.
1326*/ 1296*/
1327static lu_mem entergen (lua_State *L, global_State *g) { 1297static void entergen (lua_State *L, global_State *g) {
1328 lu_mem numobjs;
1329 luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ 1298 luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */
1330 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1299 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
1331 numobjs = atomic(L); /* propagates all and then do the atomic stuff */ 1300 atomic(L); /* propagates all and then do the atomic stuff */
1332 atomic2gen(L, g); 1301 atomic2gen(L, g);
1333 setminordebt(g); /* set debt assuming next cycle will be minor */ 1302 setminordebt(g); /* set debt assuming next cycle will be minor */
1334 return numobjs;
1335} 1303}
1336 1304
1337 1305
@@ -1348,7 +1316,6 @@ static void enterinc (global_State *g) {
1348 g->finobjrold = g->finobjold1 = g->finobjsur = NULL; 1316 g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
1349 g->gcstate = GCSpause; 1317 g->gcstate = GCSpause;
1350 g->gckind = KGC_INC; 1318 g->gckind = KGC_INC;
1351 g->lastatomic = 0;
1352} 1319}
1353 1320
1354 1321
@@ -1357,111 +1324,75 @@ static void enterinc (global_State *g) {
1357*/ 1324*/
1358void luaC_changemode (lua_State *L, int newmode) { 1325void luaC_changemode (lua_State *L, int newmode) {
1359 global_State *g = G(L); 1326 global_State *g = G(L);
1360 if (newmode != g->gckind) { 1327 if (newmode != g->gckind) { /* does it need to change? */
1361 if (newmode == KGC_GEN) /* entering generational mode? */ 1328 if (newmode == KGC_INC) { /* entering incremental mode? */
1329 if (g->gckind == KGC_GENMAJOR)
1330 g->gckind = KGC_INC; /* already incremental but in name */
1331 else
1332 enterinc(g); /* entering incremental mode */
1333 }
1334 else {
1335 lua_assert(newmode == KGC_GEN);
1362 entergen(L, g); 1336 entergen(L, g);
1363 else 1337 }
1364 enterinc(g); /* entering incremental mode */
1365 } 1338 }
1366 g->lastatomic = 0;
1367} 1339}
1368 1340
1369 1341
1370/* 1342/*
1371** Does a full collection in generational mode. 1343** Does a full collection in generational mode.
1372*/ 1344*/
1373static lu_mem fullgen (lua_State *L, global_State *g) { 1345static void fullgen (lua_State *L, global_State *g) {
1374 enterinc(g); 1346 enterinc(g);
1375 return entergen(L, g); 1347 entergen(L, g);
1376} 1348}
1377 1349
1378 1350
1379/* 1351/*
1380** Does a major collection after last collection was a "bad collection". 1352** Does a major collector up to the atomic phase and then either
1381** 1353** returns to minor collections or stays doing major ones. If the
1382** When the program is building a big structure, it allocates lots of 1354** number of objects collected this time (numobjs - marked) is more than
1383** memory but generates very little garbage. In those scenarios, 1355** half the number of objects created since the last major collection
1384** the generational mode just wastes time doing small collections, and 1356** (numobjs - lastmajor), it goes back to minor collections.
1385** major collections are frequently what we call a "bad collection", a 1357*/
1386** collection that frees too few objects. To avoid the cost of switching 1358static void genmajorstep (lua_State *L, global_State *g) {
1387** between generational mode and the incremental mode needed for full 1359 l_obj lastmajor = g->GClastmajor; /* count from last collection */
1388** (major) collections, the collector tries to stay in incremental mode 1360 l_obj numobjs = gettotalobjs(g); /* current count */
1389** after a bad collection, and to switch back to generational mode only
1390** after a "good" collection (one that traverses less than 9/8 objects
1391** of the previous one).
1392** The collector must choose whether to stay in incremental mode or to
1393** switch back to generational mode before sweeping. At this point, it
1394** does not know the real memory in use, so it cannot use memory to
1395** decide whether to return to generational mode. Instead, it uses the
1396** number of objects traversed (returned by 'atomic') as a proxy. The
1397** field 'g->lastatomic' keeps this count from the last collection.
1398** ('g->lastatomic != 0' also means that the last collection was bad.)
1399*/
1400static void stepgenfull (lua_State *L, global_State *g) {
1401 lu_mem newatomic; /* count of traversed objects */
1402 lu_mem lastatomic = g->lastatomic; /* count from last collection */
1403 if (g->gckind == KGC_GEN) /* still in generational mode? */
1404 enterinc(g); /* enter incremental mode */
1405 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1361 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
1406 newatomic = atomic(L); /* mark everybody */ 1362 atomic(L); /* mark everybody */
1407 if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ 1363 if ((numobjs - g->marked) > ((numobjs - lastmajor) >> 1)) {
1408 atomic2gen(L, g); /* return to generational mode */ 1364 atomic2gen(L, g); /* return to generational mode */
1409 setminordebt(g); 1365 setminordebt(g);
1410 } 1366 }
1411 else { /* another bad collection; stay in incremental mode */ 1367 else { /* bad collection; stay in major mode */
1412 g->GCestimate = gettotalbytes(g); /* first estimate */;
1413 entersweep(L); 1368 entersweep(L);
1414 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ 1369 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */
1415 setpause(g); 1370 setpause(g);
1416 g->lastatomic = newatomic; 1371 g->GClastmajor = gettotalobjs(g);
1417 } 1372 }
1418} 1373}
1419 1374
1420 1375
1421/* 1376/*
1422** Does a generational "step". 1377** Does a generational "step". If the total number of objects grew
1423** Usually, this means doing a minor collection and setting the debt to 1378** more than 'majormul'% since the last major collection, does a
1424** make another collection when memory grows 'genminormul'% larger. 1379** major collection. Otherwise, does a minor collection.
1425**
1426** However, there are exceptions. If memory grows 'genmajormul'%
1427** larger than it was at the end of the last major collection (kept
1428** in 'g->GCestimate'), the function does a major collection. At the
1429** end, it checks whether the major collection was able to free a
1430** decent amount of memory (at least half the growth in memory since
1431** previous major collection). If so, the collector keeps its state,
1432** and the next collection will probably be minor again. Otherwise,
1433** we have what we call a "bad collection". In that case, set the field
1434** 'g->lastatomic' to signal that fact, so that the next collection will
1435** go to 'stepgenfull'.
1436**
1437** 'GCdebt <= 0' means an explicit call to GC step with "size" zero;
1438** in that case, do a minor collection.
1439*/ 1380*/
1440static void genstep (lua_State *L, global_State *g) { 1381static void genstep (lua_State *L, global_State *g) {
1441 if (g->lastatomic != 0) /* last collection was a bad one? */ 1382 l_obj majorbase = g->GClastmajor; /* count after last major collection */
1442 stepgenfull(L, g); /* do a full step */ 1383 l_obj majorinc = applygcparam(g, genmajormul, majorbase);
1443 else { 1384 if (gettotalobjs(g) > majorbase + majorinc && 0) {
1444 lu_mem majorbase = g->GCestimate; /* memory after last major collection */ 1385 /* do a major collection */
1445 lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); 1386 enterinc(g);
1446 if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { 1387 g->gckind = KGC_GENMAJOR;
1447 lu_mem numobjs = fullgen(L, g); /* do a major collection */ 1388 genmajorstep(L, g);
1448 if (gettotalbytes(g) < majorbase + (majorinc / 2)) { 1389 }
1449 /* collected at least half of memory growth since last major 1390 else { /* regular case; do a minor collection */
1450 collection; keep doing minor collections. */ 1391 g->marked = 0;
1451 lua_assert(g->lastatomic == 0); 1392 youngcollection(L, g);
1452 } 1393 setminordebt(g);
1453 else { /* bad collection */ 1394 lua_assert(g->GClastmajor == majorbase);
1454 g->lastatomic = numobjs; /* signal that last collection was bad */
1455 setpause(g); /* do a long wait for next (major) collection */
1456 }
1457 }
1458 else { /* regular case; do a minor collection */
1459 youngcollection(L, g);
1460 setminordebt(g);
1461 g->GCestimate = majorbase; /* preserve base value */
1462 }
1463 } 1395 }
1464 lua_assert(isdecGCmodegen(g));
1465} 1396}
1466 1397
1467/* }====================================================== */ 1398/* }====================================================== */
@@ -1520,9 +1451,9 @@ void luaC_freeallobjects (lua_State *L) {
1520} 1451}
1521 1452
1522 1453
1523static lu_mem atomic (lua_State *L) { 1454static l_obj atomic (lua_State *L) {
1455 l_obj work = 0;
1524 global_State *g = G(L); 1456 global_State *g = G(L);
1525 lu_mem work = 0;
1526 GCObject *origweak, *origall; 1457 GCObject *origweak, *origall;
1527 GCObject *grayagain = g->grayagain; /* save original list */ 1458 GCObject *grayagain = g->grayagain; /* save original list */
1528 g->grayagain = NULL; 1459 g->grayagain = NULL;
@@ -1539,50 +1470,44 @@ static lu_mem atomic (lua_State *L) {
1539 work += propagateall(g); /* propagate changes */ 1470 work += propagateall(g); /* propagate changes */
1540 g->gray = grayagain; 1471 g->gray = grayagain;
1541 work += propagateall(g); /* traverse 'grayagain' list */ 1472 work += propagateall(g); /* traverse 'grayagain' list */
1542 convergeephemerons(g); 1473 work += convergeephemerons(g);
1543 /* at this point, all strongly accessible objects are marked. */ 1474 /* at this point, all strongly accessible objects are marked. */
1544 /* Clear values from weak tables, before checking finalizers */ 1475 /* Clear values from weak tables, before checking finalizers */
1545 clearbyvalues(g, g->weak, NULL); 1476 work += clearbyvalues(g, g->weak, NULL);
1546 clearbyvalues(g, g->allweak, NULL); 1477 work += clearbyvalues(g, g->allweak, NULL);
1547 origweak = g->weak; origall = g->allweak; 1478 origweak = g->weak; origall = g->allweak;
1548 separatetobefnz(g, 0); /* separate objects to be finalized */ 1479 separatetobefnz(g, 0); /* separate objects to be finalized */
1549 work += markbeingfnz(g); /* mark objects that will be finalized */ 1480 work += markbeingfnz(g); /* mark objects that will be finalized */
1550 work += propagateall(g); /* remark, to propagate 'resurrection' */ 1481 work += propagateall(g); /* remark, to propagate 'resurrection' */
1551 convergeephemerons(g); 1482 work += convergeephemerons(g);
1552 /* at this point, all resurrected objects are marked. */ 1483 /* at this point, all resurrected objects are marked. */
1553 /* remove dead objects from weak tables */ 1484 /* remove dead objects from weak tables */
1554 clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ 1485 work += clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron */
1555 clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ 1486 work += clearbykeys(g, g->allweak); /* clear keys from all 'allweak' */
1556 /* clear values from resurrected weak tables */ 1487 /* clear values from resurrected weak tables */
1557 clearbyvalues(g, g->weak, origweak); 1488 work += clearbyvalues(g, g->weak, origweak);
1558 clearbyvalues(g, g->allweak, origall); 1489 work += clearbyvalues(g, g->allweak, origall);
1559 luaS_clearcache(g); 1490 luaS_clearcache(g);
1560 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 1491 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
1561 lua_assert(g->gray == NULL); 1492 lua_assert(g->gray == NULL);
1562 return work; /* estimate of slots marked by 'atomic' */ 1493 return work;
1563} 1494}
1564 1495
1565 1496
1566static int sweepstep (lua_State *L, global_State *g, 1497static void sweepstep (lua_State *L, global_State *g,
1567 int nextstate, GCObject **nextlist) { 1498 int nextstate, GCObject **nextlist) {
1568 if (g->sweepgc) { 1499 if (g->sweepgc)
1569 l_mem olddebt = g->GCdebt; 1500 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1570 int count;
1571 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count);
1572 g->GCestimate += g->GCdebt - olddebt; /* update estimate */
1573 return count;
1574 }
1575 else { /* enter next state */ 1501 else { /* enter next state */
1576 g->gcstate = nextstate; 1502 g->gcstate = nextstate;
1577 g->sweepgc = nextlist; 1503 g->sweepgc = nextlist;
1578 return 0; /* no work done */
1579 } 1504 }
1580} 1505}
1581 1506
1582 1507
1583static lu_mem singlestep (lua_State *L) { 1508static l_obj singlestep (lua_State *L) {
1584 global_State *g = G(L); 1509 global_State *g = G(L);
1585 lu_mem work; 1510 l_obj work;
1586 lua_assert(!g->gcstopem); /* collector is not reentrant */ 1511 lua_assert(!g->gcstopem); /* collector is not reentrant */
1587 g->gcstopem = 1; /* no emergency collections while collecting */ 1512 g->gcstopem = 1; /* no emergency collections while collecting */
1588 switch (g->gcstate) { 1513 switch (g->gcstate) {
@@ -1597,26 +1522,30 @@ static lu_mem singlestep (lua_State *L) {
1597 g->gcstate = GCSenteratomic; /* finish propagate phase */ 1522 g->gcstate = GCSenteratomic; /* finish propagate phase */
1598 work = 0; 1523 work = 0;
1599 } 1524 }
1600 else 1525 else {
1601 work = propagatemark(g); /* traverse one gray object */ 1526 propagatemark(g); /* traverse one gray object */
1527 work = 1;
1528 }
1602 break; 1529 break;
1603 } 1530 }
1604 case GCSenteratomic: { 1531 case GCSenteratomic: {
1605 work = atomic(L); /* work is what was traversed by 'atomic' */ 1532 work = atomic(L);
1606 entersweep(L); 1533 entersweep(L);
1607 g->GCestimate = gettotalbytes(g); /* first estimate */;
1608 break; 1534 break;
1609 } 1535 }
1610 case GCSswpallgc: { /* sweep "regular" objects */ 1536 case GCSswpallgc: { /* sweep "regular" objects */
1611 work = sweepstep(L, g, GCSswpfinobj, &g->finobj); 1537 sweepstep(L, g, GCSswpfinobj, &g->finobj);
1538 work = GCSWEEPMAX;
1612 break; 1539 break;
1613 } 1540 }
1614 case GCSswpfinobj: { /* sweep objects with finalizers */ 1541 case GCSswpfinobj: { /* sweep objects with finalizers */
1615 work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); 1542 sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
1543 work = GCSWEEPMAX;
1616 break; 1544 break;
1617 } 1545 }
1618 case GCSswptobefnz: { /* sweep objects to be finalized */ 1546 case GCSswptobefnz: { /* sweep objects to be finalized */
1619 work = sweepstep(L, g, GCSswpend, NULL); 1547 sweepstep(L, g, GCSswpend, NULL);
1548 work = GCSWEEPMAX;
1620 break; 1549 break;
1621 } 1550 }
1622 case GCSswpend: { /* finish sweeps */ 1551 case GCSswpend: { /* finish sweeps */
@@ -1625,10 +1554,11 @@ static lu_mem singlestep (lua_State *L) {
1625 work = 0; 1554 work = 0;
1626 break; 1555 break;
1627 } 1556 }
1628 case GCScallfin: { /* call remaining finalizers */ 1557 case GCScallfin: { /* call finalizers */
1629 if (g->tobefnz && !g->gcemergency) { 1558 if (g->tobefnz && !g->gcemergency) {
1630 g->gcstopem = 0; /* ok collections during finalizers */ 1559 g->gcstopem = 0; /* ok collections during finalizers */
1631 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; 1560 GCTM(L); /* call one finalizer */
1561 work = 1;
1632 } 1562 }
1633 else { /* emergency mode or no more finalizers */ 1563 else { /* emergency mode or no more finalizers */
1634 g->gcstate = GCSpause; /* finish collection */ 1564 g->gcstate = GCSpause; /* finish collection */
@@ -1663,20 +1593,16 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
1663** controls when next step will be performed. 1593** controls when next step will be performed.
1664*/ 1594*/
1665static void incstep (lua_State *L, global_State *g) { 1595static void incstep (lua_State *L, global_State *g) {
1666 int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ 1596 l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
1667 l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; 1597 l_obj work2do = applygcparam(g, gcstepmul, stepsize);
1668 l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem))
1669 ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul
1670 : MAX_LMEM; /* overflow; keep maximum value */
1671 do { /* repeat until pause or enough "credit" (negative debt) */ 1598 do { /* repeat until pause or enough "credit" (negative debt) */
1672 lu_mem work = singlestep(L); /* perform one single step */ 1599 l_obj work = singlestep(L); /* perform one single step */
1673 debt -= work; 1600 work2do -= work;
1674 } while (debt > -stepsize && g->gcstate != GCSpause); 1601 } while (work2do > 0 && g->gcstate != GCSpause);
1675 if (g->gcstate == GCSpause) 1602 if (g->gcstate == GCSpause)
1676 setpause(g); /* pause until next cycle */ 1603 setpause(g); /* pause until next cycle */
1677 else { 1604 else {
1678 debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ 1605 luaE_setdebt(g, stepsize);
1679 luaE_setdebt(g, debt);
1680 } 1606 }
1681} 1607}
1682 1608
@@ -1687,13 +1613,21 @@ static void incstep (lua_State *L, global_State *g) {
1687*/ 1613*/
1688void luaC_step (lua_State *L) { 1614void luaC_step (lua_State *L) {
1689 global_State *g = G(L); 1615 global_State *g = G(L);
1616 lua_assert(!g->gcemergency);
1690 if (!gcrunning(g)) /* not running? */ 1617 if (!gcrunning(g)) /* not running? */
1691 luaE_setdebt(g, -2000); 1618 luaE_setdebt(g, 2000);
1692 else { 1619 else {
1693 if(isdecGCmodegen(g)) 1620 switch (g->gckind) {
1694 genstep(L, g); 1621 case KGC_INC:
1695 else 1622 incstep(L, g);
1696 incstep(L, g); 1623 break;
1624 case KGC_GEN:
1625 genstep(L, g);
1626 break;
1627 case KGC_GENMAJOR:
1628 genmajorstep(L, g);
1629 break;
1630 }
1697 } 1631 }
1698} 1632}
1699 1633
@@ -1711,8 +1645,8 @@ static void fullinc (lua_State *L, global_State *g) {
1711 /* finish any pending sweep phase to start a new cycle */ 1645 /* finish any pending sweep phase to start a new cycle */
1712 luaC_runtilstate(L, bitmask(GCSpause)); 1646 luaC_runtilstate(L, bitmask(GCSpause));
1713 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ 1647 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
1714 /* estimate must be correct after a full GC cycle */ 1648 /* 'marked' must be correct after a full GC cycle */
1715 lua_assert(g->GCestimate == gettotalbytes(g)); 1649 lua_assert(g->marked == gettotalobjs(g));
1716 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ 1650 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */
1717 setpause(g); 1651 setpause(g);
1718} 1652}
@@ -1727,10 +1661,10 @@ void luaC_fullgc (lua_State *L, int isemergency) {
1727 global_State *g = G(L); 1661 global_State *g = G(L);
1728 lua_assert(!g->gcemergency); 1662 lua_assert(!g->gcemergency);
1729 g->gcemergency = isemergency; /* set flag */ 1663 g->gcemergency = isemergency; /* set flag */
1730 if (g->gckind == KGC_INC) 1664 if (g->gckind == KGC_GEN)
1731 fullinc(L, g);
1732 else
1733 fullgen(L, g); 1665 fullgen(L, g);
1666 else
1667 fullinc(L, g);
1734 g->gcemergency = 0; 1668 g->gcemergency = 0;
1735} 1669}
1736 1670
diff --git a/lgc.h b/lgc.h
index 538f6edc..959465ec 100644
--- a/lgc.h
+++ b/lgc.h
@@ -8,6 +8,9 @@
8#define lgc_h 8#define lgc_h
9 9
10 10
11#include <stddef.h>
12
13
11#include "lobject.h" 14#include "lobject.h"
12#include "lstate.h" 15#include "lstate.h"
13 16
@@ -122,31 +125,21 @@
122 125
123 126
124/* Default Values for GC parameters */ 127/* Default Values for GC parameters */
125#define LUAI_GENMAJORMUL 100
126#define LUAI_GENMINORMUL 20
127 128
128/* wait memory to double before starting new cycle */ 129/* generational */
129#define LUAI_GCPAUSE 200
130 130
131/* 131#define LUAI_GENMAJORMUL 100 /* major multiplier */
132** some gc parameters are stored divided by 4 to allow a maximum value 132#define LUAI_GENMINORMUL 20 /* minor multiplier */
133** up to 1023 in a 'lu_byte'.
134*/
135#define getgcparam(p) ((p) * 4)
136#define setgcparam(p,v) ((p) = (v) / 4)
137 133
138#define LUAI_GCMUL 100 134/* incremental */
139 135
140/* how much to allocate before next GC step (log2) */ 136/* wait memory to double before starting new cycle */
141#define LUAI_GCSTEPSIZE 13 /* 8 KB */ 137#define LUAI_GCPAUSE 200
142 138
139#define LUAI_GCMUL 300 /* step multiplier */
143 140
144/* 141/* how many objects to allocate before next GC step (log2) */
145** Check whether the declared GC mode is generational. While in 142#define LUAI_GCSTEPSIZE 8 /* 256 objects */
146** generational mode, the collector can go temporarily to incremental
147** mode to improve performance. This is signaled by 'g->lastatomic != 0'.
148*/
149#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
150 143
151 144
152/* 145/*
@@ -157,15 +150,38 @@
157#define GCSTPCLS 4 /* bit true when closing Lua state */ 150#define GCSTPCLS 4 /* bit true when closing Lua state */
158#define gcrunning(g) ((g)->gcstp == 0) 151#define gcrunning(g) ((g)->gcstp == 0)
159 152
153/*
154** Macros to set and apply GC parameters. GC parameters are given in
155** percentage points, but are stored as lu_byte. To reduce their
156** values and avoid repeated divisions by 100, these macros store
157** the original parameter multiplied by 2^n and divided by 100.
158** To apply them, the value is divided by 2^n (a shift) and then
159** multiplied by the stored parameter, yielding
160** value / 2^n * (original parameter * 2^n / 100), or approximately
161** (value * original parameter / 100).
162**
163** For most parameters, which are typically larger than 100%, 2^n is
164** 16 (2^4), allowing maximum values up to 1599. For the minor
165** multiplier, which is typically smaller, 2^n is 64 (2^6) to allow more
166** precision.
167*/
168#define gcparamshift(p) \
169 (offsetof(global_State, p) == offsetof(global_State, genminormul) ? 6 : 4)
170
171#define setgcparam(g,p,v) \
172 (g->p = (cast_uint(v) << gcparamshift(p)) / 100u)
173#define applygcparam(g,p,v) (((v) >> gcparamshift(p)) * g->p)
174
175
160 176
161/* 177/*
162** Does one step of collection when debt becomes positive. 'pre'/'pos' 178** Does one step of collection when debt becomes zero. 'pre'/'pos'
163** allows some adjustments to be done only when needed. macro 179** allows some adjustments to be done only when needed. macro
164** 'condchangemem' is used only for heavy tests (forcing a full 180** 'condchangemem' is used only for heavy tests (forcing a full
165** GC cycle on every opportunity) 181** GC cycle on every opportunity)
166*/ 182*/
167#define luaC_condGC(L,pre,pos) \ 183#define luaC_condGC(L,pre,pos) \
168 { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 184 { if (G(L)->GCdebt <= 0) { pre; luaC_step(L); pos;}; \
169 condchangemem(L,pre,pos); } 185 condchangemem(L,pre,pos); }
170 186
171/* more often than not, 'pre'/'pos' are empty */ 187/* more often than not, 'pre'/'pos' are empty */
diff --git a/linit.c b/linit.c
index 69808f84..675fb65f 100644
--- a/linit.c
+++ b/linit.c
@@ -8,21 +8,6 @@
8#define linit_c 8#define linit_c
9#define LUA_LIB 9#define LUA_LIB
10 10
11/*
12** If you embed Lua in your program and need to open the standard
13** libraries, call luaL_openlibs in your program. If you need a
14** different set of libraries, copy this file to your project and edit
15** it to suit your needs.
16**
17** You can also *preload* libraries, so that a later 'require' can
18** open the library, which is already linked to the application.
19** For that, do the following code:
20**
21** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
22** lua_pushcfunction(L, luaopen_modname);
23** lua_setfield(L, -2, modname);
24** lua_pop(L, 1); // remove PRELOAD table
25*/
26 11
27#include "lprefix.h" 12#include "lprefix.h"
28 13
@@ -36,30 +21,44 @@
36 21
37 22
38/* 23/*
39** these libs are loaded by lua.c and are readily available to any Lua 24** Standard Libraries
40** program
41*/ 25*/
42static const luaL_Reg loadedlibs[] = { 26static const luaL_Reg stdlibs[] = {
43 {LUA_GNAME, luaopen_base}, 27 {LUA_GNAME, luaopen_base},
44 {LUA_LOADLIBNAME, luaopen_package}, 28 {LUA_LOADLIBNAME, luaopen_package},
29
45 {LUA_COLIBNAME, luaopen_coroutine}, 30 {LUA_COLIBNAME, luaopen_coroutine},
46 {LUA_TABLIBNAME, luaopen_table}, 31 {LUA_DBLIBNAME, luaopen_debug},
47 {LUA_IOLIBNAME, luaopen_io}, 32 {LUA_IOLIBNAME, luaopen_io},
33 {LUA_MATHLIBNAME, luaopen_math},
48 {LUA_OSLIBNAME, luaopen_os}, 34 {LUA_OSLIBNAME, luaopen_os},
49 {LUA_STRLIBNAME, luaopen_string}, 35 {LUA_STRLIBNAME, luaopen_string},
50 {LUA_MATHLIBNAME, luaopen_math}, 36 {LUA_TABLIBNAME, luaopen_table},
51 {LUA_UTF8LIBNAME, luaopen_utf8}, 37 {LUA_UTF8LIBNAME, luaopen_utf8},
52 {LUA_DBLIBNAME, luaopen_debug}, 38
53 {NULL, NULL} 39 {NULL, NULL}
54}; 40};
55 41
56 42
57LUALIB_API void luaL_openlibs (lua_State *L) { 43/*
44** require selected standard libraries and add the others to the
45** preload table.
46*/
47LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) {
48 int mask = 1;
58 const luaL_Reg *lib; 49 const luaL_Reg *lib;
59 /* "require" functions from 'loadedlibs' and set results to global table */ 50 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
60 for (lib = loadedlibs; lib->func; lib++) { 51 for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) {
61 luaL_requiref(L, lib->name, lib->func, 1); 52 if (what & mask) { /* selected? */
62 lua_pop(L, 1); /* remove lib */ 53 luaL_requiref(L, lib->name, lib->func, 1); /* require library */
54 lua_pop(L, 1); /* remove result from the stack */
55 }
56 else { /* add library to PRELOAD table */
57 lua_pushcfunction(L, lib->func);
58 lua_setfield(L, -2, lib->name);
59 }
63 } 60 }
61 lua_assert((mask >> 1) == LUA_UTF8LIBK);
62 lua_pop(L, 1); // remove PRELOAD table
64} 63}
65 64
diff --git a/llimits.h b/llimits.h
index 251a2702..03cc51cb 100644
--- a/llimits.h
+++ b/llimits.h
@@ -16,21 +16,25 @@
16 16
17 17
18/* 18/*
19** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 19** 'lu_mem' is an unsigned integer big enough to count the total memory
20** the total memory used by Lua (in bytes). Usually, 'size_t' and 20** used by Lua (in bytes). 'l_obj' is a signed integer big enough to
21** count the total number of objects used by Lua. (It is signed due
22** to the use of debt in several computations.) Usually, 'size_t' and
21** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 23** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
22*/ 24*/
23#if defined(LUAI_MEM) /* { external definitions? */ 25#if defined(LUAI_MEM) /* { external definitions? */
24typedef LUAI_UMEM lu_mem; 26typedef LUAI_UMEM lu_mem;
25typedef LUAI_MEM l_mem; 27typedef LUAI_MEM l_obj;
26#elif LUAI_IS32INT /* }{ */ 28#elif LUAI_IS32INT /* }{ */
27typedef size_t lu_mem; 29typedef size_t lu_mem;
28typedef ptrdiff_t l_mem; 30typedef ptrdiff_t l_obj;
29#else /* 16-bit ints */ /* }{ */ 31#else /* 16-bit ints */ /* }{ */
30typedef unsigned long lu_mem; 32typedef unsigned long lu_mem;
31typedef long l_mem; 33typedef long l_obj;
32#endif /* } */ 34#endif /* } */
33 35
36#define MAX_LOBJ cast(l_obj, ~cast(lu_mem, 0) >> 1)
37
34 38
35/* chars used as small naturals (so that 'char' is reserved for characters) */ 39/* chars used as small naturals (so that 'char' is reserved for characters) */
36typedef unsigned char lu_byte; 40typedef unsigned char lu_byte;
@@ -45,11 +49,6 @@ typedef signed char ls_byte;
45 : (size_t)(LUA_MAXINTEGER)) 49 : (size_t)(LUA_MAXINTEGER))
46 50
47 51
48#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
49
50#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
51
52
53#define MAX_INT INT_MAX /* maximum value of an int */ 52#define MAX_INT INT_MAX /* maximum value of an int */
54 53
55 54
@@ -57,7 +56,7 @@ typedef signed char ls_byte;
57** floor of the log2 of the maximum signed value for integral type 't'. 56** floor of the log2 of the maximum signed value for integral type 't'.
58** (That is, maximum 'n' such that '2^n' fits in the given signed type.) 57** (That is, maximum 'n' such that '2^n' fits in the given signed type.)
59*/ 58*/
60#define log2maxs(t) (sizeof(t) * 8 - 2) 59#define log2maxs(t) cast_int(sizeof(t) * 8 - 2)
61 60
62 61
63/* 62/*
diff --git a/lmem.c b/lmem.c
index 9800a86f..dfd8a49b 100644
--- a/lmem.c
+++ b/lmem.c
@@ -151,7 +151,7 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {
151 global_State *g = G(L); 151 global_State *g = G(L);
152 lua_assert((osize == 0) == (block == NULL)); 152 lua_assert((osize == 0) == (block == NULL));
153 callfrealloc(g, block, osize, 0); 153 callfrealloc(g, block, osize, 0);
154 g->GCdebt -= osize; 154 g->totalbytes -= osize;
155} 155}
156 156
157 157
@@ -181,10 +181,10 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
181 if (l_unlikely(newblock == NULL && nsize > 0)) { 181 if (l_unlikely(newblock == NULL && nsize > 0)) {
182 newblock = tryagain(L, block, osize, nsize); 182 newblock = tryagain(L, block, osize, nsize);
183 if (newblock == NULL) /* still no memory? */ 183 if (newblock == NULL) /* still no memory? */
184 return NULL; /* do not update 'GCdebt' */ 184 return NULL; /* do not update 'totalbytes' */
185 } 185 }
186 lua_assert((nsize == 0) == (newblock == NULL)); 186 lua_assert((nsize == 0) == (newblock == NULL));
187 g->GCdebt = (g->GCdebt + nsize) - osize; 187 g->totalbytes += nsize - osize;
188 return newblock; 188 return newblock;
189} 189}
190 190
@@ -209,7 +209,7 @@ void *luaM_malloc_ (lua_State *L, size_t size, int tag) {
209 if (newblock == NULL) 209 if (newblock == NULL)
210 luaM_error(L); 210 luaM_error(L);
211 } 211 }
212 g->GCdebt += size; 212 g->totalbytes += size;
213 return newblock; 213 return newblock;
214 } 214 }
215} 215}
diff --git a/lmem.h b/lmem.h
index 8c75a44b..c5dada9c 100644
--- a/lmem.h
+++ b/lmem.h
@@ -63,6 +63,8 @@
63 63
64#define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) 64#define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag)
65 65
66#define luaM_newblock(L, size) luaM_newvector(L, size, char)
67
66#define luaM_growvector(L,v,nelems,size,t,limit,e) \ 68#define luaM_growvector(L,v,nelems,size,t,limit,e) \
67 ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 69 ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \
68 luaM_limitN(limit,t),e))) 70 luaM_limitN(limit,t),e)))
diff --git a/lobject.h b/lobject.h
index 556608e4..1c300e86 100644
--- a/lobject.h
+++ b/lobject.h
@@ -743,7 +743,6 @@ typedef struct Table {
743 unsigned int alimit; /* "limit" of 'array' array */ 743 unsigned int alimit; /* "limit" of 'array' array */
744 TValue *array; /* array part */ 744 TValue *array; /* array part */
745 Node *node; 745 Node *node;
746 Node *lastfree; /* any free position is before this position */
747 struct Table *metatable; 746 struct Table *metatable;
748 GCObject *gclist; 747 GCObject *gclist;
749} Table; 748} Table;
diff --git a/lparser.c b/lparser.c
index 24668c24..c0eb7890 100644
--- a/lparser.c
+++ b/lparser.c
@@ -187,10 +187,10 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
187 187
188 188
189/* 189/*
190** Create a new local variable with the given 'name'. Return its index 190** Create a new local variable with the given 'name' and given 'kind'.
191** in the function. 191** Return its index in the function.
192*/ 192*/
193static int new_localvar (LexState *ls, TString *name) { 193static int new_localvarkind (LexState *ls, TString *name, int kind) {
194 lua_State *L = ls->L; 194 lua_State *L = ls->L;
195 FuncState *fs = ls->fs; 195 FuncState *fs = ls->fs;
196 Dyndata *dyd = ls->dyd; 196 Dyndata *dyd = ls->dyd;
@@ -200,11 +200,19 @@ static int new_localvar (LexState *ls, TString *name) {
200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); 201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
202 var = &dyd->actvar.arr[dyd->actvar.n++]; 202 var = &dyd->actvar.arr[dyd->actvar.n++];
203 var->vd.kind = VDKREG; /* default */ 203 var->vd.kind = kind; /* default */
204 var->vd.name = name; 204 var->vd.name = name;
205 return dyd->actvar.n - 1 - fs->firstlocal; 205 return dyd->actvar.n - 1 - fs->firstlocal;
206} 206}
207 207
208
209/*
210** Create a new local variable with the given 'name' and regular kind.
211*/
212static int new_localvar (LexState *ls, TString *name) {
213 return new_localvarkind(ls, name, VDKREG);
214}
215
208#define new_localvarliteral(ls,v) \ 216#define new_localvarliteral(ls,v) \
209 new_localvar(ls, \ 217 new_localvar(ls, \
210 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 218 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
@@ -1550,6 +1558,7 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isgen) {
1550 int prep, endfor; 1558 int prep, endfor;
1551 checknext(ls, TK_DO); 1559 checknext(ls, TK_DO);
1552 prep = luaK_codeABx(fs, forprep[isgen], base, 0); 1560 prep = luaK_codeABx(fs, forprep[isgen], base, 0);
1561 fs->freereg--; /* both 'forprep' remove one register from the stack */
1553 enterblock(fs, &bl, 0); /* scope for declared variables */ 1562 enterblock(fs, &bl, 0); /* scope for declared variables */
1554 adjustlocalvars(ls, nvars); 1563 adjustlocalvars(ls, nvars);
1555 luaK_reserveregs(fs, nvars); 1564 luaK_reserveregs(fs, nvars);
@@ -1572,8 +1581,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1572 int base = fs->freereg; 1581 int base = fs->freereg;
1573 new_localvarliteral(ls, "(for state)"); 1582 new_localvarliteral(ls, "(for state)");
1574 new_localvarliteral(ls, "(for state)"); 1583 new_localvarliteral(ls, "(for state)");
1575 new_localvarliteral(ls, "(for state)"); 1584 new_localvarkind(ls, varname, RDKCONST); /* control variable */
1576 new_localvar(ls, varname);
1577 checknext(ls, '='); 1585 checknext(ls, '=');
1578 exp1(ls); /* initial value */ 1586 exp1(ls); /* initial value */
1579 checknext(ls, ','); 1587 checknext(ls, ',');
@@ -1584,7 +1592,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1584 luaK_int(fs, fs->freereg, 1); 1592 luaK_int(fs, fs->freereg, 1);
1585 luaK_reserveregs(fs, 1); 1593 luaK_reserveregs(fs, 1);
1586 } 1594 }
1587 adjustlocalvars(ls, 3); /* control variables */ 1595 adjustlocalvars(ls, 2); /* start scope for internal variables */
1588 forbody(ls, base, line, 1, 0); 1596 forbody(ls, base, line, 1, 0);
1589} 1597}
1590 1598
@@ -1593,16 +1601,15 @@ static void forlist (LexState *ls, TString *indexname) {
1593 /* forlist -> NAME {,NAME} IN explist forbody */ 1601 /* forlist -> NAME {,NAME} IN explist forbody */
1594 FuncState *fs = ls->fs; 1602 FuncState *fs = ls->fs;
1595 expdesc e; 1603 expdesc e;
1596 int nvars = 5; /* gen, state, control, toclose, 'indexname' */ 1604 int nvars = 4; /* function, state, closing, control */
1597 int line; 1605 int line;
1598 int base = fs->freereg; 1606 int base = fs->freereg;
1599 /* create control variables */ 1607 /* create internal variables */
1600 new_localvarliteral(ls, "(for state)"); 1608 new_localvarliteral(ls, "(for state)"); /* iterator function */
1601 new_localvarliteral(ls, "(for state)"); 1609 new_localvarliteral(ls, "(for state)"); /* state */
1602 new_localvarliteral(ls, "(for state)"); 1610 new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */
1603 new_localvarliteral(ls, "(for state)"); 1611 new_localvarkind(ls, indexname, RDKCONST); /* control variable */
1604 /* create declared variables */ 1612 /* other declared variables */
1605 new_localvar(ls, indexname);
1606 while (testnext(ls, ',')) { 1613 while (testnext(ls, ',')) {
1607 new_localvar(ls, str_checkname(ls)); 1614 new_localvar(ls, str_checkname(ls));
1608 nvars++; 1615 nvars++;
@@ -1610,10 +1617,10 @@ static void forlist (LexState *ls, TString *indexname) {
1610 checknext(ls, TK_IN); 1617 checknext(ls, TK_IN);
1611 line = ls->linenumber; 1618 line = ls->linenumber;
1612 adjust_assign(ls, 4, explist(ls, &e), &e); 1619 adjust_assign(ls, 4, explist(ls, &e), &e);
1613 adjustlocalvars(ls, 4); /* control variables */ 1620 adjustlocalvars(ls, 3); /* start scope for internal variables */
1614 marktobeclosed(fs); /* last control var. must be closed */ 1621 marktobeclosed(fs); /* last internal var. must be closed */
1615 luaK_checkstack(fs, 3); /* extra space to call generator */ 1622 luaK_checkstack(fs, 2); /* extra space to call iterator */
1616 forbody(ls, base, line, nvars - 4, 1); 1623 forbody(ls, base, line, nvars - 3, 1);
1617} 1624}
1618 1625
1619 1626
@@ -1728,14 +1735,14 @@ static void localstat (LexState *ls) {
1728 FuncState *fs = ls->fs; 1735 FuncState *fs = ls->fs;
1729 int toclose = -1; /* index of to-be-closed variable (if any) */ 1736 int toclose = -1; /* index of to-be-closed variable (if any) */
1730 Vardesc *var; /* last variable */ 1737 Vardesc *var; /* last variable */
1731 int vidx, kind; /* index and kind of last variable */ 1738 int vidx; /* index of last variable */
1732 int nvars = 0; 1739 int nvars = 0;
1733 int nexps; 1740 int nexps;
1734 expdesc e; 1741 expdesc e;
1735 do { 1742 do {
1736 vidx = new_localvar(ls, str_checkname(ls)); 1743 TString *vname = str_checkname(ls);
1737 kind = getlocalattribute(ls); 1744 int kind = getlocalattribute(ls);
1738 getlocalvardesc(fs, vidx)->vd.kind = kind; 1745 vidx = new_localvarkind(ls, vname, kind);
1739 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1746 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1740 if (toclose != -1) /* one already present? */ 1747 if (toclose != -1) /* one already present? */
1741 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1748 luaK_semerror(ls, "multiple to-be-closed variables in local list");
diff --git a/lstate.c b/lstate.c
index 1fbefb4b..bee3bf66 100644
--- a/lstate.c
+++ b/lstate.c
@@ -83,15 +83,15 @@ static unsigned int luai_makeseed (lua_State *L) {
83 83
84 84
85/* 85/*
86** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 86** set GCdebt to a new value keeping the value (totalobjs + GCdebt)
87** invariant (and avoiding underflows in 'totalbytes') 87** invariant (and avoiding underflows in 'totalobjs')
88*/ 88*/
89void luaE_setdebt (global_State *g, l_mem debt) { 89void luaE_setdebt (global_State *g, l_obj debt) {
90 l_mem tb = gettotalbytes(g); 90 l_obj tb = gettotalobjs(g);
91 lua_assert(tb > 0); 91 lua_assert(tb > 0);
92 if (debt < tb - MAX_LMEM) 92 if (debt > MAX_LOBJ - tb)
93 debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ 93 debt = MAX_LOBJ - tb; /* will make 'totalobjs == MAX_LMEM' */
94 g->totalbytes = tb - debt; 94 g->totalobjs = tb + debt;
95 g->GCdebt = debt; 95 g->GCdebt = debt;
96} 96}
97 97
@@ -278,7 +278,8 @@ static void close_state (lua_State *L) {
278 } 278 }
279 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 279 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
280 freestack(L); 280 freestack(L);
281 lua_assert(gettotalbytes(g) == sizeof(LG)); 281 lua_assert(g->totalbytes == sizeof(LG));
282 lua_assert(gettotalobjs(g) == 1);
282 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 283 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
283} 284}
284 285
@@ -387,14 +388,15 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
387 g->weak = g->ephemeron = g->allweak = NULL; 388 g->weak = g->ephemeron = g->allweak = NULL;
388 g->twups = NULL; 389 g->twups = NULL;
389 g->totalbytes = sizeof(LG); 390 g->totalbytes = sizeof(LG);
391 g->totalobjs = 1;
392 g->marked = 0;
390 g->GCdebt = 0; 393 g->GCdebt = 0;
391 g->lastatomic = 0;
392 setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ 394 setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */
393 setgcparam(g->gcpause, LUAI_GCPAUSE); 395 setgcparam(g, gcpause, LUAI_GCPAUSE);
394 setgcparam(g->gcstepmul, LUAI_GCMUL); 396 setgcparam(g, gcstepmul, LUAI_GCMUL);
395 g->gcstepsize = LUAI_GCSTEPSIZE; 397 g->gcstepsize = LUAI_GCSTEPSIZE;
396 setgcparam(g->genmajormul, LUAI_GENMAJORMUL); 398 setgcparam(g, genmajormul, LUAI_GENMAJORMUL);
397 g->genminormul = LUAI_GENMINORMUL; 399 setgcparam(g, genminormul, LUAI_GENMINORMUL);
398 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 400 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
399 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 401 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
400 /* memory allocation error: free partial state */ 402 /* memory allocation error: free partial state */
diff --git a/lstate.h b/lstate.h
index 8bf6600e..50273295 100644
--- a/lstate.h
+++ b/lstate.h
@@ -150,12 +150,13 @@ struct lua_longjmp; /* defined in ldo.c */
150/* kinds of Garbage Collection */ 150/* kinds of Garbage Collection */
151#define KGC_INC 0 /* incremental gc */ 151#define KGC_INC 0 /* incremental gc */
152#define KGC_GEN 1 /* generational gc */ 152#define KGC_GEN 1 /* generational gc */
153#define KGC_GENMAJOR 2 /* generational in "major" mode */
153 154
154 155
155typedef struct stringtable { 156typedef struct stringtable {
156 TString **hash; 157 TString **hash; /* array of buckets (linked lists of strings) */
157 int nuse; /* number of elements */ 158 int nuse; /* number of elements */
158 int size; 159 int size; /* number of buckets */
159} stringtable; 160} stringtable;
160 161
161 162
@@ -254,10 +255,11 @@ struct CallInfo {
254typedef struct global_State { 255typedef struct global_State {
255 lua_Alloc frealloc; /* function to reallocate memory */ 256 lua_Alloc frealloc; /* function to reallocate memory */
256 void *ud; /* auxiliary data to 'frealloc' */ 257 void *ud; /* auxiliary data to 'frealloc' */
257 l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 258 lu_mem totalbytes; /* number of bytes currently allocated */
258 l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 259 l_obj totalobjs; /* total number of objects allocated + GCdebt */
259 lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 260 l_obj GCdebt; /* objects counted but not yet allocated */
260 lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ 261 l_obj marked; /* number of objects marked in a GC cycle */
262 l_obj GClastmajor; /* objects at last major collection */
261 stringtable strt; /* hash table for strings */ 263 stringtable strt; /* hash table for strings */
262 TValue l_registry; 264 TValue l_registry;
263 TValue nilvalue; /* a nil value */ 265 TValue nilvalue; /* a nil value */
@@ -390,10 +392,11 @@ union GCUnion {
390#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) 392#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc))
391 393
392 394
393/* actual number of total bytes allocated */ 395/* actual number of total objects allocated */
394#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) 396#define gettotalobjs(g) ((g)->totalobjs - (g)->GCdebt)
395 397
396LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 398
399LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt);
397LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 400LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
398LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 401LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
399LUAI_FUNC void luaE_freeCI (lua_State *L); 402LUAI_FUNC void luaE_freeCI (lua_State *L);
diff --git a/lstrlib.c b/lstrlib.c
index 0b4fdbb7..ce07d9bc 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -239,6 +239,7 @@ static int str_dump (lua_State *L) {
239 if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) 239 if (l_unlikely(lua_dump(L, writer, &state, strip) != 0))
240 return luaL_error(L, "unable to dump given function"); 240 return luaL_error(L, "unable to dump given function");
241 luaL_pushresult(&state.B); 241 luaL_pushresult(&state.B);
242 lua_assert(lua_isfunction(L, 1)); /* lua_dump kept that value */
242 return 1; 243 return 1;
243} 244}
244 245
diff --git a/ltable.c b/ltable.c
index cc7993e0..485563f3 100644
--- a/ltable.c
+++ b/ltable.c
@@ -40,6 +40,27 @@
40 40
41 41
42/* 42/*
43** Only tables with hash parts larget than LIMFORLAST has a 'lastfree'
44** field that optimizes finding a free slot. Smaller tables do a
45** complete search when looking for a free slot.
46*/
47#define LLIMFORLAST 2 /* log2 of LIMTFORLAST */
48#define LIMFORLAST twoto(LLIMFORLAST)
49
50/*
51** Union to store an int field ensuring that what follows it in
52** memory is properly aligned to store a TValue.
53*/
54typedef union {
55 int lastfree;
56 char padding[offsetof(struct { int i; TValue v; }, v)];
57} Limbox;
58
59#define haslastfree(t) ((t)->lsizenode > LLIMFORLAST)
60#define getlastfree(t) (&((cast(Limbox *, (t)->node) - 1)->lastfree))
61
62
63/*
43** MAXABITS is the largest integer such that MAXASIZE fits in an 64** MAXABITS is the largest integer such that MAXASIZE fits in an
44** unsigned int. 65** unsigned int.
45*/ 66*/
@@ -367,8 +388,15 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
367 388
368 389
369static void freehash (lua_State *L, Table *t) { 390static void freehash (lua_State *L, Table *t) {
370 if (!isdummy(t)) 391 if (!isdummy(t)) {
371 luaM_freearray(L, t->node, cast_sizet(sizenode(t))); 392 size_t bsize = sizenode(t) * sizeof(Node); /* 'node' size in bytes */
393 char *arr = cast_charp(t->node);
394 if (haslastfree(t)) {
395 bsize += sizeof(Limbox);
396 arr -= sizeof(Limbox);
397 }
398 luaM_freearray(L, arr, bsize);
399 }
372} 400}
373 401
374 402
@@ -479,7 +507,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
479 if (size == 0) { /* no elements to hash part? */ 507 if (size == 0) { /* no elements to hash part? */
480 t->node = cast(Node *, dummynode); /* use common 'dummynode' */ 508 t->node = cast(Node *, dummynode); /* use common 'dummynode' */
481 t->lsizenode = 0; 509 t->lsizenode = 0;
482 t->lastfree = NULL; /* signal that it is using dummy node */ 510 setdummy(t); /* signal that it is using dummy node */
483 } 511 }
484 else { 512 else {
485 int i; 513 int i;
@@ -487,15 +515,22 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
487 if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) 515 if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE)
488 luaG_runerror(L, "table overflow"); 516 luaG_runerror(L, "table overflow");
489 size = twoto(lsize); 517 size = twoto(lsize);
490 t->node = luaM_newvector(L, size, Node); 518 if (lsize <= LLIMFORLAST) /* no 'lastfree' field? */
519 t->node = luaM_newvector(L, size, Node);
520 else {
521 size_t bsize = size * sizeof(Node) + sizeof(Limbox);
522 char *node = luaM_newblock(L, bsize);
523 t->node = cast(Node *, node + sizeof(Limbox));
524 *getlastfree(t) = size; /* all positions are free */
525 }
526 t->lsizenode = cast_byte(lsize);
527 setnodummy(t);
491 for (i = 0; i < cast_int(size); i++) { 528 for (i = 0; i < cast_int(size); i++) {
492 Node *n = gnode(t, i); 529 Node *n = gnode(t, i);
493 gnext(n) = 0; 530 gnext(n) = 0;
494 setnilkey(n); 531 setnilkey(n);
495 setempty(gval(n)); 532 setempty(gval(n));
496 } 533 }
497 t->lsizenode = cast_byte(lsize);
498 t->lastfree = gnode(t, size); /* all positions are free */
499 } 534 }
500} 535}
501 536
@@ -520,18 +555,21 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
520 555
521 556
522/* 557/*
523** Exchange the hash part of 't1' and 't2'. 558** Exchange the hash part of 't1' and 't2'. (In 'flags', only the
559** dummy bit must be exchanged: The 'isrealasize' is not related
560** to the hash part, and the metamethod bits do not change during
561** a resize, so the "real" table can keep their values.)
524*/ 562*/
525static void exchangehashpart (Table *t1, Table *t2) { 563static void exchangehashpart (Table *t1, Table *t2) {
526 lu_byte lsizenode = t1->lsizenode; 564 lu_byte lsizenode = t1->lsizenode;
527 Node *node = t1->node; 565 Node *node = t1->node;
528 Node *lastfree = t1->lastfree; 566 int bitdummy1 = t1->flags & BITDUMMY;
529 t1->lsizenode = t2->lsizenode; 567 t1->lsizenode = t2->lsizenode;
530 t1->node = t2->node; 568 t1->node = t2->node;
531 t1->lastfree = t2->lastfree; 569 t1->flags = (t1->flags & NOTBITDUMMY) | (t2->flags & BITDUMMY);
532 t2->lsizenode = lsizenode; 570 t2->lsizenode = lsizenode;
533 t2->node = node; 571 t2->node = node;
534 t2->lastfree = lastfree; 572 t2->flags = (t2->flags & NOTBITDUMMY) | bitdummy1;
535} 573}
536 574
537 575
@@ -555,6 +593,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
555 unsigned int oldasize = setlimittosize(t); 593 unsigned int oldasize = setlimittosize(t);
556 TValue *newarray; 594 TValue *newarray;
557 /* create new hash part with appropriate size into 'newt' */ 595 /* create new hash part with appropriate size into 'newt' */
596 newt.flags = 0;
558 setnodevector(L, &newt, nhsize); 597 setnodevector(L, &newt, nhsize);
559 if (newasize < oldasize) { /* will array shrink? */ 598 if (newasize < oldasize) { /* will array shrink? */
560 t->alimit = newasize; /* pretend array has new size... */ 599 t->alimit = newasize; /* pretend array has new size... */
@@ -641,11 +680,22 @@ void luaH_free (lua_State *L, Table *t) {
641 680
642 681
643static Node *getfreepos (Table *t) { 682static Node *getfreepos (Table *t) {
644 if (!isdummy(t)) { 683 if (haslastfree(t)) { /* does it have 'lastfree' information? */
645 while (t->lastfree > t->node) { 684 /* look for a spot before 'lastfree', updating 'lastfree' */
646 t->lastfree--; 685 while (*getlastfree(t) > 0) {
647 if (keyisnil(t->lastfree)) 686 Node *free = gnode(t, --(*getlastfree(t)));
648 return t->lastfree; 687 if (keyisnil(free))
688 return free;
689 }
690 }
691 else { /* no 'lastfree' information */
692 if (!isdummy(t)) {
693 int i = sizenode(t);
694 while (i--) { /* do a linear search */
695 Node *free = gnode(t, i);
696 if (keyisnil(free))
697 return free;
698 }
649 } 699 }
650 } 700 }
651 return NULL; /* could not find a free place */ 701 return NULL; /* could not find a free place */
diff --git a/ltable.h b/ltable.h
index 75dd9e26..dce8c2f7 100644
--- a/ltable.h
+++ b/ltable.h
@@ -23,8 +23,18 @@
23#define invalidateTMcache(t) ((t)->flags &= ~maskflags) 23#define invalidateTMcache(t) ((t)->flags &= ~maskflags)
24 24
25 25
26/* true when 't' is using 'dummynode' as its hash part */ 26/*
27#define isdummy(t) ((t)->lastfree == NULL) 27** Bit BITDUMMY set in 'flags' means the table is using the dummy node
28** for its hash part.
29*/
30
31#define BITDUMMY (1 << 6)
32#define NOTBITDUMMY cast_byte(~BITDUMMY)
33#define isdummy(t) ((t)->flags & BITDUMMY)
34
35#define setnodummy(t) ((t)->flags &= NOTBITDUMMY)
36#define setdummy(t) ((t)->flags |= BITDUMMY)
37
28 38
29 39
30/* allocated size for hash nodes */ 40/* allocated size for hash nodes */
diff --git a/ltests.c b/ltests.c
index 4a0a6af1..e2e0d983 100644
--- a/ltests.c
+++ b/ltests.c
@@ -297,7 +297,7 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
297 if (isdead(g,t)) return 0; 297 if (isdead(g,t)) return 0;
298 if (issweepphase(g)) 298 if (issweepphase(g))
299 return 1; /* no invariants */ 299 return 1; /* no invariants */
300 else if (g->gckind == KGC_INC) 300 else if (g->gckind != KGC_GEN)
301 return !(isblack(f) && iswhite(t)); /* basic incremental invariant */ 301 return !(isblack(f) && iswhite(t)); /* basic incremental invariant */
302 else { /* generational mode */ 302 else { /* generational mode */
303 if ((getage(f) == G_OLD && isblack(f)) && !isold(t)) 303 if ((getage(f) == G_OLD && isblack(f)) && !isold(t))
@@ -531,7 +531,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead,
531} 531}
532 532
533 533
534static lu_mem checkgraylist (global_State *g, GCObject *o) { 534static l_obj checkgraylist (global_State *g, GCObject *o) {
535 int total = 0; /* count number of elements in the list */ 535 int total = 0; /* count number of elements in the list */
536 cast_void(g); /* better to keep it if we need to print an object */ 536 cast_void(g); /* better to keep it if we need to print an object */
537 while (o) { 537 while (o) {
@@ -560,7 +560,7 @@ static lu_mem checkgraylist (global_State *g, GCObject *o) {
560/* 560/*
561** Check objects in gray lists. 561** Check objects in gray lists.
562*/ 562*/
563static lu_mem checkgrays (global_State *g) { 563static l_obj checkgrays (global_State *g) {
564 int total = 0; /* count number of elements in all lists */ 564 int total = 0; /* count number of elements in all lists */
565 if (!keepinvariant(g)) return total; 565 if (!keepinvariant(g)) return total;
566 total += checkgraylist(g, g->gray); 566 total += checkgraylist(g, g->gray);
@@ -577,7 +577,7 @@ static lu_mem checkgrays (global_State *g) {
577** 'count' and check its TESTBIT. (It must have been previously set by 577** 'count' and check its TESTBIT. (It must have been previously set by
578** 'checkgraylist'.) 578** 'checkgraylist'.)
579*/ 579*/
580static void incifingray (global_State *g, GCObject *o, lu_mem *count) { 580static void incifingray (global_State *g, GCObject *o, l_obj *count) {
581 if (!keepinvariant(g)) 581 if (!keepinvariant(g))
582 return; /* gray lists not being kept in these phases */ 582 return; /* gray lists not being kept in these phases */
583 if (o->tt == LUA_VUPVAL) { 583 if (o->tt == LUA_VUPVAL) {
@@ -594,10 +594,10 @@ static void incifingray (global_State *g, GCObject *o, lu_mem *count) {
594} 594}
595 595
596 596
597static lu_mem checklist (global_State *g, int maybedead, int tof, 597static l_obj checklist (global_State *g, int maybedead, int tof,
598 GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) { 598 GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) {
599 GCObject *o; 599 GCObject *o;
600 lu_mem total = 0; /* number of object that should be in gray lists */ 600 l_obj total = 0; /* number of object that should be in gray lists */
601 for (o = newl; o != survival; o = o->next) { 601 for (o = newl; o != survival; o = o->next) {
602 checkobject(g, o, maybedead, G_NEW); 602 checkobject(g, o, maybedead, G_NEW);
603 incifingray(g, o, &total); 603 incifingray(g, o, &total);
@@ -626,8 +626,8 @@ int lua_checkmemory (lua_State *L) {
626 global_State *g = G(L); 626 global_State *g = G(L);
627 GCObject *o; 627 GCObject *o;
628 int maybedead; 628 int maybedead;
629 lu_mem totalin; /* total of objects that are in gray lists */ 629 l_obj totalin; /* total of objects that are in gray lists */
630 lu_mem totalshould; /* total of objects that should be in gray lists */ 630 l_obj totalshould; /* total of objects that should be in gray lists */
631 if (keepinvariant(g)) { 631 if (keepinvariant(g)) {
632 assert(!iswhite(g->mainthread)); 632 assert(!iswhite(g->mainthread));
633 assert(!iswhite(gcvalue(&g->l_registry))); 633 assert(!iswhite(gcvalue(&g->l_registry)));
@@ -999,9 +999,8 @@ static int table_query (lua_State *L) {
999 if (i == -1) { 999 if (i == -1) {
1000 lua_pushinteger(L, asize); 1000 lua_pushinteger(L, asize);
1001 lua_pushinteger(L, allocsizenode(t)); 1001 lua_pushinteger(L, allocsizenode(t));
1002 lua_pushinteger(L, isdummy(t) ? 0 : t->lastfree - t->node);
1003 lua_pushinteger(L, t->alimit); 1002 lua_pushinteger(L, t->alimit);
1004 return 4; 1003 return 3;
1005 } 1004 }
1006 else if ((unsigned int)i < asize) { 1005 else if ((unsigned int)i < asize) {
1007 lua_pushinteger(L, i); 1006 lua_pushinteger(L, i);
@@ -1028,6 +1027,16 @@ static int table_query (lua_State *L) {
1028} 1027}
1029 1028
1030 1029
1030static int query_inc (lua_State *L) {
1031 global_State *g = G(L);
1032 lua_pushinteger(L, gettotalobjs(g));
1033 lua_pushinteger(L, g->GCdebt);
1034 lua_pushinteger(L, applygcparam(g, gcpause, 100));
1035 lua_pushinteger(L, applygcparam(g, gcstepmul, 100));
1036 lua_pushinteger(L, cast(l_obj, 1) << g->gcstepsize);
1037 return 5;
1038}
1039
1031static int string_query (lua_State *L) { 1040static int string_query (lua_State *L) {
1032 stringtable *tb = &G(L)->strt; 1041 stringtable *tb = &G(L)->strt;
1033 int s = cast_int(luaL_optinteger(L, 1, 0)) - 1; 1042 int s = cast_int(luaL_optinteger(L, 1, 0)) - 1;
@@ -1169,31 +1178,15 @@ static lua_State *getstate (lua_State *L) {
1169 1178
1170 1179
1171static int loadlib (lua_State *L) { 1180static int loadlib (lua_State *L) {
1172 static const luaL_Reg libs[] = {
1173 {LUA_GNAME, luaopen_base},
1174 {"coroutine", luaopen_coroutine},
1175 {"debug", luaopen_debug},
1176 {"io", luaopen_io},
1177 {"os", luaopen_os},
1178 {"math", luaopen_math},
1179 {"string", luaopen_string},
1180 {"table", luaopen_table},
1181 {"T", luaB_opentests},
1182 {NULL, NULL}
1183 };
1184 lua_State *L1 = getstate(L); 1181 lua_State *L1 = getstate(L);
1185 int i; 1182 int what = luaL_checkinteger(L, 2);
1186 luaL_requiref(L1, "package", luaopen_package, 0); 1183 luaL_openselectedlibs(L1, what);
1184 luaL_requiref(L1, "T", luaB_opentests, 0);
1187 lua_assert(lua_type(L1, -1) == LUA_TTABLE); 1185 lua_assert(lua_type(L1, -1) == LUA_TTABLE);
1188 /* 'requiref' should not reload module already loaded... */ 1186 /* 'requiref' should not reload module already loaded... */
1189 luaL_requiref(L1, "package", NULL, 1); /* seg. fault if it reloads */ 1187 luaL_requiref(L1, "T", NULL, 1); /* seg. fault if it reloads */
1190 /* ...but should return the same module */ 1188 /* ...but should return the same module */
1191 lua_assert(lua_compare(L1, -1, -2, LUA_OPEQ)); 1189 lua_assert(lua_compare(L1, -1, -2, LUA_OPEQ));
1192 luaL_getsubtable(L1, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
1193 for (i = 0; libs[i].name; i++) {
1194 lua_pushcfunction(L1, libs[i].func);
1195 lua_setfield(L1, -2, libs[i].name);
1196 }
1197 return 0; 1190 return 0;
1198} 1191}
1199 1192
@@ -1934,6 +1927,7 @@ static const struct luaL_Reg tests_funcs[] = {
1934 {"pushuserdata", pushuserdata}, 1927 {"pushuserdata", pushuserdata},
1935 {"querystr", string_query}, 1928 {"querystr", string_query},
1936 {"querytab", table_query}, 1929 {"querytab", table_query},
1930 {"queryinc", query_inc},
1937 {"ref", tref}, 1931 {"ref", tref},
1938 {"resume", coresume}, 1932 {"resume", coresume},
1939 {"s2d", s2d}, 1933 {"s2d", s2d},
diff --git a/ltests.h b/ltests.h
index ec520498..45d5beba 100644
--- a/ltests.h
+++ b/ltests.h
@@ -103,8 +103,8 @@ LUA_API void *debug_realloc (void *ud, void *block,
103 103
104#if defined(lua_c) 104#if defined(lua_c)
105#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) 105#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
106#define luaL_openlibs(L) \ 106#define luai_openlibs(L) \
107 { (luaL_openlibs)(L); \ 107 { luaL_openlibs(L); \
108 luaL_requiref(L, "T", luaB_opentests, 1); \ 108 luaL_requiref(L, "T", luaB_opentests, 1); \
109 lua_pop(L, 1); } 109 lua_pop(L, 1); }
110#endif 110#endif
diff --git a/ltm.c b/ltm.c
index 07a06081..8e0d2222 100644
--- a/ltm.c
+++ b/ltm.c
@@ -260,7 +260,7 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
260 int nextra = ci->u.l.nextraargs; 260 int nextra = ci->u.l.nextraargs;
261 if (wanted < 0) { 261 if (wanted < 0) {
262 wanted = nextra; /* get all extra arguments available */ 262 wanted = nextra; /* get all extra arguments available */
263 checkstackGCp(L, nextra, where); /* ensure stack space */ 263 checkstackp(L, nextra, where); /* ensure stack space */
264 L->top.p = where + nextra; /* next instruction will need top */ 264 L->top.p = where + nextra; /* next instruction will need top */
265 } 265 }
266 for (i = 0; i < wanted && i < nextra; i++) 266 for (i = 0; i < wanted && i < nextra; i++)
diff --git a/ltm.h b/ltm.h
index c309e2ae..82a26a96 100644
--- a/ltm.h
+++ b/ltm.h
@@ -49,8 +49,8 @@ typedef enum {
49/* 49/*
50** Mask with 1 in all fast-access methods. A 1 in any of these bits 50** Mask with 1 in all fast-access methods. A 1 in any of these bits
51** in the flag of a (meta)table means the metatable does not have the 51** in the flag of a (meta)table means the metatable does not have the
52** corresponding metamethod field. (Bit 7 of the flag is used for 52** corresponding metamethod field. (Bit 6 of the flag indicates that
53** 'isrealasize'.) 53** the table is using the dummy node; bit 7 is used for 'isrealasize'.)
54*/ 54*/
55#define maskflags (~(~0u << (TM_EQ + 1))) 55#define maskflags (~(~0u << (TM_EQ + 1)))
56 56
diff --git a/lua.c b/lua.c
index 715430a0..af20754e 100644
--- a/lua.c
+++ b/lua.c
@@ -609,6 +609,10 @@ static void doREPL (lua_State *L) {
609 609
610/* }================================================================== */ 610/* }================================================================== */
611 611
612#if !defined(luai_openlibs)
613#define luai_openlibs(L) luaL_openlibs(L)
614#endif
615
612 616
613/* 617/*
614** Main body of stand-alone interpreter (to be called in protected mode). 618** Main body of stand-alone interpreter (to be called in protected mode).
@@ -631,7 +635,7 @@ static int pmain (lua_State *L) {
631 lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ 635 lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
632 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 636 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
633 } 637 }
634 luaL_openlibs(L); /* open standard libraries */ 638 luai_openlibs(L); /* open standard libraries */
635 createargtable(L, argv, argc, script); /* create table 'arg' */ 639 createargtable(L, argv, argc, script); /* create table 'arg' */
636 lua_gc(L, LUA_GCRESTART); /* start GC... */ 640 lua_gc(L, LUA_GCRESTART); /* start GC... */
637 lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */ 641 lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */
diff --git a/lua.h b/lua.h
index feb3dbc5..cb32ec22 100644
--- a/lua.h
+++ b/lua.h
@@ -17,11 +17,11 @@
17 17
18 18
19#define LUA_VERSION_MAJOR "5" 19#define LUA_VERSION_MAJOR "5"
20#define LUA_VERSION_MINOR "4" 20#define LUA_VERSION_MINOR "5"
21#define LUA_VERSION_RELEASE "5" 21#define LUA_VERSION_RELEASE "0"
22 22
23#define LUA_VERSION_NUM 504 23#define LUA_VERSION_NUM 505
24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 5) 24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0)
25 25
26#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR 26#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
27#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE 27#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
diff --git a/lualib.h b/lualib.h
index 26255290..e124cf1b 100644
--- a/lualib.h
+++ b/lualib.h
@@ -14,39 +14,52 @@
14/* version suffix for environment variable names */ 14/* version suffix for environment variable names */
15#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 15#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
16 16
17 17#define LUA_GK 1
18LUAMOD_API int (luaopen_base) (lua_State *L); 18LUAMOD_API int (luaopen_base) (lua_State *L);
19 19
20#define LUA_LOADLIBNAME "package"
21#define LUA_LOADLIBK (LUA_GK << 1)
22LUAMOD_API int (luaopen_package) (lua_State *L);
23
24
20#define LUA_COLIBNAME "coroutine" 25#define LUA_COLIBNAME "coroutine"
26#define LUA_COLIBK (LUA_LOADLIBK << 1)
21LUAMOD_API int (luaopen_coroutine) (lua_State *L); 27LUAMOD_API int (luaopen_coroutine) (lua_State *L);
22 28
23#define LUA_TABLIBNAME "table" 29#define LUA_DBLIBNAME "debug"
24LUAMOD_API int (luaopen_table) (lua_State *L); 30#define LUA_DBLIBK (LUA_COLIBK << 1)
31LUAMOD_API int (luaopen_debug) (lua_State *L);
25 32
26#define LUA_IOLIBNAME "io" 33#define LUA_IOLIBNAME "io"
34#define LUA_IOLIBK (LUA_DBLIBK << 1)
27LUAMOD_API int (luaopen_io) (lua_State *L); 35LUAMOD_API int (luaopen_io) (lua_State *L);
28 36
37#define LUA_MATHLIBNAME "math"
38#define LUA_MATHLIBK (LUA_IOLIBK << 1)
39LUAMOD_API int (luaopen_math) (lua_State *L);
40
29#define LUA_OSLIBNAME "os" 41#define LUA_OSLIBNAME "os"
42#define LUA_OSLIBK (LUA_MATHLIBK << 1)
30LUAMOD_API int (luaopen_os) (lua_State *L); 43LUAMOD_API int (luaopen_os) (lua_State *L);
31 44
32#define LUA_STRLIBNAME "string" 45#define LUA_STRLIBNAME "string"
46#define LUA_STRLIBK (LUA_OSLIBK << 1)
33LUAMOD_API int (luaopen_string) (lua_State *L); 47LUAMOD_API int (luaopen_string) (lua_State *L);
34 48
49#define LUA_TABLIBNAME "table"
50#define LUA_TABLIBK (LUA_STRLIBK << 1)
51LUAMOD_API int (luaopen_table) (lua_State *L);
52
35#define LUA_UTF8LIBNAME "utf8" 53#define LUA_UTF8LIBNAME "utf8"
54#define LUA_UTF8LIBK (LUA_TABLIBK << 1)
36LUAMOD_API int (luaopen_utf8) (lua_State *L); 55LUAMOD_API int (luaopen_utf8) (lua_State *L);
37 56
38#define LUA_MATHLIBNAME "math"
39LUAMOD_API int (luaopen_math) (lua_State *L);
40
41#define LUA_DBLIBNAME "debug"
42LUAMOD_API int (luaopen_debug) (lua_State *L);
43
44#define LUA_LOADLIBNAME "package"
45LUAMOD_API int (luaopen_package) (lua_State *L);
46 57
58/* open selected libraries */
59LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what);
47 60
48/* open all previous libraries */ 61/* open all libraries */
49LUALIB_API void (luaL_openlibs) (lua_State *L); 62#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0)
50 63
51 64
52#endif 65#endif
diff --git a/lundump.c b/lundump.c
index aba93f82..3bff463f 100644
--- a/lundump.c
+++ b/lundump.c
@@ -21,6 +21,7 @@
21#include "lmem.h" 21#include "lmem.h"
22#include "lobject.h" 22#include "lobject.h"
23#include "lstring.h" 23#include "lstring.h"
24#include "ltable.h"
24#include "lundump.h" 25#include "lundump.h"
25#include "lzio.h" 26#include "lzio.h"
26 27
@@ -34,6 +35,8 @@ typedef struct {
34 lua_State *L; 35 lua_State *L;
35 ZIO *Z; 36 ZIO *Z;
36 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */
39 lua_Integer nstr; /* number of strings in the list */
37} LoadState; 40} LoadState;
38 41
39 42
@@ -110,10 +113,16 @@ static lua_Integer loadInteger (LoadState *S) {
110static TString *loadStringN (LoadState *S, Proto *p) { 113static TString *loadStringN (LoadState *S, Proto *p) {
111 lua_State *L = S->L; 114 lua_State *L = S->L;
112 TString *ts; 115 TString *ts;
116 TValue sv;
113 size_t size = loadSize(S); 117 size_t size = loadSize(S);
114 if (size == 0) /* no string? */ 118 if (size == 0) /* no string? */
115 return NULL; 119 return NULL;
116 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 120 else if (size == 1) { /* previously saved string? */
121 int idx = loadInt(S); /* get its index */
122 const TValue *stv = luaH_getint(S->h, idx);
123 return tsvalue(stv);
124 }
125 else if (size -= 2, size <= LUAI_MAXSHORTLEN) { /* short string? */
117 char buff[LUAI_MAXSHORTLEN]; 126 char buff[LUAI_MAXSHORTLEN];
118 loadVector(S, buff, size); /* load string into buffer */ 127 loadVector(S, buff, size); /* load string into buffer */
119 ts = luaS_newlstr(L, buff, size); /* create string */ 128 ts = luaS_newlstr(L, buff, size); /* create string */
@@ -126,6 +135,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
126 L->top.p--; /* pop string */ 135 L->top.p--; /* pop string */
127 } 136 }
128 luaC_objbarrier(L, p, ts); 137 luaC_objbarrier(L, p, ts);
138 S->nstr++; /* add string to list of saved strings */
139 setsvalue(L, &sv, ts);
140 luaH_setint(L, S->h, S->nstr, &sv);
141 luaC_objbarrierback(L, obj2gco(S->h), ts);
129 return ts; 142 return ts;
130} 143}
131 144
@@ -149,7 +162,7 @@ static void loadCode (LoadState *S, Proto *f) {
149} 162}
150 163
151 164
152static void loadFunction(LoadState *S, Proto *f, TString *psource); 165static void loadFunction(LoadState *S, Proto *f);
153 166
154 167
155static void loadConstants (LoadState *S, Proto *f) { 168static void loadConstants (LoadState *S, Proto *f) {
@@ -198,7 +211,7 @@ static void loadProtos (LoadState *S, Proto *f) {
198 for (i = 0; i < n; i++) { 211 for (i = 0; i < n; i++) {
199 f->p[i] = luaF_newproto(S->L); 212 f->p[i] = luaF_newproto(S->L);
200 luaC_objbarrier(S->L, f, f->p[i]); 213 luaC_objbarrier(S->L, f, f->p[i]);
201 loadFunction(S, f->p[i], f->source); 214 loadFunction(S, f->p[i]);
202 } 215 }
203} 216}
204 217
@@ -253,10 +266,8 @@ static void loadDebug (LoadState *S, Proto *f) {
253} 266}
254 267
255 268
256static void loadFunction (LoadState *S, Proto *f, TString *psource) { 269static void loadFunction (LoadState *S, Proto *f) {
257 f->source = loadStringN(S, f); 270 f->source = loadStringN(S, f);
258 if (f->source == NULL) /* no source in dump? */
259 f->source = psource; /* reuse parent's source */
260 f->linedefined = loadInt(S); 271 f->linedefined = loadInt(S);
261 f->lastlinedefined = loadInt(S); 272 f->lastlinedefined = loadInt(S);
262 f->numparams = loadByte(S); 273 f->numparams = loadByte(S);
@@ -323,11 +334,16 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
323 cl = luaF_newLclosure(L, loadByte(&S)); 334 cl = luaF_newLclosure(L, loadByte(&S));
324 setclLvalue2s(L, L->top.p, cl); 335 setclLvalue2s(L, L->top.p, cl);
325 luaD_inctop(L); 336 luaD_inctop(L);
337 S.h = luaH_new(L); /* create list of saved strings */
338 S.nstr = 0;
339 sethvalue2s(L, L->top.p, S.h); /* anchor it */
340 luaD_inctop(L);
326 cl->p = luaF_newproto(L); 341 cl->p = luaF_newproto(L);
327 luaC_objbarrier(L, cl, cl->p); 342 luaC_objbarrier(L, cl, cl->p);
328 loadFunction(&S, cl->p, NULL); 343 loadFunction(&S, cl->p);
329 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 344 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
330 luai_verifycode(L, cl->p); 345 luai_verifycode(L, cl->p);
346 L->top.p--; /* pop table */
331 return cl; 347 return cl;
332} 348}
333 349
diff --git a/lundump.h b/lundump.h
index f3748a99..7def905b 100644
--- a/lundump.h
+++ b/lundump.h
@@ -31,6 +31,6 @@ LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
31 31
32/* dump one chunk; from ldump.c */ 32/* dump one chunk; from ldump.c */
33LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 33LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
34 void* data, int strip); 34 void* data, int strip, Table *h);
35 35
36#endif 36#endif
diff --git a/lvm.c b/lvm.c
index 2e84dc63..8ab8753d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -196,12 +196,15 @@ static int forlimit (lua_State *L, lua_Integer init, const TValue *lim,
196 196
197/* 197/*
198** Prepare a numerical for loop (opcode OP_FORPREP). 198** Prepare a numerical for loop (opcode OP_FORPREP).
199** Before execution, stack is as follows:
200** ra : initial value
201** ra + 1 : limit
202** ra + 2 : step
199** Return true to skip the loop. Otherwise, 203** Return true to skip the loop. Otherwise,
200** after preparation, stack will be as follows: 204** after preparation, stack will be as follows:
201** ra : internal index (safe copy of the control variable) 205** ra : loop counter (integer loops) or limit (float loops)
202** ra + 1 : loop counter (integer loops) or limit (float loops) 206** ra + 1 : step
203** ra + 2 : step 207** ra + 2 : control variable
204** ra + 3 : control variable
205*/ 208*/
206static int forprep (lua_State *L, StkId ra) { 209static int forprep (lua_State *L, StkId ra) {
207 TValue *pinit = s2v(ra); 210 TValue *pinit = s2v(ra);
@@ -213,7 +216,6 @@ static int forprep (lua_State *L, StkId ra) {
213 lua_Integer limit; 216 lua_Integer limit;
214 if (step == 0) 217 if (step == 0)
215 luaG_runerror(L, "'for' step is zero"); 218 luaG_runerror(L, "'for' step is zero");
216 setivalue(s2v(ra + 3), init); /* control variable */
217 if (forlimit(L, init, plimit, &limit, step)) 219 if (forlimit(L, init, plimit, &limit, step))
218 return 1; /* skip the loop */ 220 return 1; /* skip the loop */
219 else { /* prepare loop counter */ 221 else { /* prepare loop counter */
@@ -228,9 +230,10 @@ static int forprep (lua_State *L, StkId ra) {
228 /* 'step+1' avoids negating 'mininteger' */ 230 /* 'step+1' avoids negating 'mininteger' */
229 count /= l_castS2U(-(step + 1)) + 1u; 231 count /= l_castS2U(-(step + 1)) + 1u;
230 } 232 }
231 /* store the counter in place of the limit (which won't be 233 /* use 'chgivalue' for places that for sure had integers */
232 needed anymore) */ 234 chgivalue(s2v(ra), l_castU2S(count)); /* change init to count */
233 setivalue(plimit, l_castU2S(count)); 235 setivalue(s2v(ra + 1), step); /* change limit to step */
236 chgivalue(s2v(ra + 2), init); /* change step to init */
234 } 237 }
235 } 238 }
236 else { /* try making all values floats */ 239 else { /* try making all values floats */
@@ -247,11 +250,10 @@ static int forprep (lua_State *L, StkId ra) {
247 : luai_numlt(init, limit)) 250 : luai_numlt(init, limit))
248 return 1; /* skip the loop */ 251 return 1; /* skip the loop */
249 else { 252 else {
250 /* make sure internal values are all floats */ 253 /* make sure all values are floats */
251 setfltvalue(plimit, limit); 254 setfltvalue(s2v(ra), limit);
252 setfltvalue(pstep, step); 255 setfltvalue(s2v(ra + 1), step);
253 setfltvalue(s2v(ra), init); /* internal index */ 256 setfltvalue(s2v(ra + 2), init); /* control variable */
254 setfltvalue(s2v(ra + 3), init); /* control variable */
255 } 257 }
256 } 258 }
257 return 0; 259 return 0;
@@ -264,14 +266,13 @@ static int forprep (lua_State *L, StkId ra) {
264** written online with opcode OP_FORLOOP, for performance.) 266** written online with opcode OP_FORLOOP, for performance.)
265*/ 267*/
266static int floatforloop (StkId ra) { 268static int floatforloop (StkId ra) {
267 lua_Number step = fltvalue(s2v(ra + 2)); 269 lua_Number step = fltvalue(s2v(ra + 1));
268 lua_Number limit = fltvalue(s2v(ra + 1)); 270 lua_Number limit = fltvalue(s2v(ra));
269 lua_Number idx = fltvalue(s2v(ra)); /* internal index */ 271 lua_Number idx = fltvalue(s2v(ra + 2)); /* control variable */
270 idx = luai_numadd(L, idx, step); /* increment index */ 272 idx = luai_numadd(L, idx, step); /* increment index */
271 if (luai_numlt(0, step) ? luai_numle(idx, limit) 273 if (luai_numlt(0, step) ? luai_numle(idx, limit)
272 : luai_numle(limit, idx)) { 274 : luai_numle(limit, idx)) {
273 chgfltvalue(s2v(ra), idx); /* update internal index */ 275 chgfltvalue(s2v(ra + 2), idx); /* update control variable */
274 setfltvalue(s2v(ra + 3), idx); /* and control variable */
275 return 1; /* jump back */ 276 return 1; /* jump back */
276 } 277 }
277 else 278 else
@@ -1781,15 +1782,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1781 } 1782 }
1782 vmcase(OP_FORLOOP) { 1783 vmcase(OP_FORLOOP) {
1783 StkId ra = RA(i); 1784 StkId ra = RA(i);
1784 if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ 1785 if (ttisinteger(s2v(ra + 1))) { /* integer loop? */
1785 lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); 1786 lua_Unsigned count = l_castS2U(ivalue(s2v(ra)));
1786 if (count > 0) { /* still more iterations? */ 1787 if (count > 0) { /* still more iterations? */
1787 lua_Integer step = ivalue(s2v(ra + 2)); 1788 lua_Integer step = ivalue(s2v(ra + 1));
1788 lua_Integer idx = ivalue(s2v(ra)); /* internal index */ 1789 lua_Integer idx = ivalue(s2v(ra + 2)); /* control variable */
1789 chgivalue(s2v(ra + 1), count - 1); /* update counter */ 1790 chgivalue(s2v(ra), count - 1); /* update counter */
1790 idx = intop(+, idx, step); /* add step to index */ 1791 idx = intop(+, idx, step); /* add step to index */
1791 chgivalue(s2v(ra), idx); /* update internal index */ 1792 chgivalue(s2v(ra + 2), idx); /* update control variable */
1792 setivalue(s2v(ra + 3), idx); /* and control variable */
1793 pc -= GETARG_Bx(i); /* jump back */ 1793 pc -= GETARG_Bx(i); /* jump back */
1794 } 1794 }
1795 } 1795 }
@@ -1806,26 +1806,38 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1806 vmbreak; 1806 vmbreak;
1807 } 1807 }
1808 vmcase(OP_TFORPREP) { 1808 vmcase(OP_TFORPREP) {
1809 /* before: 'ra' has the iterator function, 'ra + 1' has the state,
1810 'ra + 2' has the initial value for the control variable, and
1811 'ra + 3' has the closing variable. This opcode then swaps the
1812 control and the closing variables and marks the closing variable
1813 as to-be-closed.
1814 */
1809 StkId ra = RA(i); 1815 StkId ra = RA(i);
1810 /* create to-be-closed upvalue (if needed) */ 1816 TValue temp; /* to swap control and closing variables */
1811 halfProtect(luaF_newtbcupval(L, ra + 3)); 1817 setobj(L, &temp, s2v(ra + 3));
1812 pc += GETARG_Bx(i); 1818 setobjs2s(L, ra + 3, ra + 2);
1813 i = *(pc++); /* go to next instruction */ 1819 setobj2s(L, ra + 2, &temp);
1820 /* create to-be-closed upvalue (if closing var. is not nil) */
1821 halfProtect(luaF_newtbcupval(L, ra + 2));
1822 pc += GETARG_Bx(i); /* go to end of the loop */
1823 i = *(pc++); /* fetch next instruction */
1814 lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); 1824 lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i));
1815 goto l_tforcall; 1825 goto l_tforcall;
1816 } 1826 }
1817 vmcase(OP_TFORCALL) { 1827 vmcase(OP_TFORCALL) {
1818 l_tforcall: { 1828 l_tforcall: {
1819 StkId ra = RA(i);
1820 /* 'ra' has the iterator function, 'ra + 1' has the state, 1829 /* 'ra' has the iterator function, 'ra + 1' has the state,
1821 'ra + 2' has the control variable, and 'ra + 3' has the 1830 'ra + 2' has the closing variable, and 'ra + 3' has the control
1822 to-be-closed variable. The call will use the stack after 1831 variable. The call will use the stack starting at 'ra + 3',
1823 these values (starting at 'ra + 4') 1832 so that it preserves the first three values, and the first
1833 return will be the new value for the control variable.
1824 */ 1834 */
1825 /* push function, state, and control variable */ 1835 StkId ra = RA(i);
1826 memcpy(ra + 4, ra, 3 * sizeof(*ra)); 1836 setobjs2s(L, ra + 5, ra + 3); /* copy the control variable */
1827 L->top.p = ra + 4 + 3; 1837 setobjs2s(L, ra + 4, ra + 1); /* copy state */
1828 ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ 1838 setobjs2s(L, ra + 3, ra); /* copy function */
1839 L->top.p = ra + 3 + 3;
1840 ProtectNT(luaD_call(L, ra + 3, GETARG_C(i))); /* do the call */
1829 updatestack(ci); /* stack may have changed */ 1841 updatestack(ci); /* stack may have changed */
1830 i = *(pc++); /* go to next instruction */ 1842 i = *(pc++); /* go to next instruction */
1831 lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); 1843 lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
@@ -1834,10 +1846,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1834 vmcase(OP_TFORLOOP) { 1846 vmcase(OP_TFORLOOP) {
1835 l_tforloop: { 1847 l_tforloop: {
1836 StkId ra = RA(i); 1848 StkId ra = RA(i);
1837 if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ 1849 if (!ttisnil(s2v(ra + 3))) /* continue loop? */
1838 setobjs2s(L, ra + 2, ra + 4); /* save control variable */
1839 pc -= GETARG_Bx(i); /* jump back */ 1850 pc -= GETARG_Bx(i); /* jump back */
1840 }
1841 vmbreak; 1851 vmbreak;
1842 }} 1852 }}
1843 vmcase(OP_SETLIST) { 1853 vmcase(OP_SETLIST) {
diff --git a/manual/manual.of b/manual/manual.of
index 6d19e251..73d25951 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -1467,7 +1467,7 @@ It has the following syntax:
1467 exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}} 1467 exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}}
1468} 1468}
1469The given identifier (@bnfNter{Name}) defines the control variable, 1469The given identifier (@bnfNter{Name}) defines the control variable,
1470which is a new variable local to the loop body (@emph{block}). 1470which is a new read-only variable local to the loop body (@emph{block}).
1471 1471
1472The loop starts by evaluating once the three control expressions. 1472The loop starts by evaluating once the three control expressions.
1473Their values are called respectively 1473Their values are called respectively
@@ -1499,11 +1499,6 @@ For integer loops,
1499the control variable never wraps around; 1499the control variable never wraps around;
1500instead, the loop ends in case of an overflow. 1500instead, the loop ends in case of an overflow.
1501 1501
1502You should not change the value of the control variable
1503during the loop.
1504If you need its value after the loop,
1505assign it to another variable before exiting the loop.
1506
1507} 1502}
1508 1503
1509@sect4{@title{The generic @Rw{for} loop} 1504@sect4{@title{The generic @Rw{for} loop}
@@ -1526,7 +1521,8 @@ for @rep{var_1}, @Cdots, @rep{var_n} in @rep{explist} do @rep{body} end
1526works as follows. 1521works as follows.
1527 1522
1528The names @rep{var_i} declare loop variables local to the loop body. 1523The names @rep{var_i} declare loop variables local to the loop body.
1529The first of these variables is the @emph{control variable}. 1524The first of these variables is the @emph{control variable},
1525which is a read-only variable.
1530 1526
1531The loop starts by evaluating @rep{explist} 1527The loop starts by evaluating @rep{explist}
1532to produce four values: 1528to produce four values:
@@ -1550,9 +1546,6 @@ to-be-closed variable @see{to-be-closed},
1550which can be used to release resources when the loop ends. 1546which can be used to release resources when the loop ends.
1551Otherwise, it does not interfere with the loop. 1547Otherwise, it does not interfere with the loop.
1552 1548
1553You should not change the value of the control variable
1554during the loop.
1555
1556} 1549}
1557 1550
1558} 1551}
@@ -1586,7 +1579,8 @@ Each variable name may be postfixed by an attribute
1586@producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}} 1579@producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}}
1587} 1580}
1588There are two possible attributes: 1581There are two possible attributes:
1589@id{const}, which declares a @x{constant variable}, 1582@id{const}, which declares a @emph{constant} or @emph{read-only} variable,
1583@index{constant variable}
1590that is, a variable that cannot be assigned to 1584that is, a variable that cannot be assigned to
1591after its initialization; 1585after its initialization;
1592and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. 1586and @id{close}, which declares a to-be-closed variable @see{to-be-closed}.
@@ -9118,7 +9112,7 @@ is a more portable solution.
9118@simplesect{ 9112@simplesect{
9119 9113
9120Here we list the incompatibilities that you may find when moving a program 9114Here we list the incompatibilities that you may find when moving a program
9121from @N{Lua 5.3} to @N{Lua 5.4}. 9115from @N{Lua 5.4} to @N{Lua 5.5}.
9122 9116
9123You can avoid some incompatibilities by compiling Lua with 9117You can avoid some incompatibilities by compiling Lua with
9124appropriate options (see file @id{luaconf.h}). 9118appropriate options (see file @id{luaconf.h}).
@@ -9155,51 +9149,9 @@ change between versions.
9155@itemize{ 9149@itemize{
9156 9150
9157@item{ 9151@item{
9158The coercion of strings to numbers in 9152The control variable in @Rw{for} loops are read only.
9159arithmetic and bitwise operations 9153If you need to change it,
9160has been removed from the core language. 9154declare a local variable with the same name in the loop body.
9161The string library does a similar job
9162for arithmetic (but not for bitwise) operations
9163using the string metamethods.
9164However, unlike in previous versions,
9165the new implementation preserves the implicit type of the numeral
9166in the string.
9167For instance, the result of @T{"1" + "2"} now is an integer,
9168not a float.
9169}
9170
9171@item{
9172Literal decimal integer constants that overflow are read as floats,
9173instead of wrapping around.
9174You can use hexadecimal notation for such constants if you
9175want the old behavior
9176(reading them as integers with wrap around).
9177}
9178
9179@item{
9180The use of the @idx{__lt} metamethod to emulate @idx{__le}
9181has been removed.
9182When needed, this metamethod must be explicitly defined.
9183}
9184
9185@item{
9186The semantics of the numerical @Rw{for} loop
9187over integers changed in some details.
9188In particular, the control variable never wraps around.
9189}
9190
9191@item{
9192A label for a @Rw{goto} cannot be declared where a label with the same
9193name is visible, even if this other label is declared in an enclosing
9194block.
9195}
9196
9197@item{
9198When finalizing an object,
9199Lua does not ignore @idx{__gc} metamethods that are not functions.
9200Any value will be called, if present.
9201(Non-callable values will generate a warning,
9202like any other error when calling a finalizer.)
9203} 9155}
9204 9156
9205} 9157}
@@ -9210,39 +9162,6 @@ like any other error when calling a finalizer.)
9210@itemize{ 9162@itemize{
9211 9163
9212@item{ 9164@item{
9213The function @Lid{print} does not call @Lid{tostring}
9214to format its arguments;
9215instead, it has this functionality hardwired.
9216You should use @idx{__tostring} to modify how values are printed.
9217}
9218
9219@item{
9220The pseudo-random number generator used by the function @Lid{math.random}
9221now starts with a somewhat random seed.
9222Moreover, it uses a different algorithm.
9223}
9224
9225@item{
9226By default, the decoding functions in the @Lid{utf8} library
9227do not accept surrogates as valid code points.
9228An extra parameter in these functions makes them more permissive.
9229}
9230
9231@item{
9232The options @St{setpause} and @St{setstepmul}
9233of the function @Lid{collectgarbage} are deprecated.
9234You should use the new option @St{incremental} to set them.
9235}
9236
9237@item{
9238The function @Lid{io.lines} now returns four values,
9239instead of just one.
9240That can be a problem when it is used as the sole
9241argument to another function that has optional parameters,
9242such as in @T{load(io.lines(filename, "L"))}.
9243To fix that issue,
9244you can wrap the call into parentheses,
9245to adjust its number of results to one.
9246} 9165}
9247 9166
9248} 9167}
@@ -9254,46 +9173,6 @@ to adjust its number of results to one.
9254@itemize{ 9173@itemize{
9255 9174
9256@item{ 9175@item{
9257Full userdata now has an arbitrary number of associated user values.
9258Therefore, the functions @id{lua_newuserdata},
9259@id{lua_setuservalue}, and @id{lua_getuservalue} were
9260replaced by @Lid{lua_newuserdatauv},
9261@Lid{lua_setiuservalue}, and @Lid{lua_getiuservalue},
9262which have an extra argument.
9263
9264For compatibility, the old names still work as macros assuming
9265one single user value.
9266Note, however, that userdata with zero user values
9267are more efficient memory-wise.
9268}
9269
9270@item{
9271The function @Lid{lua_resume} has an extra parameter.
9272This out parameter returns the number of values on
9273the top of the stack that were yielded or returned by the coroutine.
9274(In previous versions,
9275those values were the entire stack.)
9276}
9277
9278@item{
9279The function @Lid{lua_version} returns the version number,
9280instead of an address of the version number.
9281The Lua core should work correctly with libraries using their
9282own static copies of the same core,
9283so there is no need to check whether they are using the same
9284address space.
9285}
9286
9287@item{
9288The constant @id{LUA_ERRGCMM} was removed.
9289Errors in finalizers are never propagated;
9290instead, they generate a warning.
9291}
9292
9293@item{
9294The options @idx{LUA_GCSETPAUSE} and @idx{LUA_GCSETSTEPMUL}
9295of the function @Lid{lua_gc} are deprecated.
9296You should use the new option @id{LUA_GCINC} to set them.
9297} 9176}
9298 9177
9299} 9178}
diff --git a/testes/all.lua b/testes/all.lua
index 5df0ff9b..3c1ff5c7 100644
--- a/testes/all.lua
+++ b/testes/all.lua
@@ -3,7 +3,7 @@
3-- See Copyright Notice at the end of this file 3-- See Copyright Notice at the end of this file
4 4
5 5
6local version = "Lua 5.4" 6local version = "Lua 5.5"
7if _VERSION ~= version then 7if _VERSION ~= version then
8 io.stderr:write("This test suite is for ", version, 8 io.stderr:write("This test suite is for ", version,
9 ", not for ", _VERSION, "\nExiting tests") 9 ", not for ", _VERSION, "\nExiting tests")
diff --git a/testes/api.lua b/testes/api.lua
index 752ff18f..dece98f5 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -1046,10 +1046,12 @@ assert(a == nil and c == 2) -- 2 == run-time error
1046a, b, c = T.doremote(L1, "return a+") 1046a, b, c = T.doremote(L1, "return a+")
1047assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error 1047assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error
1048 1048
1049T.loadlib(L1) 1049T.loadlib(L1, 2) -- load only 'package'
1050a, b, c = T.doremote(L1, [[ 1050a, b, c = T.doremote(L1, [[
1051 string = require'string' 1051 string = require'string'
1052 a = require'_G'; assert(a == _G and require("_G") == a) 1052 local initialG = _G -- not loaded yet
1053 local a = require'_G'; assert(a == _G and require("_G") == a)
1054 assert(initialG == nil and io == nil) -- now we have 'assert'
1053 io = require'io'; assert(type(io.read) == "function") 1055 io = require'io'; assert(type(io.read) == "function")
1054 assert(require("io") == io) 1056 assert(require("io") == io)
1055 a = require'table'; assert(type(a.insert) == "function") 1057 a = require'table'; assert(type(a.insert) == "function")
@@ -1063,7 +1065,7 @@ T.closestate(L1);
1063 1065
1064 1066
1065L1 = T.newstate() 1067L1 = T.newstate()
1066T.loadlib(L1) 1068T.loadlib(L1, 0)
1067T.doremote(L1, "a = {}") 1069T.doremote(L1, "a = {}")
1068T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1; 1070T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1;
1069 settable -3]]) 1071 settable -3]])
@@ -1446,10 +1448,10 @@ end
1446 1448
1447do -- garbage collection with no extra memory 1449do -- garbage collection with no extra memory
1448 local L = T.newstate() 1450 local L = T.newstate()
1449 T.loadlib(L) 1451 T.loadlib(L, 1 | 2) -- load _G and 'package'
1450 local res = (T.doremote(L, [[ 1452 local res = (T.doremote(L, [[
1451 _ENV = require"_G" 1453 _ENV = _G
1452 local T = require"T" 1454 assert(string == nil)
1453 local a = {} 1455 local a = {}
1454 for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table 1456 for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table
1455 local stsize, stuse = T.querystr() 1457 local stsize, stuse = T.querystr()
diff --git a/testes/attrib.lua b/testes/attrib.lua
index 458488a8..9054e0b6 100644
--- a/testes/attrib.lua
+++ b/testes/attrib.lua
@@ -236,7 +236,7 @@ package.path = oldpath
236local fname = "file_does_not_exist2" 236local fname = "file_does_not_exist2"
237local m, err = pcall(require, fname) 237local m, err = pcall(require, fname)
238for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do 238for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
239 t = string.gsub(t, "?", fname) 239 local t = string.gsub(t, "?", fname)
240 assert(string.find(err, t, 1, true)) 240 assert(string.find(err, t, 1, true))
241end 241end
242 242
diff --git a/testes/calls.lua b/testes/calls.lua
index a1938584..9a5eed0b 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -454,7 +454,7 @@ print("testing binary chunks")
454do 454do
455 local header = string.pack("c4BBc6BBB", 455 local header = string.pack("c4BBc6BBB",
456 "\27Lua", -- signature 456 "\27Lua", -- signature
457 0x54, -- version 5.4 (0x54) 457 0x55, -- version 5.5 (0x55)
458 0, -- format 458 0, -- format
459 "\x19\x93\r\n\x1a\n", -- data 459 "\x19\x93\r\n\x1a\n", -- data
460 4, -- size of instruction 460 4, -- size of instruction
@@ -493,5 +493,30 @@ do
493 end 493 end
494end 494end
495 495
496
497do -- check reuse of strings in dumps
498 local str = "|" .. string.rep("X", 50) .. "|"
499 local foo = load(string.format([[
500 local str <const> = "%s"
501 return {
502 function () return str end,
503 function () return str end,
504 function () return str end
505 }
506 ]], str))
507 -- count occurrences of 'str' inside the dump
508 local dump = string.dump(foo)
509 local _, count = string.gsub(dump, str, {})
510 -- there should be only two occurrences:
511 -- one inside the source, other the string itself.
512 assert(count == 2)
513
514 if T then -- check reuse of strings in undump
515 local funcs = load(dump)()
516 assert(string.format("%p", T.listk(funcs[1])[1]) ==
517 string.format("%p", T.listk(funcs[3])[1]))
518 end
519end
520
496print('OK') 521print('OK')
497return deep 522return deep
diff --git a/testes/closure.lua b/testes/closure.lua
index ea038e82..de1b54ec 100644
--- a/testes/closure.lua
+++ b/testes/closure.lua
@@ -60,32 +60,29 @@ end
60-- testing closures with 'for' control variable 60-- testing closures with 'for' control variable
61a = {} 61a = {}
62for i=1,10 do 62for i=1,10 do
63 a[i] = {set = function(x) i=x end, get = function () return i end} 63 a[i] = function () return i end
64 if i == 3 then break end 64 if i == 3 then break end
65end 65end
66assert(a[4] == undef) 66assert(a[4] == undef)
67a[1].set(10) 67assert(a[2]() == 2)
68assert(a[2].get() == 2) 68assert(a[3]() == 3)
69a[2].set('a')
70assert(a[3].get() == 3)
71assert(a[2].get() == 'a')
72 69
73a = {} 70a = {}
74local t = {"a", "b"} 71local t = {"a", "b"}
75for i = 1, #t do 72for i = 1, #t do
76 local k = t[i] 73 local k = t[i]
77 a[i] = {set = function(x, y) i=x; k=y end, 74 a[i] = {set = function(x) k=x end,
78 get = function () return i, k end} 75 get = function () return i, k end}
79 if i == 2 then break end 76 if i == 2 then break end
80end 77end
81a[1].set(10, 20) 78a[1].set(10)
82local r,s = a[2].get() 79local r,s = a[2].get()
83assert(r == 2 and s == 'b') 80assert(r == 2 and s == 'b')
84r,s = a[1].get() 81r,s = a[1].get()
85assert(r == 10 and s == 20) 82assert(r == 1 and s == 10)
86a[2].set('a', 'b') 83a[2].set('a')
87r,s = a[2].get() 84r,s = a[2].get()
88assert(r == "a" and s == "b") 85assert(r == 2 and s == "a")
89 86
90 87
91-- testing closures with 'for' control variable x break 88-- testing closures with 'for' control variable x break
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index de7e46fb..990da8c4 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -703,7 +703,7 @@ else
703 703
704 T.testC(state, "settop 0") 704 T.testC(state, "settop 0")
705 705
706 T.loadlib(state) 706 T.loadlib(state, 1 | 2) -- load _G and 'package'
707 707
708 assert(T.doremote(state, [[ 708 assert(T.doremote(state, [[
709 coroutine = require'coroutine'; 709 coroutine = require'coroutine';
diff --git a/testes/files.lua b/testes/files.lua
index be00bf3f..149e9c76 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -427,12 +427,12 @@ do -- testing closing file in line iteration
427 -- get the to-be-closed variable from a loop 427 -- get the to-be-closed variable from a loop
428 local function gettoclose (lv) 428 local function gettoclose (lv)
429 lv = lv + 1 429 lv = lv + 1
430 local stvar = 0 -- to-be-closed is 4th state variable in the loop 430 local stvar = 0 -- to-be-closed is 3th state variable in the loop
431 for i = 1, 1000 do 431 for i = 1, 1000 do
432 local n, v = debug.getlocal(lv, i) 432 local n, v = debug.getlocal(lv, i)
433 if n == "(for state)" then 433 if n == "(for state)" then
434 stvar = stvar + 1 434 stvar = stvar + 1
435 if stvar == 4 then return v end 435 if stvar == 3 then return v end
436 end 436 end
437 end 437 end
438 end 438 end
diff --git a/testes/main.lua b/testes/main.lua
index f59badcf..40cbe548 100644
--- a/testes/main.lua
+++ b/testes/main.lua
@@ -134,7 +134,7 @@ RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out)
134checkout("x\n") 134checkout("x\n")
135 135
136-- test LUA_PATH_version 136-- test LUA_PATH_version
137RUN('env LUA_INIT= LUA_PATH_5_4=y LUA_PATH=x lua %s > %s', prog, out) 137RUN('env LUA_INIT= LUA_PATH_5_5=y LUA_PATH=x lua %s > %s', prog, out)
138checkout("y\n") 138checkout("y\n")
139 139
140-- test LUA_CPATH 140-- test LUA_CPATH
@@ -143,7 +143,7 @@ RUN('env LUA_INIT= LUA_CPATH=xuxu lua %s > %s', prog, out)
143checkout("xuxu\n") 143checkout("xuxu\n")
144 144
145-- test LUA_CPATH_version 145-- test LUA_CPATH_version
146RUN('env LUA_INIT= LUA_CPATH_5_4=yacc LUA_CPATH=x lua %s > %s', prog, out) 146RUN('env LUA_INIT= LUA_CPATH_5_5=yacc LUA_CPATH=x lua %s > %s', prog, out)
147checkout("yacc\n") 147checkout("yacc\n")
148 148
149-- test LUA_INIT (and its access to 'arg' table) 149-- test LUA_INIT (and its access to 'arg' table)
@@ -153,7 +153,7 @@ checkout("3.2\n")
153 153
154-- test LUA_INIT_version 154-- test LUA_INIT_version
155prepfile("print(X)") 155prepfile("print(X)")
156RUN('env LUA_INIT_5_4="X=10" LUA_INIT="X=3" lua %s > %s', prog, out) 156RUN('env LUA_INIT_5_5="X=10" LUA_INIT="X=3" lua %s > %s', prog, out)
157checkout("10\n") 157checkout("10\n")
158 158
159-- test LUA_INIT for files 159-- test LUA_INIT for files
diff --git a/testes/nextvar.lua b/testes/nextvar.lua
index 02b7dea2..5d8796f7 100644
--- a/testes/nextvar.lua
+++ b/testes/nextvar.lua
@@ -210,9 +210,9 @@ assert(T.querytab(a) == 64) -- array part has 64 elements
210a[32] = true; a[48] = true; -- binary search will find these ones 210a[32] = true; a[48] = true; -- binary search will find these ones
211a[51] = true -- binary search will miss this one 211a[51] = true -- binary search will miss this one
212assert(#a == 48) -- this will set the limit 212assert(#a == 48) -- this will set the limit
213assert(select(4, T.querytab(a)) == 48) -- this is the limit now 213assert(select(3, T.querytab(a)) == 48) -- this is the limit now
214a[50] = true -- this will set a new limit 214a[50] = true -- this will set a new limit
215assert(select(4, T.querytab(a)) == 50) -- this is the limit now 215assert(select(3, T.querytab(a)) == 50) -- this is the limit now
216-- but the size is larger (and still inside the array part) 216-- but the size is larger (and still inside the array part)
217assert(#a == 51) 217assert(#a == 51)
218 218
@@ -609,10 +609,12 @@ do
609 a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1) 609 a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1)
610end 610end
611 611
612do -- changing the control variable 612do -- attempt to change the control variable
613 local a 613 local st, msg = load "for i = 1, 10 do i = 10 end"
614 a = 0; for i = 1, 10 do a = a + 1; i = "x" end; assert(a == 10) 614 assert(not st and string.find(msg, "assign to const variable 'i'"))
615 a = 0; for i = 10.0, 1, -1 do a = a + 1; i = "x" end; assert(a == 10) 615
616 local st, msg = load "for v, k in pairs{} do v = 10 end"
617 assert(not st and string.find(msg, "assign to const variable 'v'"))
616end 618end
617 619
618-- conversion 620-- conversion