diffs-lua-5.4.0-lua-5.4.1
Makefile
49c49
< R= $V.0
> R= $V.1
README
2c2
< This is Lua 5.4.0, released on 18 Jun 2020.
> This is Lua 5.4.1, released on 30 Sep 2020.
doc/contents.html
97a98
> <LI><A HREF="manual.html#4.1.3">4.1.3 – Pointers to strings</A>
667c668
< Sat May 30 08:22:18 -03 2020
> Wed Sep 30 06:45:10 -03 2020
670c671
< Last change: revised for Lua 5.4.0 (final)
> Last change: revised for Lua 5.4.1
doc/manual.html
2976c2976,2977
< at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots.
> at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra elements;
> that is, you can safely push up to <code>LUA_MINSTACK</code> values into it.
2987c2988
< So, before pushing anything in the stack after such a call
> So, before pushing anything on the stack after such a call
3046a3048,3089
> <h3>4.1.3 – <a name="4.1.3">Pointers to strings</a></h3>
>
> <p>
> Several functions in the API return pointers (<code>const char*</code>)
> to Lua strings in the stack.
> (See <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
> <a href="#lua_pushstring"><code>lua_pushstring</code></a>, and <a href="#lua_tolstring"><code>lua_tolstring</code></a>.
> See also <a href="#luaL_checklstring"><code>luaL_checklstring</code></a>, <a href="#luaL_checkstring"><code>luaL_checkstring</code></a>,
> and <a href="#luaL_tolstring"><code>luaL_tolstring</code></a> in the auxiliary library.)
>
>
> <p>
> In general,
> Lua's garbage collection can free or move internal memory
> and then invalidate pointers to internal strings.
> To allow a safe use of these pointers,
> The API guarantees that any pointer to a string in a stack index
> is valid while the value at that index is neither modified nor popped.
> When the index is a pseudo-index (referring to an upvalue),
> the pointer is valid while the corresponding call is active and
> the corresponding upvalue is not modified.
>
>
> <p>
> Some functions in the debug interface
> also return pointers to strings,
> namely <a href="#lua_getlocal"><code>lua_getlocal</code></a>, <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>,
> <a href="#lua_setlocal"><code>lua_setlocal</code></a>, and <a href="#lua_setupvalue"><code>lua_setupvalue</code></a>.
> For these functions, the pointer is guaranteed to
> be valid while the caller function is active and
> the given closure (if one was given) is in the stack.
>
>
> <p>
> Except for these guarantees,
> the garbage collector is free to invalidate
> any pointer to internal strings.
>
>
>
>
>
3392c3435
< (For instance, they may depend on what is on the stack.)
> (For instance, they may depend on what is in the stack.)
3681c3724
< Ensures that the stack has space for at least <code>n</code> extra slots,
> Ensures that the stack has space for at least <code>n</code> extra elements,
3689c3732
< if the stack already has space for the extra slots,
> if the stack already has space for the extra elements,
4445a4489,4492
> Lua ensures that this address is valid as long as
> the corresponding userdata is alive (see <a href="#2.5">§2.5</a>).
> Moreover, if the userdata is marked for finalization (see <a href="#2.5.3">§2.5.3</a>),
> its address is valid at least until the call to its finalizer.
4691c4738
< and returns a pointer to this string.
> and returns a pointer to this string (see <a href="#4.1.3">§4.1.3</a>).
4791c4838
< Returns a pointer to the internal copy of the string.
> Returns a pointer to the internal copy of the string (see <a href="#4.1.3">§4.1.3</a>).
4832c4879
< Returns a pointer to the internal copy of the string.
> Returns a pointer to the internal copy of the string (see <a href="#4.1.3">§4.1.3</a>).
5402c5449
< <span class="apii">[-0, +0, <em>v</em>]</span>
> <span class="apii">[-0, +0, <em>m</em>]</span>
5426,5427c5473,5474
< This function can raise an out-of-memory error.
< In that case, the value in the given index is immediately closed,
> In the case of an out-of-memory error,
> the value in the given index is immediately closed,
5430a5478,5485
> <p>
> Note that, both in case of errors and of a regular return,
> by the time the <code>__close</code> metamethod runs,
> the C stack was already unwound,
> so that any automatic C variable declared in the calling function
> will be out of scope.
>
>
5485c5540
< to a string inside the Lua state.
> to a string inside the Lua state (see <a href="#4.1.3">§4.1.3</a>).
5491,5496d5545
< <p>
< Because Lua has garbage collection,
< there is no guarantee that the pointer returned by <code>lua_tolstring</code>
< will be valid after the corresponding Lua value is removed from the stack.
<
<
5947c5996
< the index on the stack of the first value being "transferred",
> the index in the stack of the first value being "transferred",
6144c6193
< (except for tail calls, which do not count on the stack).
> (except for tail calls, which do not count in the stack).
6262,6263c6311
< The hook is called just after Lua enters the new function,
< before the function gets its arguments.
> The hook is called just after Lua enters the new function.
7576c7624
< returned by the function.
> returned by the function (see <a href="#4.1.3">§4.1.3</a>).
8004,8006c8052,8056
< Lua does not check the consistency of binary chunks.
< Maliciously crafted binary chunks can crash
< the interpreter.
> It is safe to load malformed binary chunks;
> <code>load</code> signals an appropriate error.
> However,
> Lua does not check the consistency of the code inside binary chunks;
> running maliciously crafted bytecode can crash the interpreter.
8667a8718,8729
> <p>
> This function is inherently insecure,
> as it allows Lua to call any function in any readable dynamic
> library in the system.
> (Lua calls any function assuming the function
> has a proper prototype and respects a proper protocol
> (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
> Therefore,
> calling an arbitrary function in an arbitrary dynamic library
> more often than not results in an access violation.)
>
>
11087c11149
< (except for tail calls, which do not count on the stack);
> (except for tail calls, which do not count in the stack);
11889c11951
< Thu Jun 18 16:10:16 UTC 2020
> Wed Sep 30 09:46:30 UTC 2020
11892c11954
< Last change: revised for Lua 5.4.0 (final)
> Last change: revised for Lua 5.4.1
doc/readme.html
113c113
< the top-level directory, which is named <TT>lua-5.4.0</TT>.
> the top-level directory, which is named <TT>lua-5.4.1</TT>.
333c333
< Fri May 1 19:33:31 UTC 2020
> Wed Sep 30 09:55:45 UTC 2020
336c336
< Last change: revised for Lua 5.4.0 (final)
> Last change: revised for Lua 5.4.1
src/lapi.c
100c100
< CallInfo *ci = L->ci;
> CallInfo *ci;
101a102
> ci = L->ci;
173,174c174,175
< CallInfo *ci = L->ci;
< StkId func = ci->func;
> CallInfo *ci;
> StkId func;
176a178,179
> ci = L->ci;
> func = ci->func;
379c382,384
< TValue *o = index2value(L, idx);
> TValue *o;
> lua_lock(L);
> o = index2value(L, idx);
382a388
> lua_unlock(L);
385d390
< lua_lock(L); /* 'luaO_tostring' may create a new string */
389d393
< lua_unlock(L);
392a397
> lua_unlock(L);
565a571
> lua_assert(iswhite(cl));
627c633
< Table *reg = hvalue(&G(L)->l_registry);
> Table *reg;
628a635
> reg = hvalue(&G(L)->l_registry);
807c814
< Table *reg = hvalue(&G(L)->l_registry);
> Table *reg;
808a816
> reg = hvalue(&G(L)->l_registry);
1096c1104
< global_State *g = G(L);
> global_State *g;
1097a1106
> g = G(L);
1196a1206
> TValue *errobj;
1197a1208
> errobj = s2v(L->top - 1);
1199c1210,1214
< luaG_errormsg(L);
> /* error object is the memory error message? */
> if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
> luaM_error(L); /* raise a memory error */
> else
> luaG_errormsg(L); /* raise a regular error */
1241c1256
< if (n >= 2) {
> if (n > 0)
1243,1245c1258,1259
< }
< else if (n == 0) { /* push empty string */
< setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
> else { /* nothing to concatenate */
> setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */
1248d1261
< /* else n == 1; nothing to do */
src/lauxlib.c
478,479c478,481
< if (temp == NULL && newsize > 0) /* allocation error? */
< luaL_error(L, "not enough memory");
> if (temp == NULL && newsize > 0) { /* allocation error? */
> lua_pushliteral(L, "not enough memory");
> lua_error(L); /* raise a memory error */
> }
src/lcorolib.c
76c76
< if (r < 0) {
> if (r < 0) { /* error? */
78,80c78,81
< if (stat != LUA_OK && stat != LUA_YIELD)
< lua_resetthread(co); /* close variables in case of errors */
< if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
> if (stat != LUA_OK && stat != LUA_YIELD) /* error in the coroutine? */
> lua_resetthread(co); /* close its tbc variables */
> if (stat != LUA_ERRMEM && /* not a memory error and ... */
> lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */
src/lctype.h
16c16
< ** optimized for the specific needs of Lua
> ** optimized for the specific needs of Lua.
63a64
>
65c66,69
< ** this 'ltolower' only works for alphabetic characters
> ** In ASCII, this 'ltolower' is correct for alphabetic characters and
> ** for '.'. That is enough for Lua needs. ('check_exp' ensures that
> ** the character either is an upper-case letter or is unchanged by
> ** the transformation, which holds for lower-case letters and '.'.)
67c71,73
< #define ltolower(c) ((c) | ('A' ^ 'a'))
> #define ltolower(c) \
> check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
> (c) | ('A' ^ 'a'))
70c76
< /* two more entries for 0 and -1 (EOZ) */
> /* one entry for each character and for -1 (EOZ) */
src/ldebug.c
36,39c36,37
<
< /* Active Lua function (given call info) */
< #define ci_func(ci) (clLvalue(s2v((ci)->func)))
<
> /* inverse of 'pcRel' */
> #define invpcRel(pc, p) ((p)->code + (pc) + 1)
130,135c128,133
< ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
< ** 'resethookcount') are for debug only, and it is no problem if they
< ** get arbitrary values (causes at most one wrong hook call). 'hookmask'
< ** is an atomic value. We assume that pointers are atomic too (e.g., gcc
< ** ensures that for all platforms where it runs). Moreover, 'hook' is
< ** always checked before being called (see 'luaD_hook').
> ** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount')
> ** are for debug only, and it is no problem if they get arbitrary
> ** values (causes at most one wrong hook call). 'hookmask' is an atomic
> ** value. We assume that pointers are atomic too (e.g., gcc ensures that
> ** for all platforms where it runs). Moreover, 'hook' is always checked
> ** before being called (see 'luaD_hook').
142,143d139
< if (isLua(L->ci))
< L->oldpc = L->ci->u.l.savedpc;
195,196c191,192
< if (n <= nextra) {
< *pos = ci->func - nextra + (n - 1);
> if (n >= -nextra) { /* 'n' is negative */
> *pos = ci->func - nextra - (n + 1);
209c205
< return findvararg(ci, -n, pos);
> return findvararg(ci, n, pos);
789a786,787
> if (p->lineinfo == NULL) /* no debug information? */
> return 0;
794c792
< return 0; /* no line changes in the way */
> return 0; /* no line changes between positions */
797a796,806
> /*
> ** Traces the execution of a Lua function. Called before the execution
> ** of each opcode, when debug is on. 'L->oldpc' stores the last
> ** instruction traced, to detect line changes. When entering a new
> ** function, 'npci' will be zero and will test as a new line without
> ** the need for 'oldpc'; so, 'oldpc' does not need to be initialized
> ** before. Some exceptional conditions may return to a function without
> ** updating 'oldpc'. In that case, 'oldpc' may be invalid; if so, it is
> ** reset to zero. (A wrong but valid 'oldpc' at most causes an extra
> ** call to a line hook.)
> */
800a810
> const Proto *p = ci_func(ci)->p;
801a812,813
> /* 'L->oldpc' may be invalid; reset it in this case */
> int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0;
822d833
< const Proto *p = ci_func(ci)->p;
825,826c836,837
< pc <= L->oldpc || /* when jump back (loop), or when */
< changedline(p, pcRel(L->oldpc, p), npci)) { /* enter new line */
> pc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */
> changedline(p, oldpc, npci)) { /* enter new line */
830c841
< L->oldpc = pc; /* 'pc' of last call to line hook */
> L->oldpc = npci; /* 'pc' of last call to line hook */
src/ldebug.h
15a16,20
>
> /* Active Lua function (given call info) */
> #define ci_func(ci) (clLvalue(s2v((ci)->func)))
>
>
src/ldo.c
248c248
< int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
> int goodsize = inuse + BASIC_STACK_SIZE;
253,254c253
< if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
< goodsize < L->stacksize)
> if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize)
331c330
< Proto *p = clLvalue(s2v(ci->func))->p;
> Proto *p = ci_func(ci)->p;
344,345c343,344
< if (isLua(ci->previous))
< L->oldpc = ci->previous->u.l.savedpc; /* update 'oldpc' */
> if (isLua(ci = ci->previous))
> L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* update 'oldpc' */
469,470c468,470
< CallInfo *ci = next_ci(L);
< checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
> CallInfo *ci;
> checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
> L->ci = ci = next_ci(L);
475d474
< L->ci = ci;
489c488
< CallInfo *ci = next_ci(L);
> CallInfo *ci;
494c493,494
< checkstackp(L, fsize, func);
> checkstackGCp(L, fsize, func);
> L->ci = ci = next_ci(L);
508c508
< checkstackp(L, 1, func); /* space for metamethod */
> checkstackGCp(L, 1, func); /* space for metamethod */
518,520d517
< ** If there is a stack overflow, freeing all CI structures will
< ** force the subsequent call to invoke 'luaE_extendCI', which then
< ** will raise any errors.
524,525c521,524
< if (getCcalls(L) <= CSTACKERR) /* possible stack overflow? */
< luaE_freeCI(L);
> if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */
> luaE_exitCcall(L); /* to compensate decrement in next call */
> luaE_enterCcall(L); /* check properly */
> }
677c676
< L->nCcalls = getCcalls(from) + from->nci - L->nci - CSTACKCF;
> L->nCcalls = getCcalls(from) - L->nci - CSTACKCF;
709c708
< CallInfo *ci = L->ci;
> CallInfo *ci;
711a711
> ci = L->ci;
src/ldo.h
19a20,21
> ** It also allows the running of one GC step when the stack is
> ** reallocated.
38c40
< #define checkstackp(L,n,p) \
> #define checkstackGCp(L,n,p) \
47c49
< luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L))
> luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
src/lfunc.c
237,239c237,240
< if (!iswhite(uv))
< gray2black(uv); /* closed upvalues cannot be gray */
< luaC_barrier(L, uv, slot);
> if (!iswhite(uv)) { /* neither white nor dead? */
> nw2black(uv); /* closed upvalues cannot be gray */
> luaC_barrier(L, uv, slot);
> }
src/lgc.c
63,64c63,64
< /* mask to erase all color bits (plus gen. related stuff) */
< #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS | AGEBITS))
> /* mask with all color bits */
> #define maskcolors (bitmask(BLACKBIT) | WHITEBITS)
65a66,67
> /* mask with all GC bits */
> #define maskgcbits (maskcolors | AGEBITS)
67c69,70
< /* macro to erase all color bits then sets only the current white bit */
>
> /* macro to erase all color bits then set only the current white bit */
69c72,75
< (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
> (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g)))
>
> /* make an object gray (neither white nor black) */
> #define set2gray(x) resetbits(x->marked, maskcolors)
71,72c77,80
< #define white2gray(x) resetbits(x->marked, WHITEBITS)
< #define black2gray(x) resetbit(x->marked, BLACKBIT)
>
> /* make an object black (coming from any color) */
> #define set2black(x) \
> (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT)))
80,82d87
< #define checkconsistency(obj) \
< lua_longassert(!iscollectable(obj) || righttt(obj))
<
89c94
< #define markvalue(g,o) { checkconsistency(o); \
> #define markvalue(g,o) { checkliveness(g->mainthread,o); \
138c143,144
< ** Link a collectable object 'o' with a known type into list pointed by 'p'.
> ** Link a collectable object 'o' with a known type into the list 'p'.
> ** (Must be a macro to access the 'gclist' field in different types.)
140c146,153
< #define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
> #define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p))
>
> static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) {
> lua_assert(!isgray(o)); /* cannot be in a gray list */
> *pnext = *list;
> *list = o;
> set2gray(o); /* now it is */
> }
144c157
< ** Link a generic collectable object 'o' into list pointed by 'p'.
> ** Link a generic collectable object 'o' into the list 'p'.
146c159
< #define linkobjgclist(o,p) (*getgclist(o) = (p), (p) = obj2gco(o))
> #define linkobjgclist(o,p) linkgclist_(obj2gco(o), getgclist(o), &(p))
184,191c197,207
< ** barrier that moves collector forward, that is, mark the white object
< ** 'v' being pointed by the black object 'o'. (If in sweep phase, clear
< ** the black object to white [sweep it] to avoid other barrier calls for
< ** this same object.) In the generational mode, 'v' must also become
< ** old, if 'o' is old; however, it cannot be changed directly to OLD,
< ** because it may still point to non-old objects. So, it is marked as
< ** OLD0. In the next cycle it will become OLD1, and in the next it
< ** will finally become OLD (regular old).
> ** Barrier that moves collector forward, that is, marks the white object
> ** 'v' being pointed by the black object 'o'. In the generational
> ** mode, 'v' must also become old, if 'o' is old; however, it cannot
> ** be changed directly to OLD, because it may still point to non-old
> ** objects. So, it is marked as OLD0. In the next cycle it will become
> ** OLD1, and in the next it will finally become OLD (regular old). By
> ** then, any object it points to will also be old. If called in the
> ** incremental sweep phase, it clears the black object to white (sweep
> ** it) to avoid other barrier calls for this same object. (That cannot
> ** be done is generational mode, as its sweep does not distinguish
> ** whites from deads.)
205c221,222
< makewhite(g, o); /* mark main obj. as white to avoid other barriers */
> if (g->gckind == KGC_INC) /* incremental mode? */
> makewhite(g, o); /* mark 'o' as white to avoid other barriers */
217,221c234,240
< lua_assert(g->gckind != KGC_GEN || (isold(o) && getage(o) != G_TOUCHED1));
< if (getage(o) != G_TOUCHED2) /* not already in gray list? */
< linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */
< black2gray(o); /* make object gray (again) */
< setage(o, G_TOUCHED1); /* touched in current cycle */
> lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1));
> if (getage(o) == G_TOUCHED2) /* already in gray list? */
> set2gray(o); /* make it gray to become touched1 */
> else /* link it in 'grayagain' and paint it gray */
> linkobjgclist(o, g->grayagain);
> if (isold(o)) /* generational mode? */
> setage(o, G_TOUCHED1); /* touched in current cycle */
228c247
< white2gray(o); /* they will be gray forever */
> set2gray(o); /* they will be gray forever */
262,266c281,290
< ** Mark an object. Userdata, strings, and closed upvalues are visited
< ** and turned black here. Other objects are marked gray and added
< ** to appropriate list to be visited (and turned black) later. (Open
< ** upvalues are already linked in 'headuv' list. They are kept gray
< ** to avoid barriers, as their values will be revisited by the thread.)
> ** Mark an object. Userdata with no user values, strings, and closed
> ** upvalues are visited and turned black here. Open upvalues are
> ** already indirectly linked through their respective threads in the
> ** 'twups' list, so they don't go to the gray list; nevertheless, they
> ** are kept gray to avoid barriers, as their values will be revisited
> ** by the thread or by 'remarkupvals'. Other objects are added to the
> ** gray list to be visited (and turned black) later. Both userdata and
> ** upvalues can call this function recursively, but this recursion goes
> ** for at most two levels: An upvalue cannot refer to another upvalue
> ** (only closures can), and a userdata's metatable must be a table.
269d292
< white2gray(o);
273c296
< gray2black(o);
> set2black(o); /* nothing to visit */
278,279c301,304
< if (!upisopen(uv)) /* open upvalues are kept gray */
< gray2black(o);
> if (upisopen(uv))
> set2gray(uv); /* open upvalues are kept gray */
> else
> set2black(o); /* closed upvalues are visited here */
287c312
< gray2black(o); /* nothing else to mark */
> set2black(o); /* nothing else to mark */
294c319
< linkobjgclist(o, g->gray);
> linkobjgclist(o, g->gray); /* to be visited later */
327,330c352,360
< ** Mark all values stored in marked open upvalues from non-marked threads.
< ** (Values from marked threads were already marked when traversing the
< ** thread.) Remove from the list threads that no longer have upvalues and
< ** not-marked threads.
> ** For each non-marked thread, simulates a barrier between each open
> ** upvalue and its value. (If the thread is collected, the value will be
> ** assigned to the upvalue, but then it can be too late for the barrier
> ** to act. The "barrier" does not need to check colors: A non-marked
> ** thread must be young; upvalues cannot be older than their threads; so
> ** any visited upvalue must be young too.) Also removes the thread from
> ** the list, as it was already visited. Removes also threads with no
> ** upvalues, as they have nothing to be checked. (If the thread gets an
> ** upvalue later, it will be linked in the list again.)
335c365
< int work = 0;
> int work = 0; /* estimate of how much work was done here */
338,339c368
< lua_assert(!isblack(thread)); /* threads are never black */
< if (isgray(thread) && thread->openupval != NULL)
> if (!iswhite(thread) && thread->openupval != NULL)
342a372
> lua_assert(!isold(thread) || thread->openupval == NULL);
345a376
> lua_assert(getage(uv) <= getage(thread));
347c378,379
< if (!iswhite(uv)) /* upvalue already visited? */
> if (!iswhite(uv)) { /* upvalue already visited? */
> lua_assert(upisopen(uv) && isgray(uv));
348a381
> }
355a389,394
> static void cleargraylists (global_State *g) {
> g->gray = g->grayagain = NULL;
> g->weak = g->allweak = g->ephemeron = NULL;
> }
>
>
360,361c399
< g->gray = g->grayagain = NULL;
< g->weak = g->allweak = g->ephemeron = NULL;
> cleargraylists(g);
376a415,434
>
> /*
> ** Check whether object 'o' should be kept in the 'grayagain' list for
> ** post-processing by 'correctgraylist'. (It could put all old objects
> ** in the list and leave all the work to 'correctgraylist', but it is
> ** more efficient to avoid adding elements that will be removed.) Only
> ** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go
> ** back to a gray list, but then it must become OLD. (That is what
> ** 'correctgraylist' does when it finds a TOUCHED2 object.)
> */
> static void genlink (global_State *g, GCObject *o) {
> lua_assert(isblack(o));
> if (getage(o) == G_TOUCHED1) { /* touched in this cycle? */
> linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */
> } /* everything else do not need to be linked back */
> else if (getage(o) == G_TOUCHED2)
> changeage(o, G_TOUCHED2, G_OLD); /* advance age */
> }
>
>
413,414c471,473
< ** (in the atomic phase). In generational mode, it (like all visited
< ** tables) must be kept in some gray list for post-processing.
> ** (in the atomic phase). In generational mode, some tables
> ** must be kept in some gray list for post-processing; this is done
> ** by 'genlink'.
453,454d511
< else if (g->gckind == KGC_GEN)
< linkgclist(h, g->grayagain); /* keep it in some list */
456c513
< gray2black(h);
> genlink(g, obj2gco(h)); /* check whether collector still needs to see it */
476,479c533
< if (g->gckind == KGC_GEN) {
< linkgclist(h, g->grayagain); /* keep it in some gray list */
< black2gray(h);
< }
> genlink(g, obj2gco(h));
491d544
< black2gray(h); /* keep table gray */
510,513c563
< if (g->gckind == KGC_GEN) {
< linkgclist(u, g->grayagain); /* keep it in some gray list */
< black2gray(u);
< }
> genlink(g, obj2gco(u));
562,563c612,620
< ** and cleaning the rest of the stack in the final traversal.
< ** That ensures that the entire stack have valid (non-dead) objects.
> ** and cleaning the rest of the stack in the final traversal. That
> ** ensures that the entire stack have valid (non-dead) objects.
> ** Threads have no barriers. In gen. mode, old threads must be visited
> ** at every cycle, because they might point to young objects. In inc.
> ** mode, the thread can still be modified before the end of the cycle,
> ** and therefore it must be visited again in the atomic phase. To ensure
> ** these visits, threads must return to a gray list if they are not new
> ** (which can only happen in generational mode) or if the traverse is in
> ** the propagate phase (which can only happen in incremental mode).
567a625,626
> if (isold(th) || g->gcstate == GCSpropagate)
> linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
593,594c652
< ** traverse one gray object, turning it to black (except for threads,
< ** which are always gray).
> ** traverse one gray object, turning it to black.
598c656
< gray2black(o);
> nw2black(o);
606,611c664
< case LUA_VTHREAD: {
< lua_State *th = gco2th(o);
< linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
< black2gray(o);
< return traversethread(g, th);
< }
> case LUA_VTHREAD: return traversethread(g, gco2th(o));
641,642c694,697
< next = gco2t(w)->gclist; /* list is rebuilt during loop */
< if (traverseephemeron(g, gco2t(w), dir)) { /* marked some value? */
> Table *h = gco2t(w);
> next = h->gclist; /* list is rebuilt during loop */
> nw2black(h); /* out of the list (for now) */
> if (traverseephemeron(g, h, dir)) { /* marked some value? */
769c824
< curr->marked = cast_byte((marked & maskcolors) | white);
> curr->marked = cast_byte((marked & ~maskgcbits) | white);
825a881,882
> else if (getage(o) == G_OLD1)
> g->firstold1 = o; /* it is the first OLD1 object in the list */
899,900c956,957
< ** (Note that objects after 'finobjold' cannot be white, so they
< ** don't need to be traversed. In incremental mode, 'finobjold' is NULL,
> ** (Note that objects after 'finobjold1' cannot be white, so they
> ** don't need to be traversed. In incremental mode, 'finobjold1' is NULL,
907c964
< while ((curr = *p) != g->finobjold) { /* traverse all finalizable objects */
> while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */
923a981,1001
> ** If pointer 'p' points to 'o', move it to the next element.
> */
> static void checkpointer (GCObject **p, GCObject *o) {
> if (o == *p)
> *p = o->next;
> }
>
>
> /*
> ** Correct pointers to objects inside 'allgc' list when
> ** object 'o' is being removed from the list.
> */
> static void correctpointers (global_State *g, GCObject *o) {
> checkpointer(&g->survival, o);
> checkpointer(&g->old1, o);
> checkpointer(&g->reallyold, o);
> checkpointer(&g->firstold1, o);
> }
>
>
> /*
939,946c1017,1018
< else { /* correct pointers into 'allgc' list, if needed */
< if (o == g->survival)
< g->survival = o->next;
< if (o == g->old)
< g->old = o->next;
< if (o == g->reallyold)
< g->reallyold = o->next;
< }
> else
> correctpointers(g, o);
968,971d1039
< /* mask to erase all color bits, not changing gen-related stuff */
< #define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS))
<
<
973,974c1041,1044
< ** Sweep a list of objects, deleting dead ones and turning
< ** the non dead to old (without changing their colors).
> ** Sweep a list of objects to enter generational mode. Deletes dead
> ** objects and turns the non dead to old. All non-dead threads---which
> ** are now old---must be in a gray list. Everything else is not in a
> ** gray list. Open upvalues are also kept gray.
977a1048
> global_State *g = G(L);
980c1051
< lua_assert(isdead(G(L), curr));
> lua_assert(isdead(g, curr));
985a1057,1064
> if (curr->tt == LUA_VTHREAD) { /* threads must be watched */
> lua_State *th = gco2th(curr);
> linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
> }
> else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr)))
> set2gray(curr); /* open upvalues are always gray */
> else /* everything else is black */
> nw2black(curr);
997a1077,1080
> ** The ages of G_TOUCHED1 and G_TOUCHED2 objects cannot be advanced
> ** here, because these old-generation objects are usually not swept
> ** here. They will all be advanced in 'correctgraylist'. That function
> ** will also remove objects turned white here from any gray list.
1000c1083
< GCObject *limit) {
> GCObject *limit, GCObject **pfirstold1) {
1019,1021c1102,1110
< if (getage(curr) == G_NEW)
< curr->marked = cast_byte((curr->marked & maskgencolors) | white);
< setage(curr, nextage[getage(curr)]);
> if (getage(curr) == G_NEW) { /* new objects go back to white */
> int marked = curr->marked & ~maskgcbits; /* erase GC bits */
> curr->marked = cast_byte(marked | G_SURVIVAL | white);
> }
> else { /* all other objects will be old, and so keep their color */
> setage(curr, nextage[getage(curr)]);
> if (getage(curr) == G_OLD1 && *pfirstold1 == NULL)
> *pfirstold1 = curr; /* first OLD1 object in the list */
> }
1031c1120,1121
< ** age.
> ** age. In incremental mode, all objects are 'new' all the time,
> ** except for fixed strings (which are always old).
1036c1126
< p->marked = cast_byte((p->marked & maskcolors) | white);
> p->marked = cast_byte((p->marked & ~maskgcbits) | white);
1041c1131,1132
< ** Correct a list of gray objects.
> ** Correct a list of gray objects. Return pointer to where rest of the
> ** list should be linked.
1044,1046c1135,1137
< ** For tables and userdata, advance 'touched1' to 'touched2'; 'touched2'
< ** objects become regular old and are removed from the list.
< ** For threads, just remove white ones from the list.
> ** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list;
> ** Non-white threads also remain on the list; 'TOUCHED2' objects become
> ** regular old; they and anything else are removed from the list.
1051,1081c1142,1160
< switch (curr->tt) {
< case LUA_VTABLE: case LUA_VUSERDATA: {
< GCObject **next = getgclist(curr);
< if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */
< lua_assert(isgray(curr));
< gray2black(curr); /* make it black, for next barrier */
< changeage(curr, G_TOUCHED1, G_TOUCHED2);
< p = next; /* go to next element */
< }
< else { /* not touched in this cycle */
< if (!iswhite(curr)) { /* not white? */
< lua_assert(isold(curr));
< if (getage(curr) == G_TOUCHED2) /* advance from G_TOUCHED2... */
< changeage(curr, G_TOUCHED2, G_OLD); /* ... to G_OLD */
< gray2black(curr); /* make it black */
< }
< /* else, object is white: just remove it from this list */
< *p = *next; /* remove 'curr' from gray list */
< }
< break;
< }
< case LUA_VTHREAD: {
< lua_State *th = gco2th(curr);
< lua_assert(!isblack(th));
< if (iswhite(th)) /* new object? */
< *p = th->gclist; /* remove from gray list */
< else /* old threads remain gray */
< p = &th->gclist; /* go to next element */
< break;
< }
< default: lua_assert(0); /* nothing more could be gray here */
> GCObject **next = getgclist(curr);
> if (iswhite(curr))
> goto remove; /* remove all white objects */
> else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */
> lua_assert(isgray(curr));
> nw2black(curr); /* make it black, for next barrier */
> changeage(curr, G_TOUCHED1, G_TOUCHED2);
> goto remain; /* keep it in the list and go to next element */
> }
> else if (curr->tt == LUA_VTHREAD) {
> lua_assert(isgray(curr));
> goto remain; /* keep non-white threads on the list */
> }
> else { /* everything else is removed */
> lua_assert(isold(curr)); /* young objects should be white here */
> if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */
> changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */
> nw2black(curr); /* make object black (to be removed) */
> goto remove;
1082a1162,1163
> remove: *p = *next; continue;
> remain: p = next; continue;
1103c1184
< ** Mark 'OLD1' objects when starting a new young collection.
> ** Mark black 'OLD1' objects when starting a new young collection.
1112,1113c1193,1194
< if (isblack(p)) {
< black2gray(p); /* should be '2white', but gray works too */
> changeage(p, G_OLD1, G_OLD); /* now they are old */
> if (isblack(p))
1115d1195
< }
1134,1138c1214,1216
< ** Does a young collection. First, mark 'OLD1' objects. (Only survival
< ** and "recent old" lists can contain 'OLD1' objects. New lists cannot
< ** contain 'OLD1' objects, at most 'OLD0' objects that were already
< ** visited when marked old.) Then does the atomic step. Then,
< ** sweep all lists and advance pointers. Finally, finish the collection.
> ** Does a young collection. First, mark 'OLD1' objects. Then does the
> ** atomic step. Then, sweep all lists and advance pointers. Finally,
> ** finish the collection.
1141a1220
> GCObject *dummy; /* dummy out parameter to 'sweepgen' */
1143c1222,1225
< markold(g, g->survival, g->reallyold);
> if (g->firstold1) { /* are there regular OLD1 objects? */
> markold(g, g->firstold1, g->reallyold); /* mark them */
> g->firstold1 = NULL; /* no more OLD1 objects (for now) */
> }
1144a1227
> markold(g, g->tobefnz, NULL);
1148,1152c1231,1236
< psurvival = sweepgen(L, g, &g->allgc, g->survival);
< /* sweep 'survival' and 'old' */
< sweepgen(L, g, psurvival, g->reallyold);
< g->reallyold = g->old;
< g->old = *psurvival; /* 'survival' survivals are old now */
> g->gcstate = GCSswpallgc;
> psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1);
> /* sweep 'survival' */
> sweepgen(L, g, psurvival, g->old1, &g->firstold1);
> g->reallyold = g->old1;
> g->old1 = *psurvival; /* 'survival' survivals are old now */
1156,1160c1240,1245
< psurvival = sweepgen(L, g, &g->finobj, g->finobjsur);
< /* sweep 'survival' and 'old' */
< sweepgen(L, g, psurvival, g->finobjrold);
< g->finobjrold = g->finobjold;
< g->finobjold = *psurvival; /* 'survival' survivals are old now */
> dummy = NULL; /* no 'firstold1' optimization for 'finobj' lists */
> psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy);
> /* sweep 'survival' */
> sweepgen(L, g, psurvival, g->finobjold1, &dummy);
> g->finobjrold = g->finobjold1;
> g->finobjold1 = *psurvival; /* 'survival' survivals are old now */
1163,1164c1248
< sweepgen(L, g, &g->tobefnz, NULL);
<
> sweepgen(L, g, &g->tobefnz, NULL, &dummy);
1168a1253,1258
> /*
> ** Clears all gray lists, sweeps objects, and prepare sublists to enter
> ** generational mode. The sweeps remove dead objects and turn all
> ** surviving objects to old. Threads go back to 'grayagain'; everything
> ** else is turned black (not in any gray list).
> */
1169a1260
> cleargraylists(g);
1170a1262
> g->gcstate = GCSswpallgc;
1173c1265,1266
< g->reallyold = g->old = g->survival = g->allgc;
> g->reallyold = g->old1 = g->survival = g->allgc;
> g->firstold1 = NULL; /* there are no OLD1 objects anywhere */
1177c1270
< g->finobjrold = g->finobjold = g->finobjsur = g->finobj;
> g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj;
1190,1191c1283,1285
< ** to ensure that all threads and weak tables are in the gray lists.
< ** Then, turn all objects into old and finishes the collection.
> ** to ensure that all objects are correctly marked and weak tables
> ** are cleared. Then, turn all objects into old and finishes the
> ** collection.
1210c1304
< g->reallyold = g->old = g->survival = NULL;
> g->reallyold = g->old1 = g->survival = NULL;
1213c1307
< g->finobjrold = g->finobjold = g->finobjsur = NULL;
> g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
src/lgc.h
15,24c15,24
< ** Collectable objects may have one of three colors: white, which
< ** means the object is not marked; gray, which means the
< ** object is marked, but its references may be not marked; and
< ** black, which means that the object and all its references are marked.
< ** The main invariant of the garbage collector, while marking objects,
< ** is that a black object can never point to a white one. Moreover,
< ** any gray object must be in a "gray list" (gray, grayagain, weak,
< ** allweak, ephemeron) so that it can be visited again before finishing
< ** the collection cycle. These lists have no meaning when the invariant
< ** is not being enforced (e.g., sweep phase).
> ** Collectable objects may have one of three colors: white, which means
> ** the object is not marked; gray, which means the object is marked, but
> ** its references may be not marked; and black, which means that the
> ** object and all its references are marked. The main invariant of the
> ** garbage collector, while marking objects, is that a black object can
> ** never point to a white one. Moreover, any gray object must be in a
> ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it
> ** can be visited again before finishing the collection cycle. (Open
> ** upvalues are an exception to this rule.) These lists have no meaning
> ** when the invariant is not being enforced (e.g., sweep phase).
72,73c72,73
< ** used for object "age" in generational mode. Last bit is free
< ** to be used by respective objects.
> ** used for object "age" in generational mode. Last bit is used
> ** by tests.
79a80,81
> #define TESTBIT 7
>
97c99,100
< #define gray2black(x) l_setbit((x)->marked, BLACKBIT)
> #define nw2black(x) \
> check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT))
src/liolib.c
54a55,60
> #if !defined(l_checkmodep)
> /* By default, Lua accepts only "r" or "w" as mode */
> #define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
> #endif
>
>
281a288
> luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
src/llex.c
84d83
< lua_assert(token == cast_uchar(token));
src/llex.h
9a10,11
> #include <limits.h>
>
14c16,20
< #define FIRST_RESERVED 257
> /*
> ** Single-char tokens (terminal symbols) are represented by their own
> ** numeric code. Other tokens start at the following value.
> */
> #define FIRST_RESERVED (UCHAR_MAX + 1)
src/llimits.h
87c87,95
< /* internal assertions for in-house debugging */
> /*
> ** Internal assertions for in-house debugging
> */
> #if defined LUAI_ASSERT
> #undef NDEBUG
> #include <assert.h>
> #define lua_assert(c) assert(c)
> #endif
>
src/lmem.c
25c25
< #if defined(HARDMEMTESTS)
> #if defined(EMERGENCYGCTESTS)
src/lobject.c
218c218
< /* maximum length of a numeral */
> /* maximum length of a numeral to be converted to a number */
222a223,227
> /*
> ** Convert string 's' to a Lua number (put in 'result'). Return NULL on
> ** fail or the address of the ending '\0' on success. ('mode' == 'x')
> ** means a hexadecimal numeral.
> */
229c234
< return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
> return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */
234,239c239,240
< ** Convert string 's' to a Lua number (put in 'result'). Return NULL
< ** on fail or the address of the ending '\0' on success.
< ** 'pmode' points to (and 'mode' contains) special things in the string:
< ** - 'x'/'X' means a hexadecimal numeral
< ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
< ** - '.' just optimizes the search for the common case (nothing special)
> ** Convert string 's' to a Lua number (put in 'result') handling the
> ** current locale.
244a246,249
> ** The variable 'mode' checks for special characters in the string:
> ** - 'n' means 'inf' or 'nan' (which should be rejected)
> ** - 'x' means a hexadecimal numeral
> ** - '.' just optimizes the search for the common case (no special chars)
248c253
< const char *pmode = strpbrk(s, ".xXnN");
> const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */
336,337c341,349
< /* maximum length of the conversion of a number to a string */
< #define MAXNUMBER2STR 50
> /*
> ** Maximum length of the conversion of a number to a string. Must be
> ** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT.
> ** (For a long long int, this is 19 digits plus a sign and a final '\0',
> ** adding to 21. For a long double, it can go to a sign, 33 digits,
> ** the dot, an exponent letter, an exponent sign, 5 exponent digits,
> ** and a final '\0', adding to 43.)
> */
> #define MAXNUMBER2STR 44
378c390
< #define BUFVFS 400
> #define BUFVFS 200
390,391c402,403
< ** Push given string to the stack, as part of the buffer. If the stack
< ** is almost full, join all partial strings in the stack into one.
> ** Push given string to the stack, as part of the buffer, and
> ** join the partial strings in the stack into one.
398,401c410,411
< if (buff->pushed > 1 && L->top + 1 >= L->stack_last) {
< luaV_concat(L, buff->pushed); /* join all partial results into one */
< buff->pushed = 1;
< }
> luaV_concat(L, buff->pushed); /* join partial results into one */
> buff->pushed = 1;
524,525c534
< if (buff.pushed > 1)
< luaV_concat(L, buff.pushed); /* join all partial results */
> lua_assert(buff.pushed == 1);
src/lobject.h
99c99,100
< ** and it is not dead.
> ** and it is not dead. The option 'L == NULL' allows other
> ** macros using this one to be used where L is not available.
706,708c707,709
< #define isrealasize(t) (!((t)->marked & BITRAS))
< #define setrealasize(t) ((t)->marked &= cast_byte(~BITRAS))
< #define setnorealasize(t) ((t)->marked |= BITRAS)
> #define isrealasize(t) (!((t)->flags & BITRAS))
> #define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS))
> #define setnorealasize(t) ((t)->flags |= BITRAS)
src/lstate.c
303a304
> L->oldpc = 0;
321c322
< global_State *g = G(L);
> global_State *g;
323a325
> g = G(L);
397a400
> incnny(L); /* main thread is always non yieldable */
413,414c416,417
< g->survival = g->old = g->reallyold = NULL;
< g->finobjsur = g->finobjold = g->finobjrold = NULL;
> g->firstold1 = g->survival = g->old1 = g->reallyold = NULL;
> g->finobjsur = g->finobjold1 = g->finobjrold = NULL;
439d441
< L = G(L)->mainthread; /* only the main thread can be closed */
440a443
> L = G(L)->mainthread; /* only the main thread can be closed */
src/lstate.h
35c35
< ** 'old' -> 'reallyold': objects that became old in last collection;
> ** 'old1' -> 'reallyold': objects that became old in last collection;
39,40c39,40
< ** 'finobjsur' -> 'finobjold': survived """";
< ** 'finobjold' -> 'finobjrold': just old """";
> ** 'finobjsur' -> 'finobjold1': survived """";
> ** 'finobjold1' -> 'finobjrold': just old """";
41a42,57
> **
> ** All lists can contain elements older than their main ages, due
> ** to 'luaC_checkfinalizer' and 'udata2finalize', which move
> ** objects between the normal lists and the "marked for finalization"
> ** lists. Moreover, barriers can age young objects in young lists as
> ** OLD0, which then become OLD1. However, a list never contains
> ** elements younger than their main ages.
> **
> ** The generational collector also uses a pointer 'firstold1', which
> ** points to the first OLD1 object in the list. It is used to optimize
> ** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc'
> ** and 'reallyold', but often the list has no OLD1 objects or they are
> ** after 'old1'.) Note the difference between it and 'old1':
> ** 'firstold1': no OLD1 objects before this point; there can be all
> ** ages after it.
> ** 'old1': no objects younger than OLD1 after this point.
50c66
< ** must be gray:
> ** must be gray (with two exceptions explained below):
60a77,84
> **
> ** The exceptions to that "gray rule" are:
> ** - TOUCHED2 objects in generational mode stay in a gray list (because
> ** they must be visited again at the end of the cycle), but they are
> ** marked black because assignments to them must activate barriers (to
> ** move them back to TOUCHED1).
> ** - Open upvales are kept gray to avoid barriers, but they stay out
> ** of gray lists. (They don't even have a 'gclist' field.)
260,261c284,286
< GCObject *old; /* start of old objects */
< GCObject *reallyold; /* old objects with more than one cycle */
> GCObject *old1; /* start of old1 objects */
> GCObject *reallyold; /* objects more than one cycle old ("really old") */
> GCObject *firstold1; /* first OLD1 object in the list (if any) */
263c288
< GCObject *finobjold; /* list of old objects with finalizers */
> GCObject *finobjold1; /* list of old1 objects with finalizers */
289d313
< const Instruction *oldpc; /* last pc traced */
299a324
> int oldpc; /* last pc traced */
311a337,342
> ** ISO C99, 6.5.2.3 p.5:
> ** "if a union contains several structures that share a common initial
> ** sequence [...], and if the union object currently contains one
> ** of these structures, it is permitted to inspect the common initial
> ** part of any of them anywhere that a declaration of the complete type
> ** of the union is visible."
324a356,360
> /*
> ** ISO C99, 6.7.2.1 p.14:
> ** "A pointer to a union object, suitably converted, points to each of
> ** its members [...], and vice versa."
> */
src/ltable.c
586c586
< t->flags = cast_byte(~0);
> t->flags = cast_byte(maskflags); /* table has no metamethod fields */
src/ltable.h
18c18,23
< #define invalidateTMcache(t) ((t)->flags = 0)
> /*
> ** Clear all bits of fast-access metamethods, which means that the table
> ** may have any of these metamethods. (First access that fails after the
> ** clearing will set the bit again.)
> */
> #define invalidateTMcache(t) ((t)->flags &= ~maskflags)
src/ltm.c
243c243
< checkstackGC(L, p->maxstacksize + 1);
> luaD_checkstack(L, p->maxstacksize + 1);
262c262
< checkstackp(L, nextra, where); /* ensure stack space */
> checkstackGCp(L, nextra, where); /* ensure stack space */
src/ltm.h
48a49,57
> ** Mask with 1 in all fast-access methods. A 1 in any of these bits
> ** in the flag of a (meta)table means the metatable does not have the
> ** corresponding metamethod field. (Bit 7 of the flag is used for
> ** 'isrealasize'.)
> */
> #define maskflags (~(~0u << (TM_EQ + 1)))
>
>
> /*
src/lua.h
21c21
< #define LUA_VERSION_RELEASE "0"
> #define LUA_VERSION_RELEASE "1"
src/lundump.c
122a123,124
> setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
> luaD_inctop(L);
123a126
> L->top--; /* pop string */
202a206,211
> /*
> ** Load the upvalues for a function. The names must be filled first,
> ** because the filling of the other fields can raise read errors and
> ** the creation of the error message can call an emergency collection;
> ** in that case all prototypes must be consistent for the GC.
> */
208c217
< for (i = 0; i < n; i++) {
> for (i = 0; i < n; i++) /* make array valid for GC */
209a219
> for (i = 0; i < n; i++) { /* following calls can raise errors */
src/lvm.c
637c637,638
< lua_assert(total >= 2);
> if (total == 1)
> return; /* "all" values already concatenated */
843,846c844,845
< if (total > 1) { /* are there elements to concat? */
< L->top = top - 1; /* top is one after last element (at top-2) */
< luaV_concat(L, total); /* concat them (may yield again) */
< }
> L->top = top - 1; /* top is one after last element (at top-2) */
> luaV_concat(L, total); /* concat them (may yield again) */
1105c1104
<
> /* 'c' is the limit of live values in the stack */
1107c1106
< { luaC_condGC(L, L->top = (c), /* limit of live values */ \
> { luaC_condGC(L, (savepc(L), L->top = (c)), \
1638c1637
< checkstackp(L, 1, ra);
> checkstackGCp(L, 1, ra);
1795,1796c1794
< luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p);
< updatetrap(ci);
> ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
1799c1797
< L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */
> L->oldpc = 1; /* next opcode will be seen as a "new" line */