aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lapi.c10
-rw-r--r--lauxlib.c10
-rw-r--r--lcode.c23
-rw-r--r--lcode.h2
-rw-r--r--lcorolib.c16
-rw-r--r--lctype.c2
-rw-r--r--ldebug.c19
-rw-r--r--ldo.c26
-rw-r--r--ldo.h1
-rw-r--r--ldump.c27
-rw-r--r--lgc.c52
-rw-r--r--llex.c18
-rw-r--r--llex.h6
-rw-r--r--llimits.h4
-rw-r--r--loadlib.c75
-rw-r--r--lobject.c12
-rw-r--r--lobject.h12
-rw-r--r--lopcodes.h46
-rw-r--r--loslib.c5
-rw-r--r--lparser.c321
-rw-r--r--lparser.h41
-rw-r--r--lstate.c2
-rw-r--r--lstate.h4
-rw-r--r--lstring.c46
-rw-r--r--lstring.h3
-rw-r--r--lstrlib.c28
-rw-r--r--ltable.c132
-rw-r--r--ltable.h2
-rw-r--r--ltests.c36
-rw-r--r--ltests.h2
-rw-r--r--lua.c71
-rw-r--r--lua.h6
-rw-r--r--luaconf.h26
-rw-r--r--lundump.c35
-rw-r--r--lutf8lib.c11
-rw-r--r--lvm.c110
-rwxr-xr-xmanual/2html6
-rw-r--r--manual/manual.of350
-rwxr-xr-xtestes/all.lua8
-rw-r--r--testes/api.lua6
-rw-r--r--testes/attrib.lua24
-rw-r--r--testes/bwcoercion.lua2
-rw-r--r--testes/calls.lua15
-rw-r--r--testes/closure.lua2
-rw-r--r--testes/code.lua24
-rw-r--r--testes/constructs.lua2
-rw-r--r--testes/coroutine.lua65
-rw-r--r--testes/db.lua21
-rw-r--r--testes/errors.lua16
-rw-r--r--testes/files.lua10
-rw-r--r--testes/gc.lua25
-rw-r--r--testes/goto.lua170
-rw-r--r--testes/libs/lib22.c51
-rw-r--r--testes/literals.lua2
-rw-r--r--testes/locals.lua42
-rw-r--r--testes/main.lua13
-rw-r--r--testes/math.lua21
-rw-r--r--testes/nextvar.lua23
-rw-r--r--testes/pm.lua6
-rw-r--r--testes/strings.lua1
-rw-r--r--testes/tracegc.lua2
-rw-r--r--testes/utf8.lua13
62 files changed, 1490 insertions, 672 deletions
diff --git a/lapi.c b/lapi.c
index f59430a7..0c88751a 100644
--- a/lapi.c
+++ b/lapi.c
@@ -440,7 +440,7 @@ LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
440 case LUA_VSHRSTR: return cast(lua_Unsigned, tsvalue(o)->shrlen); 440 case LUA_VSHRSTR: return cast(lua_Unsigned, tsvalue(o)->shrlen);
441 case LUA_VLNGSTR: return cast(lua_Unsigned, tsvalue(o)->u.lnglen); 441 case LUA_VLNGSTR: return cast(lua_Unsigned, tsvalue(o)->u.lnglen);
442 case LUA_VUSERDATA: return cast(lua_Unsigned, uvalue(o)->len); 442 case LUA_VUSERDATA: return cast(lua_Unsigned, uvalue(o)->len);
443 case LUA_VTABLE: return luaH_getn(hvalue(o)); 443 case LUA_VTABLE: return luaH_getn(L, hvalue(o));
444 default: return 0; 444 default: return 0;
445 } 445 }
446} 446}
@@ -593,12 +593,8 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
593 const char *ret; 593 const char *ret;
594 va_list argp; 594 va_list argp;
595 lua_lock(L); 595 lua_lock(L);
596 va_start(argp, fmt); 596 pushvfstring(L, argp, fmt, ret);
597 ret = luaO_pushvfstring(L, fmt, argp);
598 va_end(argp);
599 luaC_checkGC(L); 597 luaC_checkGC(L);
600 if (ret == NULL) /* error? */
601 luaD_throw(L, LUA_ERRMEM);
602 lua_unlock(L); 598 lua_unlock(L);
603 return ret; 599 return ret;
604} 600}
@@ -683,7 +679,7 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
683 679
684/* 680/*
685** The following function assumes that the registry cannot be a weak 681** The following function assumes that the registry cannot be a weak
686** table, so that en mergency collection while using the global table 682** table; so, an emergency collection while using the global table
687** cannot collect it. 683** cannot collect it.
688*/ 684*/
689static void getGlobalTable (lua_State *L, TValue *gt) { 685static void getGlobalTable (lua_State *L, TValue *gt) {
diff --git a/lauxlib.c b/lauxlib.c
index 7c9ad53b..7f33f0ad 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -94,14 +94,14 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
94 94
95 95
96static void pushfuncname (lua_State *L, lua_Debug *ar) { 96static void pushfuncname (lua_State *L, lua_Debug *ar) {
97 if (pushglobalfuncname(L, ar)) { /* try first a global name */ 97 if (*ar->namewhat != '\0') /* is there a name from code? */
98 lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
99 lua_remove(L, -2); /* remove name */
100 }
101 else if (*ar->namewhat != '\0') /* is there a name from code? */
102 lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ 98 lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */
103 else if (*ar->what == 'm') /* main? */ 99 else if (*ar->what == 'm') /* main? */
104 lua_pushliteral(L, "main chunk"); 100 lua_pushliteral(L, "main chunk");
101 else if (pushglobalfuncname(L, ar)) { /* try a global name */
102 lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
103 lua_remove(L, -2); /* remove name */
104 }
105 else if (*ar->what != 'C') /* for Lua functions, use <file:line> */ 105 else if (*ar->what != 'C') /* for Lua functions, use <file:line> */
106 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); 106 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
107 else /* nothing left... */ 107 else /* nothing left... */
diff --git a/lcode.c b/lcode.c
index 8c04d8ab..7ca895f1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -40,7 +40,10 @@ static int codesJ (FuncState *fs, OpCode o, int sj, int k);
40 40
41 41
42/* semantic error */ 42/* semantic error */
43l_noret luaK_semerror (LexState *ls, const char *msg) { 43l_noret luaK_semerror (LexState *ls, const char *fmt, ...) {
44 const char *msg;
45 va_list argp;
46 pushvfstring(ls->L, argp, fmt, msg);
44 ls->t.token = 0; /* remove "near <token>" from final message */ 47 ls->t.token = 0; /* remove "near <token>" from final message */
45 luaX_syntaxerror(ls, msg); 48 luaX_syntaxerror(ls, msg);
46} 49}
@@ -750,10 +753,11 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
750/* 753/*
751** Convert a VKSTR to a VK 754** Convert a VKSTR to a VK
752*/ 755*/
753static void str2K (FuncState *fs, expdesc *e) { 756static int str2K (FuncState *fs, expdesc *e) {
754 lua_assert(e->k == VKSTR); 757 lua_assert(e->k == VKSTR);
755 e->u.info = stringK(fs, e->u.strval); 758 e->u.info = stringK(fs, e->u.strval);
756 e->k = VK; 759 e->k = VK;
760 return e->u.info;
757} 761}
758 762
759 763
@@ -1304,35 +1308,38 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
1304** values in registers. 1308** values in registers.
1305*/ 1309*/
1306void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 1310void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1311 int keystr = -1;
1307 if (k->k == VKSTR) 1312 if (k->k == VKSTR)
1308 str2K(fs, k); 1313 keystr = str2K(fs, k);
1309 lua_assert(!hasjumps(t) && 1314 lua_assert(!hasjumps(t) &&
1310 (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); 1315 (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
1311 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ 1316 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
1312 luaK_exp2anyreg(fs, t); /* put it in a register */ 1317 luaK_exp2anyreg(fs, t); /* put it in a register */
1313 if (t->k == VUPVAL) { 1318 if (t->k == VUPVAL) {
1314 lu_byte temp = cast_byte(t->u.info); /* upvalue index */ 1319 lu_byte temp = cast_byte(t->u.info); /* upvalue index */
1315 lua_assert(isKstr(fs, k));
1316 t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */ 1320 t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */
1317 t->u.ind.idx = cast(short, k->u.info); /* literal short string */ 1321 lua_assert(isKstr(fs, k));
1322 t->u.ind.idx = cast_short(k->u.info); /* literal short string */
1318 t->k = VINDEXUP; 1323 t->k = VINDEXUP;
1319 } 1324 }
1320 else { 1325 else {
1321 /* register index of the table */ 1326 /* register index of the table */
1322 t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info); 1327 t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info);
1323 if (isKstr(fs, k)) { 1328 if (isKstr(fs, k)) {
1324 t->u.ind.idx = cast(short, k->u.info); /* literal short string */ 1329 t->u.ind.idx = cast_short(k->u.info); /* literal short string */
1325 t->k = VINDEXSTR; 1330 t->k = VINDEXSTR;
1326 } 1331 }
1327 else if (isCint(k)) { /* int. constant in proper range? */ 1332 else if (isCint(k)) { /* int. constant in proper range? */
1328 t->u.ind.idx = cast(short, k->u.ival); 1333 t->u.ind.idx = cast_short(k->u.ival);
1329 t->k = VINDEXI; 1334 t->k = VINDEXI;
1330 } 1335 }
1331 else { 1336 else {
1332 t->u.ind.idx = cast(short, luaK_exp2anyreg(fs, k)); /* register */ 1337 t->u.ind.idx = cast_short(luaK_exp2anyreg(fs, k)); /* register */
1333 t->k = VINDEXED; 1338 t->k = VINDEXED;
1334 } 1339 }
1335 } 1340 }
1341 t->u.ind.keystr = keystr; /* string index in 'k' */
1342 t->u.ind.ro = 0; /* by default, not read-only */
1336} 1343}
1337 1344
1338 1345
diff --git a/lcode.h b/lcode.h
index 414ebe39..94fc2417 100644
--- a/lcode.h
+++ b/lcode.h
@@ -97,7 +97,7 @@ LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc,
97 int ra, int asize, int hsize); 97 int ra, int asize, int hsize);
98LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 98LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
99LUAI_FUNC void luaK_finish (FuncState *fs); 99LUAI_FUNC void luaK_finish (FuncState *fs);
100LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); 100LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *fmt, ...);
101 101
102 102
103#endif 103#endif
diff --git a/lcorolib.c b/lcorolib.c
index 3d95f873..23dd8441 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -154,8 +154,13 @@ static int luaB_costatus (lua_State *L) {
154} 154}
155 155
156 156
157static lua_State *getoptco (lua_State *L) {
158 return (lua_isnone(L, 1) ? L : getco(L));
159}
160
161
157static int luaB_yieldable (lua_State *L) { 162static int luaB_yieldable (lua_State *L) {
158 lua_State *co = lua_isnone(L, 1) ? L : getco(L); 163 lua_State *co = getoptco(L);
159 lua_pushboolean(L, lua_isyieldable(co)); 164 lua_pushboolean(L, lua_isyieldable(co));
160 return 1; 165 return 1;
161} 166}
@@ -169,7 +174,7 @@ static int luaB_corunning (lua_State *L) {
169 174
170 175
171static int luaB_close (lua_State *L) { 176static int luaB_close (lua_State *L) {
172 lua_State *co = getco(L); 177 lua_State *co = getoptco(L);
173 int status = auxstatus(L, co); 178 int status = auxstatus(L, co);
174 switch (status) { 179 switch (status) {
175 case COS_DEAD: case COS_YIELD: { 180 case COS_DEAD: case COS_YIELD: {
@@ -184,6 +189,13 @@ static int luaB_close (lua_State *L) {
184 return 2; 189 return 2;
185 } 190 }
186 } 191 }
192 case COS_RUN: /* running coroutine? */
193 lua_geti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); /* get main */
194 if (lua_tothread(L, -1) == co)
195 return luaL_error(L, "cannot close main thread");
196 lua_closethread(co, L); /* close itself */
197 lua_assert(0); /* previous call does not return */
198 return 0;
187 default: /* normal or running coroutine */ 199 default: /* normal or running coroutine */
188 return luaL_error(L, "cannot close a %s coroutine", statname[status]); 200 return luaL_error(L, "cannot close a %s coroutine", statname[status]);
189 } 201 }
diff --git a/lctype.c b/lctype.c
index 95422809..b1a43e44 100644
--- a/lctype.c
+++ b/lctype.c
@@ -18,7 +18,7 @@
18 18
19 19
20#if defined (LUA_UCID) /* accept UniCode IDentifiers? */ 20#if defined (LUA_UCID) /* accept UniCode IDentifiers? */
21/* consider all non-ascii codepoints to be alphabetic */ 21/* consider all non-ASCII codepoints to be alphabetic */
22#define NONA 0x01 22#define NONA 0x01
23#else 23#else
24#define NONA 0x00 /* default */ 24#define NONA 0x00 /* default */
diff --git a/ldebug.c b/ldebug.c
index 258a4394..9110f437 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -817,16 +817,15 @@ l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
817/* add src:line information to 'msg' */ 817/* add src:line information to 'msg' */
818const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, 818const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
819 int line) { 819 int line) {
820 char buff[LUA_IDSIZE]; 820 if (src == NULL) /* no debug information? */
821 if (src) { 821 return luaO_pushfstring(L, "?:?: %s", msg);
822 else {
823 char buff[LUA_IDSIZE];
822 size_t idlen; 824 size_t idlen;
823 const char *id = getlstr(src, idlen); 825 const char *id = getlstr(src, idlen);
824 luaO_chunkid(buff, id, idlen); 826 luaO_chunkid(buff, id, idlen);
827 return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
825 } 828 }
826 else { /* no source available; use "?" instead */
827 buff[0] = '?'; buff[1] = '\0';
828 }
829 return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
830} 829}
831 830
832 831
@@ -852,12 +851,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
852 const char *msg; 851 const char *msg;
853 va_list argp; 852 va_list argp;
854 luaC_checkGC(L); /* error message uses memory */ 853 luaC_checkGC(L); /* error message uses memory */
855 va_start(argp, fmt); 854 pushvfstring(L, argp, fmt, msg);
856 msg = luaO_pushvfstring(L, fmt, argp); /* format message */ 855 if (isLua(ci)) { /* Lua function? */
857 va_end(argp);
858 if (msg == NULL) /* no memory to format message? */
859 luaD_throw(L, LUA_ERRMEM);
860 else if (isLua(ci)) { /* Lua function? */
861 /* add source:line information */ 856 /* add source:line information */
862 luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); 857 luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
863 setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */ 858 setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
diff --git a/ldo.c b/ldo.c
index 3e5c7504..f232b588 100644
--- a/ldo.c
+++ b/ldo.c
@@ -139,6 +139,16 @@ l_noret luaD_throw (lua_State *L, TStatus errcode) {
139} 139}
140 140
141 141
142l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode) {
143 if (L->errorJmp) {
144 /* unroll error entries up to the first level */
145 while (L->errorJmp->previous != NULL)
146 L->errorJmp = L->errorJmp->previous;
147 }
148 luaD_throw(L, errcode);
149}
150
151
142TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 152TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
143 l_uint32 oldnCcalls = L->nCcalls; 153 l_uint32 oldnCcalls = L->nCcalls;
144 struct lua_longjmp lj; 154 struct lua_longjmp lj;
@@ -164,6 +174,20 @@ TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
164#define STACKERRSPACE 200 174#define STACKERRSPACE 200
165 175
166 176
177/*
178** LUAI_MAXSTACK limits the size of the Lua stack.
179** It must fit into INT_MAX/2.
180*/
181
182#if !defined(LUAI_MAXSTACK)
183#if 1000000 < (INT_MAX / 2)
184#define LUAI_MAXSTACK 1000000
185#else
186#define LUAI_MAXSTACK (INT_MAX / 2u)
187#endif
188#endif
189
190
167/* maximum stack size that respects size_t */ 191/* maximum stack size that respects size_t */
168#define MAXSTACK_BYSIZET ((MAX_SIZET / sizeof(StackValue)) - STACKERRSPACE) 192#define MAXSTACK_BYSIZET ((MAX_SIZET / sizeof(StackValue)) - STACKERRSPACE)
169 193
@@ -513,7 +537,7 @@ l_sinline void genmoveresults (lua_State *L, StkId res, int nres,
513** to 'res'. Handle most typical cases (zero results for commands, 537** to 'res'. Handle most typical cases (zero results for commands,
514** one result for expressions, multiple results for tail calls/single 538** one result for expressions, multiple results for tail calls/single
515** parameters) separated. The flag CIST_TBC in 'fwanted', if set, 539** parameters) separated. The flag CIST_TBC in 'fwanted', if set,
516** forces the swicth to go to the default case. 540** forces the switch to go to the default case.
517*/ 541*/
518l_sinline void moveresults (lua_State *L, StkId res, int nres, 542l_sinline void moveresults (lua_State *L, StkId res, int nres,
519 l_uint32 fwanted) { 543 l_uint32 fwanted) {
diff --git a/ldo.h b/ldo.h
index 465f4fb8..2d4ca8be 100644
--- a/ldo.h
+++ b/ldo.h
@@ -91,6 +91,7 @@ LUAI_FUNC void luaD_shrinkstack (lua_State *L);
91LUAI_FUNC void luaD_inctop (lua_State *L); 91LUAI_FUNC void luaD_inctop (lua_State *L);
92 92
93LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode); 93LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode);
94LUAI_FUNC l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode);
94LUAI_FUNC TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 95LUAI_FUNC TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
95 96
96#endif 97#endif
diff --git a/ldump.c b/ldump.c
index d8fca317..a75b20d2 100644
--- a/ldump.c
+++ b/ldump.c
@@ -31,7 +31,7 @@ typedef struct {
31 int strip; 31 int strip;
32 int status; 32 int status;
33 Table *h; /* table to track saved strings */ 33 Table *h; /* table to track saved strings */
34 lua_Integer nstr; /* counter for counting saved strings */ 34 lua_Unsigned nstr; /* counter for counting saved strings */
35} DumpState; 35} DumpState;
36 36
37 37
@@ -87,12 +87,12 @@ static void dumpByte (DumpState *D, int y) {
87** size for 'dumpVarint' buffer: each byte can store up to 7 bits. 87** size for 'dumpVarint' buffer: each byte can store up to 7 bits.
88** (The "+6" rounds up the division.) 88** (The "+6" rounds up the division.)
89*/ 89*/
90#define DIBS ((l_numbits(size_t) + 6) / 7) 90#define DIBS ((l_numbits(lua_Unsigned) + 6) / 7)
91 91
92/* 92/*
93** Dumps an unsigned integer using the MSB Varint encoding 93** Dumps an unsigned integer using the MSB Varint encoding
94*/ 94*/
95static void dumpVarint (DumpState *D, size_t x) { 95static void dumpVarint (DumpState *D, lua_Unsigned x) {
96 lu_byte buff[DIBS]; 96 lu_byte buff[DIBS];
97 unsigned n = 1; 97 unsigned n = 1;
98 buff[DIBS - 1] = x & 0x7f; /* fill least-significant byte */ 98 buff[DIBS - 1] = x & 0x7f; /* fill least-significant byte */
@@ -103,12 +103,13 @@ static void dumpVarint (DumpState *D, size_t x) {
103 103
104 104
105static void dumpSize (DumpState *D, size_t sz) { 105static void dumpSize (DumpState *D, size_t sz) {
106 dumpVarint(D, sz); 106 dumpVarint(D, cast(lua_Unsigned, sz));
107} 107}
108 108
109
109static void dumpInt (DumpState *D, int x) { 110static void dumpInt (DumpState *D, int x) {
110 lua_assert(x >= 0); 111 lua_assert(x >= 0);
111 dumpVarint(D, cast(size_t, x)); 112 dumpVarint(D, cast_uint(x));
112} 113}
113 114
114 115
@@ -117,8 +118,16 @@ static void dumpNumber (DumpState *D, lua_Number x) {
117} 118}
118 119
119 120
121/*
122** Signed integers are coded to keep small values small. (Coding -1 as
123** 0xfff...fff would use too many bytes to save a quite common value.)
124** A non-negative x is coded as 2x; a negative x is coded as -2x - 1.
125** (0 => 0; -1 => 1; 1 => 2; -2 => 3; 2 => 4; ...)
126*/
120static void dumpInteger (DumpState *D, lua_Integer x) { 127static void dumpInteger (DumpState *D, lua_Integer x) {
121 dumpVar(D, x); 128 lua_Unsigned cx = (x >= 0) ? 2u * l_castS2U(x)
129 : (2u * ~l_castS2U(x)) + 1;
130 dumpVarint(D, cx);
122} 131}
123 132
124 133
@@ -136,8 +145,8 @@ static void dumpString (DumpState *D, TString *ts) {
136 TValue idx; 145 TValue idx;
137 int tag = luaH_getstr(D->h, ts, &idx); 146 int tag = luaH_getstr(D->h, ts, &idx);
138 if (!tagisempty(tag)) { /* string already saved? */ 147 if (!tagisempty(tag)) { /* string already saved? */
139 dumpSize(D, 1); /* reuse a saved string */ 148 dumpVarint(D, 1); /* reuse a saved string */
140 dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */ 149 dumpVarint(D, l_castS2U(ivalue(&idx))); /* index of saved string */
141 } 150 }
142 else { /* must write and save the string */ 151 else { /* must write and save the string */
143 TValue key, value; /* to save the string in the hash */ 152 TValue key, value; /* to save the string in the hash */
@@ -147,7 +156,7 @@ static void dumpString (DumpState *D, TString *ts) {
147 dumpVector(D, s, size + 1); /* include ending '\0' */ 156 dumpVector(D, s, size + 1); /* include ending '\0' */
148 D->nstr++; /* one more saved string */ 157 D->nstr++; /* one more saved string */
149 setsvalue(D->L, &key, ts); /* the string is the key */ 158 setsvalue(D->L, &key, ts); /* the string is the key */
150 setivalue(&value, D->nstr); /* its index is the value */ 159 setivalue(&value, l_castU2S(D->nstr)); /* its index is the value */
151 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */ 160 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */
152 /* integer value does not need barrier */ 161 /* integer value does not need barrier */
153 } 162 }
diff --git a/lgc.c b/lgc.c
index cada07d9..bbaa5ff7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -126,7 +126,6 @@ static l_mem objsize (GCObject *o) {
126 CClosure *cl = gco2ccl(o); 126 CClosure *cl = gco2ccl(o);
127 res = sizeCclosure(cl->nupvalues); 127 res = sizeCclosure(cl->nupvalues);
128 break; 128 break;
129 break;
130 } 129 }
131 case LUA_VUSERDATA: { 130 case LUA_VUSERDATA: {
132 Udata *u = gco2u(o); 131 Udata *u = gco2u(o);
@@ -465,6 +464,8 @@ static void restartcollection (global_State *g) {
465** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go 464** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go
466** back to a gray list, but then it must become OLD. (That is what 465** back to a gray list, but then it must become OLD. (That is what
467** 'correctgraylist' does when it finds a TOUCHED2 object.) 466** 'correctgraylist' does when it finds a TOUCHED2 object.)
467** This function is a no-op in incremental mode, as objects cannot be
468** marked as touched in that mode.
468*/ 469*/
469static void genlink (global_State *g, GCObject *o) { 470static void genlink (global_State *g, GCObject *o) {
470 lua_assert(isblack(o)); 471 lua_assert(isblack(o));
@@ -480,7 +481,8 @@ static void genlink (global_State *g, GCObject *o) {
480** Traverse a table with weak values and link it to proper list. During 481** Traverse a table with weak values and link it to proper list. During
481** propagate phase, keep it in 'grayagain' list, to be revisited in the 482** propagate phase, keep it in 'grayagain' list, to be revisited in the
482** atomic phase. In the atomic phase, if table has any white value, 483** atomic phase. In the atomic phase, if table has any white value,
483** put it in 'weak' list, to be cleared. 484** put it in 'weak' list, to be cleared; otherwise, call 'genlink'
485** to check table age in generational mode.
484*/ 486*/
485static void traverseweakvalue (global_State *g, Table *h) { 487static void traverseweakvalue (global_State *g, Table *h) {
486 Node *n, *limit = gnodelast(h); 488 Node *n, *limit = gnodelast(h);
@@ -501,6 +503,8 @@ static void traverseweakvalue (global_State *g, Table *h) {
501 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ 503 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
502 else if (hasclears) 504 else if (hasclears)
503 linkgclist(h, g->weak); /* has to be cleared later */ 505 linkgclist(h, g->weak); /* has to be cleared later */
506 else
507 genlink(g, obj2gco(h));
504} 508}
505 509
506 510
@@ -585,25 +589,41 @@ static void traversestrongtable (global_State *g, Table *h) {
585} 589}
586 590
587 591
588static l_mem traversetable (global_State *g, Table *h) { 592/*
589 const char *weakkey, *weakvalue; 593** (result & 1) iff weak values; (result & 2) iff weak keys.
594*/
595static int getmode (global_State *g, Table *h) {
590 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); 596 const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
591 TString *smode; 597 if (mode == NULL || !ttisshrstring(mode))
598 return 0; /* ignore non-(short)string modes */
599 else {
600 const char *smode = getshrstr(tsvalue(mode));
601 const char *weakkey = strchr(smode, 'k');
602 const char *weakvalue = strchr(smode, 'v');
603 return ((weakkey != NULL) << 1) | (weakvalue != NULL);
604 }
605}
606
607
608static l_mem traversetable (global_State *g, Table *h) {
592 markobjectN(g, h->metatable); 609 markobjectN(g, h->metatable);
593 if (mode && ttisshrstring(mode) && /* is there a weak mode? */ 610 switch (getmode(g, h)) {
594 (cast_void(smode = tsvalue(mode)), 611 case 0: /* not weak */
595 cast_void(weakkey = strchr(getshrstr(smode), 'k')), 612 traversestrongtable(g, h);
596 cast_void(weakvalue = strchr(getshrstr(smode), 'v')), 613 break;
597 (weakkey || weakvalue))) { /* is really weak? */ 614 case 1: /* weak values */
598 if (!weakkey) /* strong keys? */
599 traverseweakvalue(g, h); 615 traverseweakvalue(g, h);
600 else if (!weakvalue) /* strong values? */ 616 break;
617 case 2: /* weak keys */
601 traverseephemeron(g, h, 0); 618 traverseephemeron(g, h, 0);
602 else /* all weak */ 619 break;
603 linkgclist(h, g->allweak); /* nothing to traverse now */ 620 case 3: /* all weak; nothing to traverse */
621 if (g->gcstate == GCSpropagate)
622 linkgclist(h, g->grayagain); /* must visit again its metatable */
623 else
624 linkgclist(h, g->allweak); /* must clear collected entries */
625 break;
604 } 626 }
605 else /* not weak */
606 traversestrongtable(g, h);
607 return 1 + 2*sizenode(h) + h->asize; 627 return 1 + 2*sizenode(h) + h->asize;
608} 628}
609 629
diff --git a/llex.c b/llex.c
index 4b5a1f75..f8bb3ea4 100644
--- a/llex.c
+++ b/llex.c
@@ -44,7 +44,7 @@
44/* ORDER RESERVED */ 44/* ORDER RESERVED */
45static const char *const luaX_tokens [] = { 45static const char *const luaX_tokens [] = {
46 "and", "break", "do", "else", "elseif", 46 "and", "break", "do", "else", "elseif",
47 "end", "false", "for", "function", "goto", "if", 47 "end", "false", "for", "function", "global", "goto", "if",
48 "in", "local", "nil", "not", "or", "repeat", 48 "in", "local", "nil", "not", "or", "repeat",
49 "return", "then", "true", "until", "while", 49 "return", "then", "true", "until", "while",
50 "//", "..", "...", "==", ">=", "<=", "~=", 50 "//", "..", "...", "==", ">=", "<=", "~=",
@@ -184,7 +184,15 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
184 ls->linenumber = 1; 184 ls->linenumber = 1;
185 ls->lastline = 1; 185 ls->lastline = 1;
186 ls->source = source; 186 ls->source = source;
187 ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */ 187 /* all three strings here ("_ENV", "break", "global") were fixed,
188 so they cannot be collected */
189 ls->envn = luaS_newliteral(L, LUA_ENV); /* get env string */
190 ls->brkn = luaS_newliteral(L, "break"); /* get "break" string */
191#if defined(LUA_COMPAT_GLOBAL)
192 /* compatibility mode: "global" is not a reserved word */
193 ls->glbn = luaS_newliteral(L, "global"); /* get "global" string */
194 ls->glbn->extra = 0; /* mark it as not reserved */
195#endif
188 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ 196 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
189} 197}
190 198
@@ -354,12 +362,12 @@ static int readhexaesc (LexState *ls) {
354** for error reporting in case of errors; 'i' counts the number of 362** for error reporting in case of errors; 'i' counts the number of
355** saved characters, so that they can be removed if case of success. 363** saved characters, so that they can be removed if case of success.
356*/ 364*/
357static unsigned long readutf8esc (LexState *ls) { 365static l_uint32 readutf8esc (LexState *ls) {
358 unsigned long r; 366 l_uint32 r;
359 int i = 4; /* number of chars to be removed: start with #"\u{X" */ 367 int i = 4; /* number of chars to be removed: start with #"\u{X" */
360 save_and_next(ls); /* skip 'u' */ 368 save_and_next(ls); /* skip 'u' */
361 esccheck(ls, ls->current == '{', "missing '{'"); 369 esccheck(ls, ls->current == '{', "missing '{'");
362 r = cast_ulong(gethexa(ls)); /* must have at least one digit */ 370 r = cast_uint(gethexa(ls)); /* must have at least one digit */
363 while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) { 371 while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) {
364 i++; 372 i++;
365 esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large"); 373 esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large");
diff --git a/llex.h b/llex.h
index c3500ef6..37016e8a 100644
--- a/llex.h
+++ b/llex.h
@@ -33,8 +33,8 @@ enum RESERVED {
33 /* terminal symbols denoted by reserved words */ 33 /* terminal symbols denoted by reserved words */
34 TK_AND = FIRST_RESERVED, TK_BREAK, 34 TK_AND = FIRST_RESERVED, TK_BREAK,
35 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 35 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
36 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 36 TK_GLOBAL, TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR,
37 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 37 TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
38 /* other terminal symbols */ 38 /* other terminal symbols */
39 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 39 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
40 TK_SHL, TK_SHR, 40 TK_SHL, TK_SHR,
@@ -75,6 +75,8 @@ typedef struct LexState {
75 struct Dyndata *dyd; /* dynamic structures used by the parser */ 75 struct Dyndata *dyd; /* dynamic structures used by the parser */
76 TString *source; /* current source name */ 76 TString *source; /* current source name */
77 TString *envn; /* environment variable name */ 77 TString *envn; /* environment variable name */
78 TString *brkn; /* "break" name (used as a label) */
79 TString *glbn; /* "global" name (when not a reserved word) */
78} LexState; 80} LexState;
79 81
80 82
diff --git a/llimits.h b/llimits.h
index 710dc1b4..223b5e6c 100644
--- a/llimits.h
+++ b/llimits.h
@@ -137,13 +137,15 @@ typedef LUAI_UACINT l_uacInt;
137#define cast_voidp(i) cast(void *, (i)) 137#define cast_voidp(i) cast(void *, (i))
138#define cast_num(i) cast(lua_Number, (i)) 138#define cast_num(i) cast(lua_Number, (i))
139#define cast_int(i) cast(int, (i)) 139#define cast_int(i) cast(int, (i))
140#define cast_short(i) cast(short, (i))
140#define cast_uint(i) cast(unsigned int, (i)) 141#define cast_uint(i) cast(unsigned int, (i))
141#define cast_ulong(i) cast(unsigned long, (i))
142#define cast_byte(i) cast(lu_byte, (i)) 142#define cast_byte(i) cast(lu_byte, (i))
143#define cast_uchar(i) cast(unsigned char, (i)) 143#define cast_uchar(i) cast(unsigned char, (i))
144#define cast_char(i) cast(char, (i)) 144#define cast_char(i) cast(char, (i))
145#define cast_charp(i) cast(char *, (i)) 145#define cast_charp(i) cast(char *, (i))
146#define cast_sizet(i) cast(size_t, (i)) 146#define cast_sizet(i) cast(size_t, (i))
147#define cast_Integer(i) cast(lua_Integer, (i))
148#define cast_Inst(i) cast(Instruction, (i))
147 149
148 150
149/* cast a signed lua_Integer to lua_Unsigned */ 151/* cast a signed lua_Integer to lua_Unsigned */
diff --git a/loadlib.c b/loadlib.c
index 5f0c1702..8d2e68e2 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -307,6 +307,16 @@ static void setpath (lua_State *L, const char *fieldname,
307 307
308 308
309/* 309/*
310** External strings created by DLLs may need the DLL code to be
311** deallocated. This implies that a DLL can only be unloaded after all
312** its strings were deallocated. To ensure that, we create a 'library
313** string' to represent each DLL, and when this string is deallocated
314** it closes its corresponding DLL.
315** (The string itself is irrelevant; its userdata is the DLL pointer.)
316*/
317
318
319/*
310** return registry.CLIBS[path] 320** return registry.CLIBS[path]
311*/ 321*/
312static void *checkclib (lua_State *L, const char *path) { 322static void *checkclib (lua_State *L, const char *path) {
@@ -320,34 +330,41 @@ static void *checkclib (lua_State *L, const char *path) {
320 330
321 331
322/* 332/*
323** registry.CLIBS[path] = plib -- for queries 333** Deallocate function for library strings.
324** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries 334** Unload the DLL associated with the string being deallocated.
325*/ 335*/
326static void addtoclib (lua_State *L, const char *path, void *plib) { 336static void *freelib (void *ud, void *ptr, size_t osize, size_t nsize) {
327 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 337 /* string itself is irrelevant and static */
328 lua_pushlightuserdata(L, plib); 338 (void)ptr; (void)osize; (void)nsize;
329 lua_pushvalue(L, -1); 339 lsys_unloadlib(ud); /* unload library represented by the string */
330 lua_setfield(L, -3, path); /* CLIBS[path] = plib */ 340 return NULL;
331 lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
332 lua_pop(L, 1); /* pop CLIBS table */
333} 341}
334 342
335 343
336/* 344/*
337** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib 345** Create a library string that, when deallocated, will unload 'plib'
338** handles in list CLIBS
339*/ 346*/
340static int gctm (lua_State *L) { 347static void createlibstr (lua_State *L, void *plib) {
341 lua_Integer n = luaL_len(L, 1); 348 /* common content for all library strings */
342 for (; n >= 1; n--) { /* for each handle, in reverse order */ 349 static const char dummy[] = "01234567890";
343 lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ 350 lua_pushexternalstring(L, dummy, sizeof(dummy) - 1, freelib, plib);
344 lsys_unloadlib(lua_touserdata(L, -1));
345 lua_pop(L, 1); /* pop handle */
346 }
347 return 0;
348} 351}
349 352
350 353
354/*
355** registry.CLIBS[path] = plib -- for queries.
356** Also create a reference to strlib, so that the library string will
357** only be collected when registry.CLIBS is collected.
358*/
359static void addtoclib (lua_State *L, const char *path, void *plib) {
360 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
361 lua_pushlightuserdata(L, plib);
362 lua_setfield(L, -2, path); /* CLIBS[path] = plib */
363 createlibstr(L, plib);
364 luaL_ref(L, -2); /* keep library string in CLIBS */
365 lua_pop(L, 1); /* pop CLIBS table */
366}
367
351 368
352/* error codes for 'lookforfunc' */ 369/* error codes for 'lookforfunc' */
353#define ERRLIB 1 370#define ERRLIB 1
@@ -361,8 +378,8 @@ static int gctm (lua_State *L) {
361** Then, if 'sym' is '*', return true (as library has been loaded). 378** Then, if 'sym' is '*', return true (as library has been loaded).
362** Otherwise, look for symbol 'sym' in the library and push a 379** Otherwise, look for symbol 'sym' in the library and push a
363** C function with that symbol. 380** C function with that symbol.
364** Return 0 and 'true' or a function in the stack; in case of 381** Return 0 with 'true' or a function in the stack; in case of
365** errors, return an error code and an error message in the stack. 382** errors, return an error code with an error message in the stack.
366*/ 383*/
367static int lookforfunc (lua_State *L, const char *path, const char *sym) { 384static int lookforfunc (lua_State *L, const char *path, const char *sym) {
368 void *reg = checkclib(L, path); /* check loaded C libraries */ 385 void *reg = checkclib(L, path); /* check loaded C libraries */
@@ -704,21 +721,9 @@ static void createsearcherstable (lua_State *L) {
704} 721}
705 722
706 723
707/*
708** create table CLIBS to keep track of loaded C libraries,
709** setting a finalizer to close all libraries when closing state.
710*/
711static void createclibstable (lua_State *L) {
712 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
713 lua_createtable(L, 0, 1); /* create metatable for CLIBS */
714 lua_pushcfunction(L, gctm);
715 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
716 lua_setmetatable(L, -2);
717}
718
719
720LUAMOD_API int luaopen_package (lua_State *L) { 724LUAMOD_API int luaopen_package (lua_State *L) {
721 createclibstable(L); 725 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
726 lua_pop(L, 1); /* will not use it now */
722 luaL_newlib(L, pk_funcs); /* create 'package' table */ 727 luaL_newlib(L, pk_funcs); /* create 'package' table */
723 createsearcherstable(L); 728 createsearcherstable(L);
724 /* set paths */ 729 /* set paths */
diff --git a/lobject.c b/lobject.c
index 68566a2b..b558cfe0 100644
--- a/lobject.c
+++ b/lobject.c
@@ -31,7 +31,8 @@
31 31
32 32
33/* 33/*
34** Computes ceil(log2(x)) 34** Computes ceil(log2(x)), which is the smallest integer n such that
35** x <= (1 << n).
35*/ 36*/
36lu_byte luaO_ceillog2 (unsigned int x) { 37lu_byte luaO_ceillog2 (unsigned int x) {
37 static const lu_byte log_2[256] = { /* log_2[i - 1] = ceil(log2(i)) */ 38 static const lu_byte log_2[256] = { /* log_2[i - 1] = ceil(log2(i)) */
@@ -382,10 +383,10 @@ size_t luaO_str2num (const char *s, TValue *o) {
382} 383}
383 384
384 385
385int luaO_utf8esc (char *buff, unsigned long x) { 386int luaO_utf8esc (char *buff, l_uint32 x) {
386 int n = 1; /* number of bytes put in buffer (backwards) */ 387 int n = 1; /* number of bytes put in buffer (backwards) */
387 lua_assert(x <= 0x7FFFFFFFu); 388 lua_assert(x <= 0x7FFFFFFFu);
388 if (x < 0x80) /* ascii? */ 389 if (x < 0x80) /* ASCII? */
389 buff[UTF8BUFFSZ - 1] = cast_char(x); 390 buff[UTF8BUFFSZ - 1] = cast_char(x);
390 else { /* need continuation bytes */ 391 else { /* need continuation bytes */
391 unsigned int mfb = 0x3f; /* maximum that fits in first byte */ 392 unsigned int mfb = 0x3f; /* maximum that fits in first byte */
@@ -618,7 +619,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
618 } 619 }
619 case 'I': { /* a 'lua_Integer' */ 620 case 'I': { /* a 'lua_Integer' */
620 TValue num; 621 TValue num;
621 setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); 622 setivalue(&num, cast_Integer(va_arg(argp, l_uacInt)));
622 addnum2buff(&buff, &num); 623 addnum2buff(&buff, &num);
623 break; 624 break;
624 } 625 }
@@ -637,7 +638,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
637 } 638 }
638 case 'U': { /* an 'unsigned long' as a UTF-8 sequence */ 639 case 'U': { /* an 'unsigned long' as a UTF-8 sequence */
639 char bf[UTF8BUFFSZ]; 640 char bf[UTF8BUFFSZ];
640 int len = luaO_utf8esc(bf, va_arg(argp, unsigned long)); 641 unsigned long arg = va_arg(argp, unsigned long);
642 int len = luaO_utf8esc(bf, cast(l_uint32, arg));
641 addstr2buff(&buff, bf + UTF8BUFFSZ - len, cast_uint(len)); 643 addstr2buff(&buff, bf + UTF8BUFFSZ - len, cast_uint(len));
642 break; 644 break;
643 } 645 }
diff --git a/lobject.h b/lobject.h
index 8c06a224..cc3dd370 100644
--- a/lobject.h
+++ b/lobject.h
@@ -418,6 +418,7 @@ typedef struct TString {
418 418
419 419
420#define strisshr(ts) ((ts)->shrlen >= 0) 420#define strisshr(ts) ((ts)->shrlen >= 0)
421#define isextstr(ts) (ttislngstring(ts) && tsvalue(ts)->shrlen != LSTRREG)
421 422
422 423
423/* 424/*
@@ -822,7 +823,16 @@ typedef struct Table {
822/* size of buffer for 'luaO_utf8esc' function */ 823/* size of buffer for 'luaO_utf8esc' function */
823#define UTF8BUFFSZ 8 824#define UTF8BUFFSZ 8
824 825
825LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); 826
827/* macro to call 'luaO_pushvfstring' correctly */
828#define pushvfstring(L, argp, fmt, msg) \
829 { va_start(argp, fmt); \
830 msg = luaO_pushvfstring(L, fmt, argp); \
831 va_end(argp); \
832 if (msg == NULL) luaD_throw(L, LUA_ERRMEM); /* only after 'va_end' */ }
833
834
835LUAI_FUNC int luaO_utf8esc (char *buff, l_uint32 x);
826LUAI_FUNC lu_byte luaO_ceillog2 (unsigned int x); 836LUAI_FUNC lu_byte luaO_ceillog2 (unsigned int x);
827LUAI_FUNC lu_byte luaO_codeparam (unsigned int p); 837LUAI_FUNC lu_byte luaO_codeparam (unsigned int p);
828LUAI_FUNC l_mem luaO_applyparam (lu_byte p, l_mem x); 838LUAI_FUNC l_mem luaO_applyparam (lu_byte p, l_mem x);
diff --git a/lopcodes.h b/lopcodes.h
index 7511eb22..97870038 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -126,14 +126,14 @@ enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ};
126 126
127#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) 127#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
128#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 128#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
129 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) 129 ((cast_Inst(o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
130 130
131#define checkopm(i,m) (getOpMode(GET_OPCODE(i)) == m) 131#define checkopm(i,m) (getOpMode(GET_OPCODE(i)) == m)
132 132
133 133
134#define getarg(i,pos,size) (cast_int(((i)>>(pos)) & MASK1(size,0))) 134#define getarg(i,pos,size) (cast_int(((i)>>(pos)) & MASK1(size,0)))
135#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ 135#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
136 ((cast(Instruction, v)<<pos)&MASK1(size,pos)))) 136 ((cast_Inst(v)<<pos)&MASK1(size,pos))))
137 137
138#define GETARG_A(i) getarg(i, POS_A, SIZE_A) 138#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
139#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) 139#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
@@ -174,28 +174,28 @@ enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ};
174 setarg(i, cast_uint((j)+OFFSET_sJ), POS_sJ, SIZE_sJ) 174 setarg(i, cast_uint((j)+OFFSET_sJ), POS_sJ, SIZE_sJ)
175 175
176 176
177#define CREATE_ABCk(o,a,b,c,k) ((cast(Instruction, o)<<POS_OP) \ 177#define CREATE_ABCk(o,a,b,c,k) ((cast_Inst(o)<<POS_OP) \
178 | (cast(Instruction, a)<<POS_A) \ 178 | (cast_Inst(a)<<POS_A) \
179 | (cast(Instruction, b)<<POS_B) \ 179 | (cast_Inst(b)<<POS_B) \
180 | (cast(Instruction, c)<<POS_C) \ 180 | (cast_Inst(c)<<POS_C) \
181 | (cast(Instruction, k)<<POS_k)) 181 | (cast_Inst(k)<<POS_k))
182 182
183#define CREATE_vABCk(o,a,b,c,k) ((cast(Instruction, o)<<POS_OP) \ 183#define CREATE_vABCk(o,a,b,c,k) ((cast_Inst(o)<<POS_OP) \
184 | (cast(Instruction, a)<<POS_A) \ 184 | (cast_Inst(a)<<POS_A) \
185 | (cast(Instruction, b)<<POS_vB) \ 185 | (cast_Inst(b)<<POS_vB) \
186 | (cast(Instruction, c)<<POS_vC) \ 186 | (cast_Inst(c)<<POS_vC) \
187 | (cast(Instruction, k)<<POS_k)) 187 | (cast_Inst(k)<<POS_k))
188 188
189#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ 189#define CREATE_ABx(o,a,bc) ((cast_Inst(o)<<POS_OP) \
190 | (cast(Instruction, a)<<POS_A) \ 190 | (cast_Inst(a)<<POS_A) \
191 | (cast(Instruction, bc)<<POS_Bx)) 191 | (cast_Inst(bc)<<POS_Bx))
192 192
193#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \ 193#define CREATE_Ax(o,a) ((cast_Inst(o)<<POS_OP) \
194 | (cast(Instruction, a)<<POS_Ax)) 194 | (cast_Inst(a)<<POS_Ax))
195 195
196#define CREATE_sJ(o,j,k) ((cast(Instruction, o) << POS_OP) \ 196#define CREATE_sJ(o,j,k) ((cast_Inst(o) << POS_OP) \
197 | (cast(Instruction, j) << POS_sJ) \ 197 | (cast_Inst(j) << POS_sJ) \
198 | (cast(Instruction, k) << POS_k)) 198 | (cast_Inst(k) << POS_k))
199 199
200 200
201#if !defined(MAXINDEXRK) /* (for debugging only) */ 201#if !defined(MAXINDEXRK) /* (for debugging only) */
@@ -254,7 +254,7 @@ OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */
254OP_SETI,/* A B C R[A][B] := RK(C) */ 254OP_SETI,/* A B C R[A][B] := RK(C) */
255OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */ 255OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */
256 256
257OP_NEWTABLE,/* A B C k R[A] := {} */ 257OP_NEWTABLE,/* A vB vC k R[A] := {} */
258 258
259OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][K[C]:shortstring] */ 259OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][K[C]:shortstring] */
260 260
@@ -378,9 +378,9 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
378 real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the 378 real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the
379 bits of C). 379 bits of C).
380 380
381 (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a 381 (*) In OP_NEWTABLE, vB is log2 of the hash size (which is always a
382 power of 2) plus 1, or zero for size zero. If not k, the array size 382 power of 2) plus 1, or zero for size zero. If not k, the array size
383 is C. Otherwise, the array size is EXTRAARG _ C. 383 is vC. Otherwise, the array size is EXTRAARG _ vC.
384 384
385 (*) For comparisons, k specifies what condition the test should accept 385 (*) For comparisons, k specifies what condition the test should accept
386 (true or false). 386 (true or false).
diff --git a/loslib.c b/loslib.c
index 4623ad5e..3f605028 100644
--- a/loslib.c
+++ b/loslib.c
@@ -273,7 +273,7 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
273 273
274 274
275static const char *checkoption (lua_State *L, const char *conv, 275static const char *checkoption (lua_State *L, const char *conv,
276 ptrdiff_t convlen, char *buff) { 276 size_t convlen, char *buff) {
277 const char *option = LUA_STRFTIMEOPTIONS; 277 const char *option = LUA_STRFTIMEOPTIONS;
278 unsigned oplen = 1; /* length of options being checked */ 278 unsigned oplen = 1; /* length of options being checked */
279 for (; *option != '\0' && oplen <= convlen; option += oplen) { 279 for (; *option != '\0' && oplen <= convlen; option += oplen) {
@@ -333,7 +333,8 @@ static int os_date (lua_State *L) {
333 size_t reslen; 333 size_t reslen;
334 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); 334 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
335 s++; /* skip '%' */ 335 s++; /* skip '%' */
336 s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ 336 /* copy specifier to 'cc' */
337 s = checkoption(L, s, ct_diff2sz(se - s), cc + 1);
337 reslen = strftime(buff, SIZETIMEFMT, cc, stm); 338 reslen = strftime(buff, SIZETIMEFMT, cc, stm);
338 luaL_addsize(&b, reslen); 339 luaL_addsize(&b, reslen);
339 } 340 }
diff --git a/lparser.c b/lparser.c
index 380e45f5..dde0b6d5 100644
--- a/lparser.c
+++ b/lparser.c
@@ -30,8 +30,8 @@
30 30
31 31
32 32
33/* maximum number of local variables per function (must be smaller 33/* maximum number of variable declarations per function (must be
34 than 250, due to the bytecode format) */ 34 smaller than 250, due to the bytecode format) */
35#define MAXVARS 200 35#define MAXVARS 200
36 36
37 37
@@ -50,7 +50,7 @@ typedef struct BlockCnt {
50 struct BlockCnt *previous; /* chain */ 50 struct BlockCnt *previous; /* chain */
51 int firstlabel; /* index of first label in this block */ 51 int firstlabel; /* index of first label in this block */
52 int firstgoto; /* index of first pending goto in this block */ 52 int firstgoto; /* index of first pending goto in this block */
53 lu_byte nactvar; /* # active locals outside the block */ 53 short nactvar; /* number of active declarations at block entry */
54 lu_byte upval; /* true if some variable in the block is an upvalue */ 54 lu_byte upval; /* true if some variable in the block is an upvalue */
55 lu_byte isloop; /* 1 if 'block' is a loop; 2 if it has pending breaks */ 55 lu_byte isloop; /* 1 if 'block' is a loop; 2 if it has pending breaks */
56 lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ 56 lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */
@@ -188,18 +188,16 @@ static short registerlocalvar (LexState *ls, FuncState *fs,
188 188
189 189
190/* 190/*
191** Create a new local variable with the given 'name' and given 'kind'. 191** Create a new variable with the given 'name' and given 'kind'.
192** Return its index in the function. 192** Return its index in the function.
193*/ 193*/
194static int new_localvarkind (LexState *ls, TString *name, lu_byte kind) { 194static int new_varkind (LexState *ls, TString *name, lu_byte kind) {
195 lua_State *L = ls->L; 195 lua_State *L = ls->L;
196 FuncState *fs = ls->fs; 196 FuncState *fs = ls->fs;
197 Dyndata *dyd = ls->dyd; 197 Dyndata *dyd = ls->dyd;
198 Vardesc *var; 198 Vardesc *var;
199 luaY_checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
200 MAXVARS, "local variables");
201 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 199 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
202 dyd->actvar.size, Vardesc, SHRT_MAX, "local variables"); 200 dyd->actvar.size, Vardesc, SHRT_MAX, "variable declarations");
203 var = &dyd->actvar.arr[dyd->actvar.n++]; 201 var = &dyd->actvar.arr[dyd->actvar.n++];
204 var->vd.kind = kind; /* default */ 202 var->vd.kind = kind; /* default */
205 var->vd.name = name; 203 var->vd.name = name;
@@ -211,7 +209,7 @@ static int new_localvarkind (LexState *ls, TString *name, lu_byte kind) {
211** Create a new local variable with the given 'name' and regular kind. 209** Create a new local variable with the given 'name' and regular kind.
212*/ 210*/
213static int new_localvar (LexState *ls, TString *name) { 211static int new_localvar (LexState *ls, TString *name) {
214 return new_localvarkind(ls, name, VDKREG); 212 return new_varkind(ls, name, VDKREG);
215} 213}
216 214
217#define new_localvarliteral(ls,v) \ 215#define new_localvarliteral(ls,v) \
@@ -238,7 +236,7 @@ static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
238static lu_byte reglevel (FuncState *fs, int nvar) { 236static lu_byte reglevel (FuncState *fs, int nvar) {
239 while (nvar-- > 0) { 237 while (nvar-- > 0) {
240 Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ 238 Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */
241 if (vd->vd.kind != RDKCTC) /* is in a register? */ 239 if (varinreg(vd)) /* is in a register? */
242 return cast_byte(vd->vd.ridx + 1); 240 return cast_byte(vd->vd.ridx + 1);
243 } 241 }
244 return 0; /* no variables in registers */ 242 return 0; /* no variables in registers */
@@ -259,7 +257,7 @@ lu_byte luaY_nvarstack (FuncState *fs) {
259*/ 257*/
260static LocVar *localdebuginfo (FuncState *fs, int vidx) { 258static LocVar *localdebuginfo (FuncState *fs, int vidx) {
261 Vardesc *vd = getlocalvardesc(fs, vidx); 259 Vardesc *vd = getlocalvardesc(fs, vidx);
262 if (vd->vd.kind == RDKCTC) 260 if (!varinreg(vd))
263 return NULL; /* no debug info. for constants */ 261 return NULL; /* no debug info. for constants */
264 else { 262 else {
265 int idx = vd->vd.pidx; 263 int idx = vd->vd.pidx;
@@ -275,7 +273,7 @@ static LocVar *localdebuginfo (FuncState *fs, int vidx) {
275static void init_var (FuncState *fs, expdesc *e, int vidx) { 273static void init_var (FuncState *fs, expdesc *e, int vidx) {
276 e->f = e->t = NO_JUMP; 274 e->f = e->t = NO_JUMP;
277 e->k = VLOCAL; 275 e->k = VLOCAL;
278 e->u.var.vidx = cast(unsigned short, vidx); 276 e->u.var.vidx = cast_short(vidx);
279 e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; 277 e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx;
280} 278}
281 279
@@ -303,14 +301,18 @@ static void check_readonly (LexState *ls, expdesc *e) {
303 varname = up->name; 301 varname = up->name;
304 break; 302 break;
305 } 303 }
304 case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */
305 if (e->u.ind.ro) /* read-only? */
306 varname = tsvalue(&fs->f->k[e->u.ind.keystr]);
307 break;
308 }
306 default: 309 default:
307 return; /* other cases cannot be read-only */ 310 lua_assert(e->k == VINDEXI); /* this one doesn't need any check */
308 } 311 return; /* integer index cannot be read-only */
309 if (varname) {
310 const char *msg = luaO_pushfstring(ls->L,
311 "attempt to assign to const variable '%s'", getstr(varname));
312 luaK_semerror(ls, msg); /* error */
313 } 312 }
313 if (varname)
314 luaK_semerror(ls, "attempt to assign to const variable '%s'",
315 getstr(varname));
314} 316}
315 317
316 318
@@ -326,6 +328,7 @@ static void adjustlocalvars (LexState *ls, int nvars) {
326 Vardesc *var = getlocalvardesc(fs, vidx); 328 Vardesc *var = getlocalvardesc(fs, vidx);
327 var->vd.ridx = cast_byte(reglevel++); 329 var->vd.ridx = cast_byte(reglevel++);
328 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); 330 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
331 luaY_checklimit(fs, reglevel, MAXVARS, "local variables");
329 } 332 }
330} 333}
331 334
@@ -392,18 +395,38 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
392 395
393 396
394/* 397/*
395** Look for an active local variable with the name 'n' in the 398** Look for an active variable with the name 'n' in the
396** function 'fs'. If found, initialize 'var' with it and return 399** function 'fs'. If found, initialize 'var' with it and return
397** its expression kind; otherwise return -1. 400** its expression kind; otherwise return -1. While searching,
401** var->u.info==-1 means that the preambular global declaration is
402** active (the default while there is no other global declaration);
403** var->u.info==-2 means there is no active collective declaration
404** (some previous global declaration but no collective declaration);
405** and var->u.info>=0 points to the inner-most (the first one found)
406** collective declaration, if there is one.
398*/ 407*/
399static int searchvar (FuncState *fs, TString *n, expdesc *var) { 408static int searchvar (FuncState *fs, TString *n, expdesc *var) {
400 int i; 409 int i;
401 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 410 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
402 Vardesc *vd = getlocalvardesc(fs, i); 411 Vardesc *vd = getlocalvardesc(fs, i);
403 if (eqstr(n, vd->vd.name)) { /* found? */ 412 if (varglobal(vd)) { /* global declaration? */
413 if (vd->vd.name == NULL) { /* collective declaration? */
414 if (var->u.info < 0) /* no previous collective declaration? */
415 var->u.info = fs->firstlocal + i; /* this is the first one */
416 }
417 else { /* global name */
418 if (eqstr(n, vd->vd.name)) { /* found? */
419 init_exp(var, VGLOBAL, fs->firstlocal + i);
420 return VGLOBAL;
421 }
422 else if (var->u.info == -1) /* active preambular declaration? */
423 var->u.info = -2; /* invalidate preambular declaration */
424 }
425 }
426 else if (eqstr(n, vd->vd.name)) { /* found? */
404 if (vd->vd.kind == RDKCTC) /* compile-time constant? */ 427 if (vd->vd.kind == RDKCTC) /* compile-time constant? */
405 init_exp(var, VCONST, fs->firstlocal + i); 428 init_exp(var, VCONST, fs->firstlocal + i);
406 else /* real variable */ 429 else /* local variable */
407 init_var(fs, var, i); 430 init_var(fs, var, i);
408 return cast_int(var->k); 431 return cast_int(var->k);
409 } 432 }
@@ -442,48 +465,67 @@ static void marktobeclosed (FuncState *fs) {
442** 'var' as 'void' as a flag. 465** 'var' as 'void' as a flag.
443*/ 466*/
444static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 467static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
445 if (fs == NULL) /* no more levels? */ 468 int v = searchvar(fs, n, var); /* look up variables at current level */
446 init_exp(var, VVOID, 0); /* default is global */ 469 if (v >= 0) { /* found? */
447 else { 470 if (v == VLOCAL && !base)
448 int v = searchvar(fs, n, var); /* look up locals at current level */ 471 markupval(fs, var->u.var.vidx); /* local will be used as an upval */
449 if (v >= 0) { /* found? */ 472 }
450 if (v == VLOCAL && !base) 473 else { /* not found at current level; try upvalues */
451 markupval(fs, var->u.var.vidx); /* local will be used as an upval */ 474 int idx = searchupvalue(fs, n); /* try existing upvalues */
452 } 475 if (idx < 0) { /* not found? */
453 else { /* not found as local at current level; try upvalues */ 476 if (fs->prev != NULL) /* more levels? */
454 int idx = searchupvalue(fs, n); /* try existing upvalues */
455 if (idx < 0) { /* not found? */
456 singlevaraux(fs->prev, n, var, 0); /* try upper levels */ 477 singlevaraux(fs->prev, n, var, 0); /* try upper levels */
457 if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ 478 if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */
458 idx = newupvalue(fs, n, var); /* will be a new upvalue */ 479 idx = newupvalue(fs, n, var); /* will be a new upvalue */
459 else /* it is a global or a constant */ 480 else /* it is a global or a constant */
460 return; /* don't need to do anything at this level */ 481 return; /* don't need to do anything at this level */
461 }
462 init_exp(var, VUPVAL, idx); /* new or old upvalue */
463 } 482 }
483 init_exp(var, VUPVAL, idx); /* new or old upvalue */
464 } 484 }
465} 485}
466 486
467 487
488static void buildglobal (LexState *ls, TString *varname, expdesc *var) {
489 FuncState *fs = ls->fs;
490 expdesc key;
491 init_exp(var, VGLOBAL, -1); /* global by default */
492 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
493 if (var->k == VGLOBAL)
494 luaK_semerror(ls, "_ENV is global when accessing variable '%s'",
495 getstr(varname));
496 luaK_exp2anyregup(fs, var); /* _ENV could be a constant */
497 codestring(&key, varname); /* key is variable name */
498 luaK_indexed(fs, var, &key); /* 'var' represents _ENV[varname] */
499}
500
501
468/* 502/*
469** Find a variable with the given name 'n', handling global variables 503** Find a variable with the given name 'n', handling global variables
470** too. 504** too.
471*/ 505*/
472static void singlevar (LexState *ls, expdesc *var) { 506static void buildvar (LexState *ls, TString *varname, expdesc *var) {
473 TString *varname = str_checkname(ls);
474 FuncState *fs = ls->fs; 507 FuncState *fs = ls->fs;
508 init_exp(var, VGLOBAL, -1); /* global by default */
475 singlevaraux(fs, varname, var, 1); 509 singlevaraux(fs, varname, var, 1);
476 if (var->k == VVOID) { /* global name? */ 510 if (var->k == VGLOBAL) { /* global name? */
477 expdesc key; 511 int info = var->u.info;
478 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 512 /* global by default in the scope of a global declaration? */
479 lua_assert(var->k != VVOID); /* this one must exist */ 513 if (info == -2)
480 luaK_exp2anyregup(fs, var); /* but could be a constant */ 514 luaK_semerror(ls, "variable '%s' not declared", getstr(varname));
481 codestring(&key, varname); /* key is variable name */ 515 buildglobal(ls, varname, var);
482 luaK_indexed(fs, var, &key); /* env[varname] */ 516 if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST)
517 var->u.ind.ro = 1; /* mark variable as read-only */
518 else /* anyway must be a global */
519 lua_assert(info == -1 || ls->dyd->actvar.arr[info].vd.kind == GDKREG);
483 } 520 }
484} 521}
485 522
486 523
524static void singlevar (LexState *ls, expdesc *var) {
525 buildvar(ls, str_checkname(ls), var);
526}
527
528
487/* 529/*
488** Adjust the number of results from an expression list 'e' with 'nexps' 530** Adjust the number of results from an expression list 'e' with 'nexps'
489** expressions to 'nvars' values. 531** expressions to 'nvars' values.
@@ -518,14 +560,14 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
518 560
519/* 561/*
520** Generates an error that a goto jumps into the scope of some 562** Generates an error that a goto jumps into the scope of some
521** local variable. 563** variable declaration.
522*/ 564*/
523static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { 565static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
524 TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name; 566 TString *tsname = getlocalvardesc(ls->fs, gt->nactvar)->vd.name;
525 const char *varname = getstr(tsname); 567 const char *varname = (tsname != NULL) ? getstr(tsname) : "*";
526 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; 568 luaK_semerror(ls,
527 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); 569 "<goto %s> at line %d jumps into the scope of '%s'",
528 luaK_semerror(ls, msg); /* raise the error */ 570 getstr(gt->name), gt->line, varname); /* raise the error */
529} 571}
530 572
531 573
@@ -563,7 +605,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label, int bup) {
563 605
564/* 606/*
565** Search for an active label with the given name, starting at 607** Search for an active label with the given name, starting at
566** index 'ilb' (so that it can searh for all labels in current block 608** index 'ilb' (so that it can search for all labels in current block
567** or all labels in current function). 609** or all labels in current function).
568*/ 610*/
569static Labeldesc *findlabel (LexState *ls, TString *name, int ilb) { 611static Labeldesc *findlabel (LexState *ls, TString *name, int ilb) {
@@ -630,7 +672,7 @@ static void createlabel (LexState *ls, TString *name, int line, int last) {
630 672
631 673
632/* 674/*
633** Traverse the pending goto's of the finishing block checking whether 675** Traverse the pending gotos of the finishing block checking whether
634** each match some label of that block. Those that do not match are 676** each match some label of that block. Those that do not match are
635** "exported" to the outer block, to be solved there. In particular, 677** "exported" to the outer block, to be solved there. In particular,
636** its 'nactvar' is updated with the level of the inner block, 678** its 'nactvar' is updated with the level of the inner block,
@@ -666,8 +708,9 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
666 bl->firstlabel = fs->ls->dyd->label.n; 708 bl->firstlabel = fs->ls->dyd->label.n;
667 bl->firstgoto = fs->ls->dyd->gt.n; 709 bl->firstgoto = fs->ls->dyd->gt.n;
668 bl->upval = 0; 710 bl->upval = 0;
711 /* inherit 'insidetbc' from enclosing block */
669 bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); 712 bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc);
670 bl->previous = fs->bl; 713 bl->previous = fs->bl; /* link block in function's block list */
671 fs->bl = bl; 714 fs->bl = bl;
672 lua_assert(fs->freereg == luaY_nvarstack(fs)); 715 lua_assert(fs->freereg == luaY_nvarstack(fs));
673} 716}
@@ -677,11 +720,10 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
677** generates an error for an undefined 'goto'. 720** generates an error for an undefined 'goto'.
678*/ 721*/
679static l_noret undefgoto (LexState *ls, Labeldesc *gt) { 722static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
680 const char *msg = "no visible label '%s' for <goto> at line %d";
681 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
682 /* breaks are checked when created, cannot be undefined */ 723 /* breaks are checked when created, cannot be undefined */
683 lua_assert(!eqstr(gt->name, luaS_newliteral(ls->L, "break"))); 724 lua_assert(!eqstr(gt->name, ls->brkn));
684 luaK_semerror(ls, msg); 725 luaK_semerror(ls, "no visible label '%s' for <goto> at line %d",
726 getstr(gt->name), gt->line);
685} 727}
686 728
687 729
@@ -695,7 +737,7 @@ static void leaveblock (FuncState *fs) {
695 removevars(fs, bl->nactvar); /* remove block locals */ 737 removevars(fs, bl->nactvar); /* remove block locals */
696 lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */ 738 lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
697 if (bl->isloop == 2) /* has to fix pending breaks? */ 739 if (bl->isloop == 2) /* has to fix pending breaks? */
698 createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); 740 createlabel(ls, ls->brkn, 0, 0);
699 solvegotos(fs, bl); 741 solvegotos(fs, bl);
700 if (bl->previous == NULL) { /* was it the last block? */ 742 if (bl->previous == NULL) { /* was it the last block? */
701 if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */ 743 if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */
@@ -868,10 +910,8 @@ static void recfield (LexState *ls, ConsControl *cc) {
868 FuncState *fs = ls->fs; 910 FuncState *fs = ls->fs;
869 lu_byte reg = ls->fs->freereg; 911 lu_byte reg = ls->fs->freereg;
870 expdesc tab, key, val; 912 expdesc tab, key, val;
871 if (ls->t.token == TK_NAME) { 913 if (ls->t.token == TK_NAME)
872 luaY_checklimit(fs, cc->nh, INT_MAX / 2, "items in a constructor");
873 codename(ls, &key); 914 codename(ls, &key);
874 }
875 else /* ls->t.token == '[' */ 915 else /* ls->t.token == '[' */
876 yindex(ls, &key); 916 yindex(ls, &key);
877 cc->nh++; 917 cc->nh++;
@@ -1402,6 +1442,15 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1402 } 1442 }
1403} 1443}
1404 1444
1445
1446/* Create code to store the "top" register in 'var' */
1447static void storevartop (FuncState *fs, expdesc *var) {
1448 expdesc e;
1449 init_exp(&e, VNONRELOC, fs->freereg - 1);
1450 luaK_storevar(fs, var, &e); /* will also free the top register */
1451}
1452
1453
1405/* 1454/*
1406** Parse and compile a multiple assignment. The first "variable" 1455** Parse and compile a multiple assignment. The first "variable"
1407** (a 'suffixedexp') was already read by the caller. 1456** (a 'suffixedexp') was already read by the caller.
@@ -1435,8 +1484,7 @@ static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
1435 return; /* avoid default */ 1484 return; /* avoid default */
1436 } 1485 }
1437 } 1486 }
1438 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ 1487 storevartop(ls->fs, &lh->v); /* default assignment */
1439 luaK_storevar(ls->fs, &lh->v, &e);
1440} 1488}
1441 1489
1442 1490
@@ -1469,7 +1517,7 @@ static void breakstat (LexState *ls, int line) {
1469 ok: 1517 ok:
1470 bl->isloop = 2; /* signal that block has pending breaks */ 1518 bl->isloop = 2; /* signal that block has pending breaks */
1471 luaX_next(ls); /* skip break */ 1519 luaX_next(ls); /* skip break */
1472 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line); 1520 newgotoentry(ls, ls->brkn, line);
1473} 1521}
1474 1522
1475 1523
@@ -1479,11 +1527,9 @@ static void breakstat (LexState *ls, int line) {
1479*/ 1527*/
1480static void checkrepeated (LexState *ls, TString *name) { 1528static void checkrepeated (LexState *ls, TString *name) {
1481 Labeldesc *lb = findlabel(ls, name, ls->fs->firstlabel); 1529 Labeldesc *lb = findlabel(ls, name, ls->fs->firstlabel);
1482 if (l_unlikely(lb != NULL)) { /* already defined? */ 1530 if (l_unlikely(lb != NULL)) /* already defined? */
1483 const char *msg = "label '%s' already defined on line %d"; 1531 luaK_semerror(ls, "label '%s' already defined on line %d",
1484 msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); 1532 getstr(name), lb->line); /* error */
1485 luaK_semerror(ls, msg); /* error */
1486 }
1487} 1533}
1488 1534
1489 1535
@@ -1605,7 +1651,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1605 int base = fs->freereg; 1651 int base = fs->freereg;
1606 new_localvarliteral(ls, "(for state)"); 1652 new_localvarliteral(ls, "(for state)");
1607 new_localvarliteral(ls, "(for state)"); 1653 new_localvarliteral(ls, "(for state)");
1608 new_localvarkind(ls, varname, RDKCONST); /* control variable */ 1654 new_varkind(ls, varname, RDKCONST); /* control variable */
1609 checknext(ls, '='); 1655 checknext(ls, '=');
1610 exp1(ls); /* initial value */ 1656 exp1(ls); /* initial value */
1611 checknext(ls, ','); 1657 checknext(ls, ',');
@@ -1632,7 +1678,7 @@ static void forlist (LexState *ls, TString *indexname) {
1632 new_localvarliteral(ls, "(for state)"); /* iterator function */ 1678 new_localvarliteral(ls, "(for state)"); /* iterator function */
1633 new_localvarliteral(ls, "(for state)"); /* state */ 1679 new_localvarliteral(ls, "(for state)"); /* state */
1634 new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */ 1680 new_localvarliteral(ls, "(for state)"); /* closing var. (after swap) */
1635 new_localvarkind(ls, indexname, RDKCONST); /* control variable */ 1681 new_varkind(ls, indexname, RDKCONST); /* control variable */
1636 /* other declared variables */ 1682 /* other declared variables */
1637 while (testnext(ls, ',')) { 1683 while (testnext(ls, ',')) {
1638 new_localvar(ls, str_checkname(ls)); 1684 new_localvar(ls, str_checkname(ls));
@@ -1707,8 +1753,8 @@ static void localfunc (LexState *ls) {
1707} 1753}
1708 1754
1709 1755
1710static lu_byte getlocalattribute (LexState *ls) { 1756static lu_byte getvarattribute (LexState *ls, lu_byte df) {
1711 /* ATTRIB -> ['<' Name '>'] */ 1757 /* attrib -> ['<' NAME '>'] */
1712 if (testnext(ls, '<')) { 1758 if (testnext(ls, '<')) {
1713 TString *ts = str_checkname(ls); 1759 TString *ts = str_checkname(ls);
1714 const char *attr = getstr(ts); 1760 const char *attr = getstr(ts);
@@ -1718,10 +1764,9 @@ static lu_byte getlocalattribute (LexState *ls) {
1718 else if (strcmp(attr, "close") == 0) 1764 else if (strcmp(attr, "close") == 0)
1719 return RDKTOCLOSE; /* to-be-closed variable */ 1765 return RDKTOCLOSE; /* to-be-closed variable */
1720 else 1766 else
1721 luaK_semerror(ls, 1767 luaK_semerror(ls, "unknown attribute '%s'", attr);
1722 luaO_pushfstring(ls->L, "unknown attribute '%s'", attr));
1723 } 1768 }
1724 return VDKREG; /* regular variable */ 1769 return df; /* return default value */
1725} 1770}
1726 1771
1727 1772
@@ -1734,7 +1779,7 @@ static void checktoclose (FuncState *fs, int level) {
1734 1779
1735 1780
1736static void localstat (LexState *ls) { 1781static void localstat (LexState *ls) {
1737 /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ 1782 /* stat -> LOCAL NAME attrib { ',' NAME attrib } ['=' explist] */
1738 FuncState *fs = ls->fs; 1783 FuncState *fs = ls->fs;
1739 int toclose = -1; /* index of to-be-closed variable (if any) */ 1784 int toclose = -1; /* index of to-be-closed variable (if any) */
1740 Vardesc *var; /* last variable */ 1785 Vardesc *var; /* last variable */
@@ -1742,10 +1787,12 @@ static void localstat (LexState *ls) {
1742 int nvars = 0; 1787 int nvars = 0;
1743 int nexps; 1788 int nexps;
1744 expdesc e; 1789 expdesc e;
1745 do { 1790 /* get prefixed attribute (if any); default is regular local variable */
1746 TString *vname = str_checkname(ls); 1791 lu_byte defkind = getvarattribute(ls, VDKREG);
1747 lu_byte kind = getlocalattribute(ls); 1792 do { /* for each variable */
1748 vidx = new_localvarkind(ls, vname, kind); 1793 TString *vname = str_checkname(ls); /* get its name */
1794 lu_byte kind = getvarattribute(ls, defkind); /* postfixed attribute */
1795 vidx = new_varkind(ls, vname, kind); /* predeclare it */
1749 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1796 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1750 if (toclose != -1) /* one already present? */ 1797 if (toclose != -1) /* one already present? */
1751 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1798 luaK_semerror(ls, "multiple to-be-closed variables in local list");
@@ -1753,13 +1800,13 @@ static void localstat (LexState *ls) {
1753 } 1800 }
1754 nvars++; 1801 nvars++;
1755 } while (testnext(ls, ',')); 1802 } while (testnext(ls, ','));
1756 if (testnext(ls, '=')) 1803 if (testnext(ls, '=')) /* initialization? */
1757 nexps = explist(ls, &e); 1804 nexps = explist(ls, &e);
1758 else { 1805 else {
1759 e.k = VVOID; 1806 e.k = VVOID;
1760 nexps = 0; 1807 nexps = 0;
1761 } 1808 }
1762 var = getlocalvardesc(fs, vidx); /* get last variable */ 1809 var = getlocalvardesc(fs, vidx); /* retrieve last variable */
1763 if (nvars == nexps && /* no adjustments? */ 1810 if (nvars == nexps && /* no adjustments? */
1764 var->vd.kind == RDKCONST && /* last variable is const? */ 1811 var->vd.kind == RDKCONST && /* last variable is const? */
1765 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ 1812 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */
@@ -1775,6 +1822,86 @@ static void localstat (LexState *ls) {
1775} 1822}
1776 1823
1777 1824
1825static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
1826 lu_byte kind = getvarattribute(ls, df);
1827 switch (kind) {
1828 case RDKTOCLOSE:
1829 luaK_semerror(ls, "global variables cannot be to-be-closed");
1830 break; /* to avoid warnings */
1831 case RDKCONST:
1832 return GDKCONST; /* adjust kind for global variable */
1833 default:
1834 return kind;
1835 }
1836}
1837
1838
1839static void globalnames (LexState *ls, lu_byte defkind) {
1840 FuncState *fs = ls->fs;
1841 int nvars = 0;
1842 int lastidx; /* index of last registered variable */
1843 do { /* for each name */
1844 TString *vname = str_checkname(ls);
1845 lu_byte kind = getglobalattribute(ls, defkind);
1846 lastidx = new_varkind(ls, vname, kind);
1847 nvars++;
1848 } while (testnext(ls, ','));
1849 if (testnext(ls, '=')) { /* initialization? */
1850 expdesc e;
1851 int i;
1852 int nexps = explist(ls, &e); /* read list of expressions */
1853 adjust_assign(ls, nvars, nexps, &e);
1854 for (i = 0; i < nvars; i++) { /* for each variable */
1855 expdesc var;
1856 TString *varname = getlocalvardesc(fs, lastidx - i)->vd.name;
1857 buildglobal(ls, varname, &var); /* create global variable in 'var' */
1858 storevartop(fs, &var);
1859 }
1860 }
1861 fs->nactvar = cast_short(fs->nactvar + nvars); /* activate declaration */
1862}
1863
1864
1865static void globalstat (LexState *ls) {
1866 /* globalstat -> (GLOBAL) attrib '*'
1867 globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */
1868 FuncState *fs = ls->fs;
1869 /* get prefixed attribute (if any); default is regular global variable */
1870 lu_byte defkind = getglobalattribute(ls, GDKREG);
1871 if (!testnext(ls, '*'))
1872 globalnames(ls, defkind);
1873 else {
1874 /* use NULL as name to represent '*' entries */
1875 new_varkind(ls, NULL, defkind);
1876 fs->nactvar++; /* activate declaration */
1877 }
1878}
1879
1880
1881static void globalfunc (LexState *ls, int line) {
1882 /* globalfunc -> (GLOBAL FUNCTION) NAME body */
1883 expdesc var, b;
1884 FuncState *fs = ls->fs;
1885 TString *fname = str_checkname(ls);
1886 new_varkind(ls, fname, GDKREG); /* declare global variable */
1887 fs->nactvar++; /* enter its scope */
1888 buildglobal(ls, fname, &var);
1889 body(ls, &b, 0, ls->linenumber); /* compile and return closure in 'b' */
1890 luaK_storevar(fs, &var, &b);
1891 luaK_fixline(fs, line); /* definition "happens" in the first line */
1892}
1893
1894
1895static void globalstatfunc (LexState *ls, int line) {
1896 /* stat -> GLOBAL globalfunc | GLOBAL globalstat */
1897 luaX_next(ls); /* skip 'global' */
1898 if (testnext(ls, TK_FUNCTION))
1899 globalfunc(ls, line);
1900 else
1901 globalstat(ls);
1902}
1903
1904
1778static int funcname (LexState *ls, expdesc *v) { 1905static int funcname (LexState *ls, expdesc *v) {
1779 /* funcname -> NAME {fieldsel} [':' NAME] */ 1906 /* funcname -> NAME {fieldsel} [':' NAME] */
1780 int ismethod = 0; 1907 int ismethod = 0;
@@ -1795,8 +1922,8 @@ static void funcstat (LexState *ls, int line) {
1795 expdesc v, b; 1922 expdesc v, b;
1796 luaX_next(ls); /* skip FUNCTION */ 1923 luaX_next(ls); /* skip FUNCTION */
1797 ismethod = funcname(ls, &v); 1924 ismethod = funcname(ls, &v);
1798 body(ls, &b, ismethod, line);
1799 check_readonly(ls, &v); 1925 check_readonly(ls, &v);
1926 body(ls, &b, ismethod, line);
1800 luaK_storevar(ls->fs, &v, &b); 1927 luaK_storevar(ls->fs, &v, &b);
1801 luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ 1928 luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
1802} 1929}
@@ -1894,6 +2021,10 @@ static void statement (LexState *ls) {
1894 localstat(ls); 2021 localstat(ls);
1895 break; 2022 break;
1896 } 2023 }
2024 case TK_GLOBAL: { /* stat -> globalstatfunc */
2025 globalstatfunc(ls, line);
2026 break;
2027 }
1897 case TK_DBCOLON: { /* stat -> label */ 2028 case TK_DBCOLON: { /* stat -> label */
1898 luaX_next(ls); /* skip double colon */ 2029 luaX_next(ls); /* skip double colon */
1899 labelstat(ls, str_checkname(ls), line); 2030 labelstat(ls, str_checkname(ls), line);
@@ -1913,6 +2044,22 @@ static void statement (LexState *ls) {
1913 gotostat(ls, line); 2044 gotostat(ls, line);
1914 break; 2045 break;
1915 } 2046 }
2047#if defined(LUA_COMPAT_GLOBAL)
2048 case TK_NAME: {
2049 /* compatibility code to parse global keyword when "global"
2050 is not reserved */
2051 if (ls->t.seminfo.ts == ls->glbn) { /* current = "global"? */
2052 int lk = luaX_lookahead(ls);
2053 if (lk == '<' || lk == TK_NAME || lk == '*' || lk == TK_FUNCTION) {
2054 /* 'global <attrib>' or 'global name' or 'global *' or
2055 'global function' */
2056 globalstatfunc(ls, line);
2057 break;
2058 }
2059 } /* else... */
2060 }
2061#endif
2062 /* FALLTHROUGH */
1916 default: { /* stat -> func | assignment */ 2063 default: { /* stat -> func | assignment */
1917 exprstat(ls); 2064 exprstat(ls);
1918 break; 2065 break;
diff --git a/lparser.h b/lparser.h
index a3063569..fdbb9b8a 100644
--- a/lparser.h
+++ b/lparser.h
@@ -37,21 +37,27 @@ typedef enum {
37 info = result register */ 37 info = result register */
38 VLOCAL, /* local variable; var.ridx = register index; 38 VLOCAL, /* local variable; var.ridx = register index;
39 var.vidx = relative index in 'actvar.arr' */ 39 var.vidx = relative index in 'actvar.arr' */
40 VGLOBAL, /* global variable;
41 info = relative index in 'actvar.arr' (or -1 for
42 implicit declaration) */
40 VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 43 VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
41 VCONST, /* compile-time <const> variable; 44 VCONST, /* compile-time <const> variable;
42 info = absolute index in 'actvar.arr' */ 45 info = absolute index in 'actvar.arr' */
43 VINDEXED, /* indexed variable; 46 VINDEXED, /* indexed variable;
44 ind.t = table register; 47 ind.t = table register;
45 ind.idx = key's R index */ 48 ind.idx = key's R index;
49 ind.ro = true if it represents a read-only global;
50 ind.keystr = if key is a string, index in 'k' of that string;
51 -1 if key is not a string */
46 VINDEXUP, /* indexed upvalue; 52 VINDEXUP, /* indexed upvalue;
47 ind.t = table upvalue; 53 ind.idx = key's K index;
48 ind.idx = key's K index */ 54 ind.* as in VINDEXED */
49 VINDEXI, /* indexed variable with constant integer; 55 VINDEXI, /* indexed variable with constant integer;
50 ind.t = table register; 56 ind.t = table register;
51 ind.idx = key's value */ 57 ind.idx = key's value */
52 VINDEXSTR, /* indexed variable with literal string; 58 VINDEXSTR, /* indexed variable with literal string;
53 ind.t = table register; 59 ind.idx = key's K index;
54 ind.idx = key's K index */ 60 ind.* as in VINDEXED */
55 VJMP, /* expression is a test/comparison; 61 VJMP, /* expression is a test/comparison;
56 info = pc of corresponding jump instruction */ 62 info = pc of corresponding jump instruction */
57 VRELOC, /* expression can put result in any register; 63 VRELOC, /* expression can put result in any register;
@@ -75,10 +81,12 @@ typedef struct expdesc {
75 struct { /* for indexed variables */ 81 struct { /* for indexed variables */
76 short idx; /* index (R or "long" K) */ 82 short idx; /* index (R or "long" K) */
77 lu_byte t; /* table (register or upvalue) */ 83 lu_byte t; /* table (register or upvalue) */
84 lu_byte ro; /* true if variable is read-only */
85 int keystr; /* index in 'k' of string key, or -1 if not a string */
78 } ind; 86 } ind;
79 struct { /* for local variables */ 87 struct { /* for local variables */
80 lu_byte ridx; /* register holding the variable */ 88 lu_byte ridx; /* register holding the variable */
81 unsigned short vidx; /* compiler index (in 'actvar.arr') */ 89 short vidx; /* index in 'actvar.arr' */
82 } var; 90 } var;
83 } u; 91 } u;
84 int t; /* patch list of 'exit when true' */ 92 int t; /* patch list of 'exit when true' */
@@ -87,12 +95,21 @@ typedef struct expdesc {
87 95
88 96
89/* kinds of variables */ 97/* kinds of variables */
90#define VDKREG 0 /* regular */ 98#define VDKREG 0 /* regular local */
91#define RDKCONST 1 /* constant */ 99#define RDKCONST 1 /* local constant */
92#define RDKTOCLOSE 2 /* to-be-closed */ 100#define RDKTOCLOSE 2 /* to-be-closed */
93#define RDKCTC 3 /* compile-time constant */ 101#define RDKCTC 3 /* local compile-time constant */
102#define GDKREG 4 /* regular global */
103#define GDKCONST 5 /* global constant */
104
105/* variables that live in registers */
106#define varinreg(v) ((v)->vd.kind <= RDKTOCLOSE)
107
108/* test for global variables */
109#define varglobal(v) ((v)->vd.kind >= GDKREG)
110
94 111
95/* description of an active local variable */ 112/* description of an active variable */
96typedef union Vardesc { 113typedef union Vardesc {
97 struct { 114 struct {
98 TValuefields; /* constant value (if it is a compile-time constant) */ 115 TValuefields; /* constant value (if it is a compile-time constant) */
@@ -111,7 +128,7 @@ typedef struct Labeldesc {
111 TString *name; /* label identifier */ 128 TString *name; /* label identifier */
112 int pc; /* position in code */ 129 int pc; /* position in code */
113 int line; /* line where it appeared */ 130 int line; /* line where it appeared */
114 lu_byte nactvar; /* number of active variables in that position */ 131 short nactvar; /* number of active variables in that position */
115 lu_byte close; /* true for goto that escapes upvalues */ 132 lu_byte close; /* true for goto that escapes upvalues */
116} Labeldesc; 133} Labeldesc;
117 134
@@ -156,7 +173,7 @@ typedef struct FuncState {
156 int firstlocal; /* index of first local var (in Dyndata array) */ 173 int firstlocal; /* index of first local var (in Dyndata array) */
157 int firstlabel; /* index of first label (in 'dyd->label->arr') */ 174 int firstlabel; /* index of first label (in 'dyd->label->arr') */
158 short ndebugvars; /* number of elements in 'f->locvars' */ 175 short ndebugvars; /* number of elements in 'f->locvars' */
159 lu_byte nactvar; /* number of active local variables */ 176 short nactvar; /* number of active variable declarations */
160 lu_byte nups; /* number of upvalues */ 177 lu_byte nups; /* number of upvalues */
161 lu_byte freereg; /* first free register */ 178 lu_byte freereg; /* first free register */
162 lu_byte iwthabs; /* instructions issued since last absolute line info */ 179 lu_byte iwthabs; /* instructions issued since last absolute line info */
diff --git a/lstate.c b/lstate.c
index 20ed838f..70a11aae 100644
--- a/lstate.c
+++ b/lstate.c
@@ -326,6 +326,8 @@ LUA_API int lua_closethread (lua_State *L, lua_State *from) {
326 lua_lock(L); 326 lua_lock(L);
327 L->nCcalls = (from) ? getCcalls(from) : 0; 327 L->nCcalls = (from) ? getCcalls(from) : 0;
328 status = luaE_resetthread(L, L->status); 328 status = luaE_resetthread(L, L->status);
329 if (L == from) /* closing itself? */
330 luaD_throwbaselevel(L, status);
329 lua_unlock(L); 331 lua_unlock(L);
330 return APIstatus(status); 332 return APIstatus(status);
331} 333}
diff --git a/lstate.h b/lstate.h
index f841c232..80df3b0a 100644
--- a/lstate.h
+++ b/lstate.h
@@ -85,7 +85,7 @@ typedef struct CallInfo CallInfo;
85** they must be visited again at the end of the cycle), but they are 85** they must be visited again at the end of the cycle), but they are
86** marked black because assignments to them must activate barriers (to 86** marked black because assignments to them must activate barriers (to
87** move them back to TOUCHED1). 87** move them back to TOUCHED1).
88** - Open upvales are kept gray to avoid barriers, but they stay out 88** - Open upvalues are kept gray to avoid barriers, but they stay out
89** of gray lists. (They don't even have a 'gclist' field.) 89** of gray lists. (They don't even have a 'gclist' field.)
90*/ 90*/
91 91
@@ -232,7 +232,7 @@ struct CallInfo {
232/* call is running a C function (still in first 16 bits) */ 232/* call is running a C function (still in first 16 bits) */
233#define CIST_C (1u << (CIST_RECST + 3)) 233#define CIST_C (1u << (CIST_RECST + 3))
234/* call is on a fresh "luaV_execute" frame */ 234/* call is on a fresh "luaV_execute" frame */
235#define CIST_FRESH cast(l_uint32, CIST_C << 1) 235#define CIST_FRESH (cast(l_uint32, CIST_C) << 1)
236/* function is closing tbc variables */ 236/* function is closing tbc variables */
237#define CIST_CLSRET (CIST_FRESH << 1) 237#define CIST_CLSRET (CIST_FRESH << 1)
238/* function has tbc variables to close */ 238/* function has tbc variables to close */
diff --git a/lstring.c b/lstring.c
index b5c8f89f..17c6fd8f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -39,14 +39,14 @@
39 39
40 40
41/* 41/*
42** equality for long strings 42** generic equality for strings
43*/ 43*/
44int luaS_eqlngstr (TString *a, TString *b) { 44int luaS_eqstr (TString *a, TString *b) {
45 size_t len = a->u.lnglen; 45 size_t len1, len2;
46 lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); 46 const char *s1 = getlstr(a, len1);
47 return (a == b) || /* same instance or... */ 47 const char *s2 = getlstr(b, len2);
48 ((len == b->u.lnglen) && /* equal length and ... */ 48 return ((len1 == len2) && /* equal length and ... */
49 (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ 49 (memcmp(s1, s2, len1) == 0)); /* equal contents */
50} 50}
51 51
52 52
@@ -315,28 +315,9 @@ static void f_newext (lua_State *L, void *ud) {
315} 315}
316 316
317 317
318static void f_pintern (lua_State *L, void *ud) {
319 struct NewExt *ne = cast(struct NewExt *, ud);
320 ne->ts = internshrstr(L, ne->s, ne->len);
321}
322
323
324TString *luaS_newextlstr (lua_State *L, 318TString *luaS_newextlstr (lua_State *L,
325 const char *s, size_t len, lua_Alloc falloc, void *ud) { 319 const char *s, size_t len, lua_Alloc falloc, void *ud) {
326 struct NewExt ne; 320 struct NewExt ne;
327 if (len <= LUAI_MAXSHORTLEN) { /* short string? */
328 ne.s = s; ne.len = len;
329 if (!falloc)
330 f_pintern(L, &ne); /* just internalize string */
331 else {
332 TStatus status = luaD_rawrunprotected(L, f_pintern, &ne);
333 (*falloc)(ud, cast_voidp(s), len + 1, 0); /* free external string */
334 if (status != LUA_OK) /* memory error? */
335 luaM_error(L); /* re-raise memory error */
336 }
337 return ne.ts;
338 }
339 /* "normal" case: long strings */
340 if (!falloc) { 321 if (!falloc) {
341 ne.kind = LSTRFIX; 322 ne.kind = LSTRFIX;
342 f_newext(L, &ne); /* just create header */ 323 f_newext(L, &ne); /* just create header */
@@ -357,3 +338,16 @@ TString *luaS_newextlstr (lua_State *L,
357} 338}
358 339
359 340
341/*
342** Normalize an external string: If it is short, internalize it.
343*/
344TString *luaS_normstr (lua_State *L, TString *ts) {
345 size_t len = ts->u.lnglen;
346 if (len > LUAI_MAXSHORTLEN)
347 return ts; /* long string; keep the original */
348 else {
349 const char *str = getlngstr(ts);
350 return internshrstr(L, str, len);
351 }
352}
353
diff --git a/lstring.h b/lstring.h
index 1751e043..2eac222b 100644
--- a/lstring.h
+++ b/lstring.h
@@ -56,7 +56,7 @@
56 56
57LUAI_FUNC unsigned luaS_hash (const char *str, size_t l, unsigned seed); 57LUAI_FUNC unsigned luaS_hash (const char *str, size_t l, unsigned seed);
58LUAI_FUNC unsigned luaS_hashlongstr (TString *ts); 58LUAI_FUNC unsigned luaS_hashlongstr (TString *ts);
59LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 59LUAI_FUNC int luaS_eqstr (TString *a, TString *b);
60LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 60LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
61LUAI_FUNC void luaS_clearcache (global_State *g); 61LUAI_FUNC void luaS_clearcache (global_State *g);
62LUAI_FUNC void luaS_init (lua_State *L); 62LUAI_FUNC void luaS_init (lua_State *L);
@@ -69,5 +69,6 @@ LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
69LUAI_FUNC TString *luaS_newextlstr (lua_State *L, 69LUAI_FUNC TString *luaS_newextlstr (lua_State *L,
70 const char *s, size_t len, lua_Alloc falloc, void *ud); 70 const char *s, size_t len, lua_Alloc falloc, void *ud);
71LUAI_FUNC size_t luaS_sizelngstr (size_t len, int kind); 71LUAI_FUNC size_t luaS_sizelngstr (size_t len, int kind);
72LUAI_FUNC TString *luaS_normstr (lua_State *L, TString *ts);
72 73
73#endif 74#endif
diff --git a/lstrlib.c b/lstrlib.c
index 321d6a0b..d9735903 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -132,27 +132,31 @@ static int str_upper (lua_State *L) {
132} 132}
133 133
134 134
135/*
136** MAX_SIZE is limited both by size_t and lua_Integer.
137** When x <= MAX_SIZE, x can be safely cast to size_t or lua_Integer.
138*/
135static int str_rep (lua_State *L) { 139static int str_rep (lua_State *L) {
136 size_t l, lsep; 140 size_t len, lsep;
137 const char *s = luaL_checklstring(L, 1, &l); 141 const char *s = luaL_checklstring(L, 1, &len);
138 lua_Integer n = luaL_checkinteger(L, 2); 142 lua_Integer n = luaL_checkinteger(L, 2);
139 const char *sep = luaL_optlstring(L, 3, "", &lsep); 143 const char *sep = luaL_optlstring(L, 3, "", &lsep);
140 if (n <= 0) 144 if (n <= 0)
141 lua_pushliteral(L, ""); 145 lua_pushliteral(L, "");
142 else if (l_unlikely(l + lsep < l || l + lsep > MAX_SIZE / cast_sizet(n))) 146 else if (l_unlikely(len > MAX_SIZE - lsep ||
147 cast_st2S(len + lsep) > cast_st2S(MAX_SIZE) / n))
143 return luaL_error(L, "resulting string too large"); 148 return luaL_error(L, "resulting string too large");
144 else { 149 else {
145 size_t totallen = ((size_t)n * (l + lsep)) - lsep; 150 size_t totallen = (cast_sizet(n) * (len + lsep)) - lsep;
146 luaL_Buffer b; 151 luaL_Buffer b;
147 char *p = luaL_buffinitsize(L, &b, totallen); 152 char *p = luaL_buffinitsize(L, &b, totallen);
148 while (n-- > 1) { /* first n-1 copies (followed by separator) */ 153 while (n-- > 1) { /* first n-1 copies (followed by separator) */
149 memcpy(p, s, l * sizeof(char)); p += l; 154 memcpy(p, s, len * sizeof(char)); p += len;
150 if (lsep > 0) { /* empty 'memcpy' is not that cheap */ 155 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
151 memcpy(p, sep, lsep * sizeof(char)); 156 memcpy(p, sep, lsep * sizeof(char)); p += lsep;
152 p += lsep;
153 } 157 }
154 } 158 }
155 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ 159 memcpy(p, s, len * sizeof(char)); /* last copy without separator */
156 luaL_pushresultsize(&b, totallen); 160 luaL_pushresultsize(&b, totallen);
157 } 161 }
158 return 1; 162 return 1;
@@ -1544,8 +1548,10 @@ static KOption getdetails (Header *h, size_t totalsize, const char **fmt,
1544 else { 1548 else {
1545 if (align > h->maxalign) /* enforce maximum alignment */ 1549 if (align > h->maxalign) /* enforce maximum alignment */
1546 align = h->maxalign; 1550 align = h->maxalign;
1547 if (l_unlikely(!ispow2(align))) /* not a power of 2? */ 1551 if (l_unlikely(!ispow2(align))) { /* not a power of 2? */
1552 *ntoalign = 0; /* to avoid warnings */
1548 luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); 1553 luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1554 }
1549 else { 1555 else {
1550 /* 'szmoda' = totalsize % align */ 1556 /* 'szmoda' = totalsize % align */
1551 unsigned szmoda = cast_uint(totalsize & (align - 1)); 1557 unsigned szmoda = cast_uint(totalsize & (align - 1));
@@ -1809,8 +1815,8 @@ static int str_unpack (lua_State *L) {
1809 lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos, 1815 lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos,
1810 h.islittle, cast_int(size), 0); 1816 h.islittle, cast_int(size), 0);
1811 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); 1817 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
1812 lua_pushlstring(L, data + pos + size, len); 1818 lua_pushlstring(L, data + pos + size, cast_sizet(len));
1813 pos += len; /* skip string */ 1819 pos += cast_sizet(len); /* skip string */
1814 break; 1820 break;
1815 } 1821 }
1816 case Kzstr: { 1822 case Kzstr: {
diff --git a/ltable.c b/ltable.c
index 0b3ec176..4017d8c7 100644
--- a/ltable.c
+++ b/ltable.c
@@ -234,41 +234,51 @@ l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) {
234** Check whether key 'k1' is equal to the key in node 'n2'. This 234** Check whether key 'k1' is equal to the key in node 'n2'. This
235** equality is raw, so there are no metamethods. Floats with integer 235** equality is raw, so there are no metamethods. Floats with integer
236** values have been normalized, so integers cannot be equal to 236** values have been normalized, so integers cannot be equal to
237** floats. It is assumed that 'eqshrstr' is simply pointer equality, so 237** floats. It is assumed that 'eqshrstr' is simply pointer equality,
238** that short strings are handled in the default case. 238** so that short strings are handled in the default case. The flag
239** A true 'deadok' means to accept dead keys as equal to their original 239** 'deadok' means to accept dead keys as equal to their original values.
240** values. All dead keys are compared in the default case, by pointer 240** (Only collectable objects can produce dead keys.) Note that dead
241** identity. (Only collectable objects can produce dead keys.) Note that 241** long strings are also compared by identity. Once a key is dead,
242** dead long strings are also compared by identity. 242** its corresponding value may be collected, and then another value
243** Once a key is dead, its corresponding value may be collected, and 243** can be created with the same address. If this other value is given
244** then another value can be created with the same address. If this 244** to 'next', 'equalkey' will signal a false positive. In a regular
245** other value is given to 'next', 'equalkey' will signal a false 245** traversal, this situation should never happen, as all keys given to
246** positive. In a regular traversal, this situation should never happen, 246** 'next' came from the table itself, and therefore could not have been
247** as all keys given to 'next' came from the table itself, and therefore 247** collected. Outside a regular traversal, we have garbage in, garbage
248** could not have been collected. Outside a regular traversal, we 248** out. What is relevant is that this false positive does not break
249** have garbage in, garbage out. What is relevant is that this false 249** anything. (In particular, 'next' will return some other valid item
250** positive does not break anything. (In particular, 'next' will return 250** on the table or nil.)
251** some other valid item on the table or nil.)
252*/ 251*/
253static int equalkey (const TValue *k1, const Node *n2, int deadok) { 252static int equalkey (const TValue *k1, const Node *n2, int deadok) {
254 if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ 253 if (rawtt(k1) != keytt(n2)) { /* not the same variants? */
255 !(deadok && keyisdead(n2) && iscollectable(k1))) 254 if (keyisshrstr(n2) && ttislngstring(k1)) {
256 return 0; /* cannot be same key */ 255 /* an external string can be equal to a short-string key */
257 switch (keytt(n2)) { 256 return luaS_eqstr(tsvalue(k1), keystrval(n2));
258 case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: 257 }
259 return 1; 258 else if (deadok && keyisdead(n2) && iscollectable(k1)) {
260 case LUA_VNUMINT: 259 /* a collectable value can be equal to a dead key */
261 return (ivalue(k1) == keyival(n2));
262 case LUA_VNUMFLT:
263 return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
264 case LUA_VLIGHTUSERDATA:
265 return pvalue(k1) == pvalueraw(keyval(n2));
266 case LUA_VLCF:
267 return fvalue(k1) == fvalueraw(keyval(n2));
268 case ctb(LUA_VLNGSTR):
269 return luaS_eqlngstr(tsvalue(k1), keystrval(n2));
270 default:
271 return gcvalue(k1) == gcvalueraw(keyval(n2)); 260 return gcvalue(k1) == gcvalueraw(keyval(n2));
261 }
262 else
263 return 0; /* otherwise, different variants cannot be equal */
264 }
265 else { /* equal variants */
266 switch (keytt(n2)) {
267 case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
268 return 1;
269 case LUA_VNUMINT:
270 return (ivalue(k1) == keyival(n2));
271 case LUA_VNUMFLT:
272 return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
273 case LUA_VLIGHTUSERDATA:
274 return pvalue(k1) == pvalueraw(keyval(n2));
275 case LUA_VLCF:
276 return fvalue(k1) == fvalueraw(keyval(n2));
277 case ctb(LUA_VLNGSTR):
278 return luaS_eqstr(tsvalue(k1), keystrval(n2));
279 default:
280 return gcvalue(k1) == gcvalueraw(keyval(n2));
281 }
272 } 282 }
273} 283}
274 284
@@ -1158,6 +1168,14 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key,
1158 else if (l_unlikely(luai_numisnan(f))) 1168 else if (l_unlikely(luai_numisnan(f)))
1159 luaG_runerror(L, "table index is NaN"); 1169 luaG_runerror(L, "table index is NaN");
1160 } 1170 }
1171 else if (isextstr(key)) { /* external string? */
1172 /* If string is short, must internalize it to be used as table key */
1173 TString *ts = luaS_normstr(L, tsvalue(key));
1174 setsvalue2s(L, L->top.p++, ts); /* anchor 'ts' (EXTRA_STACK) */
1175 luaH_newkey(L, t, s2v(L->top.p - 1), value);
1176 L->top.p--;
1177 return;
1178 }
1161 luaH_newkey(L, t, key, value); 1179 luaH_newkey(L, t, key, value);
1162 } 1180 }
1163 else if (hres > 0) { /* regular Node? */ 1181 else if (hres > 0) { /* regular Node? */
@@ -1202,24 +1220,36 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
1202 1220
1203/* 1221/*
1204** Try to find a boundary in the hash part of table 't'. From the 1222** Try to find a boundary in the hash part of table 't'. From the
1205** caller, we know that 'j' is zero or present and that 'j + 1' is 1223** caller, we know that 'asize + 1' is present. We want to find a larger
1206** present. We want to find a larger key that is absent from the 1224** key that is absent from the table, so that we can do a binary search
1207** table, so that we can do a binary search between the two keys to 1225** between the two keys to find a boundary. We keep doubling 'j' until
1208** find a boundary. We keep doubling 'j' until we get an absent index. 1226** we get an absent index. If the doubling would overflow, we try
1209** If the doubling would overflow, we try LUA_MAXINTEGER. If it is 1227** LUA_MAXINTEGER. If it is absent, we are ready for the binary search.
1210** absent, we are ready for the binary search. ('j', being max integer, 1228** ('j', being max integer, is larger or equal to 'i', but it cannot be
1211** is larger or equal to 'i', but it cannot be equal because it is 1229** equal because it is absent while 'i' is present.) Otherwise, 'j' is a
1212** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a 1230** boundary. ('j + 1' cannot be a present integer key because it is not
1213** boundary. ('j + 1' cannot be a present integer key because it is 1231** a valid integer in Lua.)
1214** not a valid integer in Lua.) 1232** About 'rnd': If we used a fixed algorithm, a bad actor could fill
1233** a table with only the keys that would be probed, in such a way that
1234** a small table could result in a huge length. To avoid that, we use
1235** the state's seed as a source of randomness. For the first probe,
1236** we "randomly double" 'i' by adding to it a random number roughly its
1237** width.
1215*/ 1238*/
1216static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { 1239static lua_Unsigned hash_search (lua_State *L, Table *t, unsigned asize) {
1217 lua_Unsigned i; 1240 lua_Unsigned i = asize + 1; /* caller ensures t[i] is present */
1218 if (j == 0) j++; /* the caller ensures 'j + 1' is present */ 1241 unsigned rnd = G(L)->seed;
1219 do { 1242 int n = (asize > 0) ? luaO_ceillog2(asize) : 0; /* width of 'asize' */
1243 unsigned mask = (1u << n) - 1; /* 11...111 with the width of 'asize' */
1244 unsigned incr = (rnd & mask) + 1; /* first increment (at least 1) */
1245 lua_Unsigned j = (incr <= l_castS2U(LUA_MAXINTEGER) - i) ? i + incr : i + 1;
1246 rnd >>= n; /* used 'n' bits from 'rnd' */
1247 while (!hashkeyisempty(t, j)) { /* repeat until an absent t[j] */
1220 i = j; /* 'i' is a present index */ 1248 i = j; /* 'i' is a present index */
1221 if (j <= l_castS2U(LUA_MAXINTEGER) / 2) 1249 if (j <= l_castS2U(LUA_MAXINTEGER)/2 - 1) {
1222 j *= 2; 1250 j = j*2 + (rnd & 1); /* try again with 2j or 2j+1 */
1251 rnd >>= 1;
1252 }
1223 else { 1253 else {
1224 j = LUA_MAXINTEGER; 1254 j = LUA_MAXINTEGER;
1225 if (hashkeyisempty(t, j)) /* t[j] not present? */ 1255 if (hashkeyisempty(t, j)) /* t[j] not present? */
@@ -1227,7 +1257,7 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
1227 else /* weird case */ 1257 else /* weird case */
1228 return j; /* well, max integer is a boundary... */ 1258 return j; /* well, max integer is a boundary... */
1229 } 1259 }
1230 } while (!hashkeyisempty(t, j)); /* repeat until an absent t[j] */ 1260 }
1231 /* i < j && t[i] present && t[j] absent */ 1261 /* i < j && t[i] present && t[j] absent */
1232 while (j - i > 1u) { /* do a binary search between them */ 1262 while (j - i > 1u) { /* do a binary search between them */
1233 lua_Unsigned m = (i + j) / 2; 1263 lua_Unsigned m = (i + j) / 2;
@@ -1268,7 +1298,7 @@ static lua_Unsigned newhint (Table *t, unsigned hint) {
1268** If there is no array part, or its last element is non empty, the 1298** If there is no array part, or its last element is non empty, the
1269** border may be in the hash part. 1299** border may be in the hash part.
1270*/ 1300*/
1271lua_Unsigned luaH_getn (Table *t) { 1301lua_Unsigned luaH_getn (lua_State *L, Table *t) {
1272 unsigned asize = t->asize; 1302 unsigned asize = t->asize;
1273 if (asize > 0) { /* is there an array part? */ 1303 if (asize > 0) { /* is there an array part? */
1274 const unsigned maxvicinity = 4; 1304 const unsigned maxvicinity = 4;
@@ -1309,7 +1339,7 @@ lua_Unsigned luaH_getn (Table *t) {
1309 if (isdummy(t) || hashkeyisempty(t, asize + 1)) 1339 if (isdummy(t) || hashkeyisempty(t, asize + 1))
1310 return asize; /* 'asize + 1' is empty */ 1340 return asize; /* 'asize + 1' is empty */
1311 else /* 'asize + 1' is also non empty */ 1341 else /* 'asize + 1' is also non empty */
1312 return hash_search(t, asize); 1342 return hash_search(L, t, asize);
1313} 1343}
1314 1344
1315 1345
diff --git a/ltable.h b/ltable.h
index ca21e692..f3b7bc7e 100644
--- a/ltable.h
+++ b/ltable.h
@@ -173,7 +173,7 @@ LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned nasize);
173LUAI_FUNC lu_mem luaH_size (Table *t); 173LUAI_FUNC lu_mem luaH_size (Table *t);
174LUAI_FUNC void luaH_free (lua_State *L, Table *t); 174LUAI_FUNC void luaH_free (lua_State *L, Table *t);
175LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 175LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
176LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 176LUAI_FUNC lua_Unsigned luaH_getn (lua_State *L, Table *t);
177 177
178 178
179#if defined(LUA_DEBUG) 179#if defined(LUA_DEBUG)
diff --git a/ltests.c b/ltests.c
index 1517aa88..d92cd6c5 100644
--- a/ltests.c
+++ b/ltests.c
@@ -910,9 +910,9 @@ static int get_limits (lua_State *L) {
910 910
911static int mem_query (lua_State *L) { 911static int mem_query (lua_State *L) {
912 if (lua_isnone(L, 1)) { 912 if (lua_isnone(L, 1)) {
913 lua_pushinteger(L, cast(lua_Integer, l_memcontrol.total)); 913 lua_pushinteger(L, cast_Integer(l_memcontrol.total));
914 lua_pushinteger(L, cast(lua_Integer, l_memcontrol.numblocks)); 914 lua_pushinteger(L, cast_Integer(l_memcontrol.numblocks));
915 lua_pushinteger(L, cast(lua_Integer, l_memcontrol.maxmem)); 915 lua_pushinteger(L, cast_Integer(l_memcontrol.maxmem));
916 return 3; 916 return 3;
917 } 917 }
918 else if (lua_isnumber(L, 1)) { 918 else if (lua_isnumber(L, 1)) {
@@ -926,7 +926,7 @@ static int mem_query (lua_State *L) {
926 int i; 926 int i;
927 for (i = LUA_NUMTYPES - 1; i >= 0; i--) { 927 for (i = LUA_NUMTYPES - 1; i >= 0; i--) {
928 if (strcmp(t, ttypename(i)) == 0) { 928 if (strcmp(t, ttypename(i)) == 0) {
929 lua_pushinteger(L, cast(lua_Integer, l_memcontrol.objcount[i])); 929 lua_pushinteger(L, cast_Integer(l_memcontrol.objcount[i]));
930 return 1; 930 return 1;
931 } 931 }
932 } 932 }
@@ -1066,15 +1066,19 @@ static int tracegc (lua_State *L) {
1066 1066
1067static int hash_query (lua_State *L) { 1067static int hash_query (lua_State *L) {
1068 if (lua_isnone(L, 2)) { 1068 if (lua_isnone(L, 2)) {
1069 TString *ts;
1069 luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); 1070 luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
1070 lua_pushinteger(L, cast_int(tsvalue(obj_at(L, 1))->hash)); 1071 ts = tsvalue(obj_at(L, 1));
1072 if (ts->tt == LUA_VLNGSTR)
1073 luaS_hashlongstr(ts); /* make sure long string has a hash */
1074 lua_pushinteger(L, cast_int(ts->hash));
1071 } 1075 }
1072 else { 1076 else {
1073 TValue *o = obj_at(L, 1); 1077 TValue *o = obj_at(L, 1);
1074 Table *t; 1078 Table *t;
1075 luaL_checktype(L, 2, LUA_TTABLE); 1079 luaL_checktype(L, 2, LUA_TTABLE);
1076 t = hvalue(obj_at(L, 2)); 1080 t = hvalue(obj_at(L, 2));
1077 lua_pushinteger(L, cast(lua_Integer, luaH_mainposition(t, o) - t->node)); 1081 lua_pushinteger(L, cast_Integer(luaH_mainposition(t, o) - t->node));
1078 } 1082 }
1079 return 1; 1083 return 1;
1080} 1084}
@@ -1082,9 +1086,9 @@ static int hash_query (lua_State *L) {
1082 1086
1083static int stacklevel (lua_State *L) { 1087static int stacklevel (lua_State *L) {
1084 int a = 0; 1088 int a = 0;
1085 lua_pushinteger(L, cast(lua_Integer, L->top.p - L->stack.p)); 1089 lua_pushinteger(L, cast_Integer(L->top.p - L->stack.p));
1086 lua_pushinteger(L, stacksize(L)); 1090 lua_pushinteger(L, stacksize(L));
1087 lua_pushinteger(L, cast(lua_Integer, L->nCcalls)); 1091 lua_pushinteger(L, cast_Integer(L->nCcalls));
1088 lua_pushinteger(L, L->nci); 1092 lua_pushinteger(L, L->nci);
1089 lua_pushinteger(L, (lua_Integer)(size_t)&a); 1093 lua_pushinteger(L, (lua_Integer)(size_t)&a);
1090 return 5; 1094 return 5;
@@ -1099,9 +1103,9 @@ static int table_query (lua_State *L) {
1099 t = hvalue(obj_at(L, 1)); 1103 t = hvalue(obj_at(L, 1));
1100 asize = t->asize; 1104 asize = t->asize;
1101 if (i == -1) { 1105 if (i == -1) {
1102 lua_pushinteger(L, cast(lua_Integer, asize)); 1106 lua_pushinteger(L, cast_Integer(asize));
1103 lua_pushinteger(L, cast(lua_Integer, allocsizenode(t))); 1107 lua_pushinteger(L, cast_Integer(allocsizenode(t)));
1104 lua_pushinteger(L, cast(lua_Integer, asize > 0 ? *lenhint(t) : 0)); 1108 lua_pushinteger(L, cast_Integer(asize > 0 ? *lenhint(t) : 0));
1105 return 3; 1109 return 3;
1106 } 1110 }
1107 else if (cast_uint(i) < asize) { 1111 else if (cast_uint(i) < asize) {
@@ -1157,7 +1161,7 @@ static int test_codeparam (lua_State *L) {
1157static int test_applyparam (lua_State *L) { 1161static int test_applyparam (lua_State *L) {
1158 lua_Integer p = luaL_checkinteger(L, 1); 1162 lua_Integer p = luaL_checkinteger(L, 1);
1159 lua_Integer x = luaL_checkinteger(L, 2); 1163 lua_Integer x = luaL_checkinteger(L, 2);
1160 lua_pushinteger(L, cast(lua_Integer, luaO_applyparam(cast_byte(p), x))); 1164 lua_pushinteger(L, cast_Integer(luaO_applyparam(cast_byte(p), x)));
1161 return 1; 1165 return 1;
1162} 1166}
1163 1167
@@ -1257,7 +1261,7 @@ static int pushuserdata (lua_State *L) {
1257 1261
1258 1262
1259static int udataval (lua_State *L) { 1263static int udataval (lua_State *L) {
1260 lua_pushinteger(L, cast(lua_Integer, cast(size_t, lua_touserdata(L, 1)))); 1264 lua_pushinteger(L, cast_st2S(cast_sizet(lua_touserdata(L, 1))));
1261 return 1; 1265 return 1;
1262} 1266}
1263 1267
@@ -1294,7 +1298,7 @@ static int num2int (lua_State *L) {
1294 1298
1295 1299
1296static int makeseed (lua_State *L) { 1300static int makeseed (lua_State *L) {
1297 lua_pushinteger(L, cast(lua_Integer, luaL_makeseed(L))); 1301 lua_pushinteger(L, cast_Integer(luaL_makeseed(L)));
1298 return 1; 1302 return 1;
1299} 1303}
1300 1304
@@ -1638,7 +1642,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1638 } 1642 }
1639 else if EQ("func2num") { 1643 else if EQ("func2num") {
1640 lua_CFunction func = lua_tocfunction(L1, getindex); 1644 lua_CFunction func = lua_tocfunction(L1, getindex);
1641 lua_pushinteger(L1, cast(lua_Integer, cast(size_t, func))); 1645 lua_pushinteger(L1, cast_st2S(cast_sizet(func)));
1642 } 1646 }
1643 else if EQ("getfield") { 1647 else if EQ("getfield") {
1644 int t = getindex; 1648 int t = getindex;
@@ -2011,7 +2015,7 @@ static int Cfunc (lua_State *L) {
2011static int Cfunck (lua_State *L, int status, lua_KContext ctx) { 2015static int Cfunck (lua_State *L, int status, lua_KContext ctx) {
2012 lua_pushstring(L, statcodes[status]); 2016 lua_pushstring(L, statcodes[status]);
2013 lua_setglobal(L, "status"); 2017 lua_setglobal(L, "status");
2014 lua_pushinteger(L, cast(lua_Integer, ctx)); 2018 lua_pushinteger(L, cast_Integer(ctx));
2015 lua_setglobal(L, "ctx"); 2019 lua_setglobal(L, "ctx");
2016 return runC(L, L, lua_tostring(L, cast_int(ctx))); 2020 return runC(L, L, lua_tostring(L, cast_int(ctx)));
2017} 2021}
diff --git a/ltests.h b/ltests.h
index 7f0ce404..d34e9d42 100644
--- a/ltests.h
+++ b/ltests.h
@@ -14,6 +14,7 @@
14/* test Lua with compatibility code */ 14/* test Lua with compatibility code */
15#define LUA_COMPAT_MATHLIB 15#define LUA_COMPAT_MATHLIB
16#define LUA_COMPAT_LT_LE 16#define LUA_COMPAT_LT_LE
17#undef LUA_COMPAT_GLOBAL
17 18
18 19
19#define LUA_DEBUG 20#define LUA_DEBUG
@@ -154,7 +155,6 @@ LUA_API void *debug_realloc (void *ud, void *block,
154** Reduce maximum stack size to make stack-overflow tests run faster. 155** Reduce maximum stack size to make stack-overflow tests run faster.
155** (But value is still large enough to overflow smaller integers.) 156** (But value is still large enough to overflow smaller integers.)
156*/ 157*/
157#undef LUAI_MAXSTACK
158#define LUAI_MAXSTACK 68000 158#define LUAI_MAXSTACK 68000
159 159
160 160
diff --git a/lua.c b/lua.c
index b611cbca..b2967a44 100644
--- a/lua.c
+++ b/lua.c
@@ -303,7 +303,8 @@ static int collectargs (char **argv, int *first) {
303 case '-': /* '--' */ 303 case '-': /* '--' */
304 if (argv[i][2] != '\0') /* extra characters after '--'? */ 304 if (argv[i][2] != '\0') /* extra characters after '--'? */
305 return has_error; /* invalid option */ 305 return has_error; /* invalid option */
306 *first = i + 1; 306 /* if there is a script name, it comes after '--' */
307 *first = (argv[i + 1] != NULL) ? i + 1 : 0;
307 return args; 308 return args;
308 case '\0': /* '-' */ 309 case '\0': /* '-' */
309 return args; /* script "name" is '-' */ 310 return args; /* script "name" is '-' */
@@ -432,32 +433,41 @@ static int handle_luainit (lua_State *L) {
432 433
433 434
434/* 435/*
435** lua_readline defines how to show a prompt and then read a line from 436** * lua_initreadline initializes the readline system.
436** the standard input. 437** * lua_readline defines how to show a prompt and then read a line from
437** lua_saveline defines how to "save" a read line in a "history". 438** the standard input.
438** lua_freeline defines how to free a line read by lua_readline. 439** * lua_saveline defines how to "save" a read line in a "history".
440** * lua_freeline defines how to free a line read by lua_readline.
439*/ 441*/
440 442
441#if defined(LUA_USE_READLINE) 443#if !defined(lua_readline) /* { */
444/* Otherwise, all previously listed functions should be defined. */
445
446#if defined(LUA_USE_READLINE) /* { */
447/* Lua will be linked with '-lreadline' */
442 448
443#include <readline/readline.h> 449#include <readline/readline.h>
444#include <readline/history.h> 450#include <readline/history.h>
451
445#define lua_initreadline(L) ((void)L, rl_readline_name="lua") 452#define lua_initreadline(L) ((void)L, rl_readline_name="lua")
446#define lua_readline(b,p) ((void)b, readline(p)) 453#define lua_readline(buff,prompt) ((void)buff, readline(prompt))
447#define lua_saveline(line) add_history(line) 454#define lua_saveline(line) add_history(line)
448#define lua_freeline(b) free(b) 455#define lua_freeline(line) free(line)
449 456
450#endif 457#else /* }{ */
458/* use dynamically loaded readline (or nothing) */
451 459
460/* pointer to 'readline' function (if any) */
461typedef char *(*l_readlineT) (const char *prompt);
462static l_readlineT l_readline = NULL;
452 463
453#if !defined(lua_readline) /* { */ 464/* pointer to 'add_history' function (if any) */
465typedef void (*l_addhistT) (const char *string);
466static l_addhistT l_addhist = NULL;
454 467
455/* pointer to dynamically loaded 'readline' function (if any) */
456typedef char *(*l_readline_t) (const char *prompt);
457static l_readline_t l_readline = NULL;
458 468
459static char *lua_readline (char *buff, const char *prompt) { 469static char *lua_readline (char *buff, const char *prompt) {
460 if (l_readline != NULL) /* is there a dynamic 'readline'? */ 470 if (l_readline != NULL) /* is there a 'readline'? */
461 return (*l_readline)(prompt); /* use it */ 471 return (*l_readline)(prompt); /* use it */
462 else { /* emulate 'readline' over 'buff' */ 472 else { /* emulate 'readline' over 'buff' */
463 fputs(prompt, stdout); 473 fputs(prompt, stdout);
@@ -467,33 +477,25 @@ static char *lua_readline (char *buff, const char *prompt) {
467} 477}
468 478
469 479
470/* pointer to dynamically loaded 'add_history' function (if any) */
471typedef void (*l_addhist_t) (const char *string);
472static l_addhist_t l_addhist = NULL;
473
474static void lua_saveline (const char *line) { 480static void lua_saveline (const char *line) {
475 if (l_addhist != NULL) /* is there a dynamic 'add_history'? */ 481 if (l_addhist != NULL) /* is there an 'add_history'? */
476 (*l_addhist)(line); /* use it */ 482 (*l_addhist)(line); /* use it */
477 /* else nothing to be done */ 483 /* else nothing to be done */
478} 484}
479 485
480 486
481static void lua_freeline (char *line) { 487static void lua_freeline (char *line) {
482 if (l_readline != NULL) /* is there a dynamic 'readline'? */ 488 if (l_readline != NULL) /* is there a 'readline'? */
483 free(line); /* free line created by it */ 489 free(line); /* free line created by it */
484 /* else 'lua_readline' used an automatic buffer; nothing to free */ 490 /* else 'lua_readline' used an automatic buffer; nothing to free */
485} 491}
486 492
487 493
488#if !defined(LUA_USE_DLOPEN) || !defined(LUA_READLINELIB) 494#if defined(LUA_USE_DLOPEN) && defined(LUA_READLINELIB) /* { */
489 495/* try to load 'readline' dynamically */
490#define lua_initreadline(L) ((void)L)
491
492#else /* { */
493 496
494#include <dlfcn.h> 497#include <dlfcn.h>
495 498
496
497static void lua_initreadline (lua_State *L) { 499static void lua_initreadline (lua_State *L) {
498 void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL); 500 void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL);
499 if (lib == NULL) 501 if (lib == NULL)
@@ -501,16 +503,23 @@ static void lua_initreadline (lua_State *L) {
501 else { 503 else {
502 const char **name = cast(const char**, dlsym(lib, "rl_readline_name")); 504 const char **name = cast(const char**, dlsym(lib, "rl_readline_name"));
503 if (name != NULL) 505 if (name != NULL)
504 *name = "Lua"; 506 *name = "lua";
505 l_readline = cast(l_readline_t, cast_func(dlsym(lib, "readline"))); 507 l_readline = cast(l_readlineT, cast_func(dlsym(lib, "readline")));
508 l_addhist = cast(l_addhistT, cast_func(dlsym(lib, "add_history")));
506 if (l_readline == NULL) 509 if (l_readline == NULL)
507 lua_warning(L, "unable to load 'readline'", 0); 510 lua_warning(L, "unable to load 'readline'", 0);
508 else
509 l_addhist = cast(l_addhist_t, cast_func(dlsym(lib, "add_history")));
510 } 511 }
511} 512}
512 513
513#endif /* } */ 514#else /* }{ */
515/* no dlopen or LUA_READLINELIB undefined */
516
517/* Leave pointers with NULL */
518#define lua_initreadline(L) ((void)L)
519
520#endif /* } */
521
522#endif /* } */
514 523
515#endif /* } */ 524#endif /* } */
516 525
diff --git a/lua.h b/lua.h
index 95e0db32..131a8fcb 100644
--- a/lua.h
+++ b/lua.h
@@ -37,10 +37,10 @@
37 37
38/* 38/*
39** Pseudo-indices 39** Pseudo-indices
40** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty 40** (The stack size is limited to INT_MAX/2; we keep some free empty
41** space after that to help overflow detection) 41** space after that to help overflow detection.)
42*/ 42*/
43#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) 43#define LUA_REGISTRYINDEX (-(INT_MAX/2 + 1000))
44#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) 44#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
45 45
46 46
diff --git a/luaconf.h b/luaconf.h
index bd394650..0adc9c13 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -59,7 +59,7 @@
59 59
60 60
61/* 61/*
62** When Posix DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone 62** When POSIX DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone
63** application will try to dynamically link a 'readline' facility 63** application will try to dynamically link a 'readline' facility
64** for its REPL. In that case, LUA_READLINELIB is the name of the 64** for its REPL. In that case, LUA_READLINELIB is the name of the
65** library it will look for those facilities. If lua.c cannot open 65** library it will look for those facilities. If lua.c cannot open
@@ -76,7 +76,7 @@
76 76
77#if defined(LUA_USE_MACOSX) 77#if defined(LUA_USE_MACOSX)
78#define LUA_USE_POSIX 78#define LUA_USE_POSIX
79#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ 79#define LUA_USE_DLOPEN /* macOS does not need -ldl */
80#define LUA_READLINELIB "libedit.dylib" 80#define LUA_READLINELIB "libedit.dylib"
81#endif 81#endif
82 82
@@ -88,7 +88,7 @@
88 88
89 89
90#if defined(LUA_USE_C89) && defined(LUA_USE_POSIX) 90#if defined(LUA_USE_C89) && defined(LUA_USE_POSIX)
91#error "Posix is not compatible with C89" 91#error "POSIX is not compatible with C89"
92#endif 92#endif
93 93
94 94
@@ -356,6 +356,12 @@
356*/ 356*/
357 357
358/* 358/*
359@@ LUA_COMPAT_GLOBAL avoids 'global' being a reserved word
360*/
361#define LUA_COMPAT_GLOBAL
362
363
364/*
359@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. 365@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3.
360** You can define it to get all options, or change specific options 366** You can define it to get all options, or change specific options
361** to fit your specific needs. 367** to fit your specific needs.
@@ -758,20 +764,6 @@
758*/ 764*/
759 765
760/* 766/*
761@@ LUAI_MAXSTACK limits the size of the Lua stack.
762** CHANGE it if you need a different limit. This limit is arbitrary;
763** its only purpose is to stop Lua from consuming unlimited stack
764** space and to reserve some numbers for pseudo-indices.
765** (It must fit into max(int)/2.)
766*/
767#if 1000000 < (INT_MAX / 2)
768#define LUAI_MAXSTACK 1000000
769#else
770#define LUAI_MAXSTACK (INT_MAX / 2u)
771#endif
772
773
774/*
775@@ LUA_EXTRASPACE defines the size of a raw memory area associated with 767@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
776** a Lua state with very fast access. 768** a Lua state with very fast access.
777** CHANGE it if you need a different size. 769** CHANGE it if you need a different size.
diff --git a/lundump.c b/lundump.c
index d53bfc9a..76f0ddc1 100644
--- a/lundump.c
+++ b/lundump.c
@@ -37,7 +37,7 @@ typedef struct {
37 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */ 38 Table *h; /* list for string reuse */
39 size_t offset; /* current position relative to beginning of dump */ 39 size_t offset; /* current position relative to beginning of dump */
40 lua_Integer nstr; /* number of strings in the list */ 40 lua_Unsigned nstr; /* number of strings in the list */
41 lu_byte fixed; /* dump is fixed in memory */ 41 lu_byte fixed; /* dump is fixed in memory */
42} LoadState; 42} LoadState;
43 43
@@ -94,8 +94,8 @@ static lu_byte loadByte (LoadState *S) {
94} 94}
95 95
96 96
97static size_t loadVarint (LoadState *S, size_t limit) { 97static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
98 size_t x = 0; 98 lua_Unsigned x = 0;
99 int b; 99 int b;
100 limit >>= 7; 100 limit >>= 7;
101 do { 101 do {
@@ -109,7 +109,7 @@ static size_t loadVarint (LoadState *S, size_t limit) {
109 109
110 110
111static size_t loadSize (LoadState *S) { 111static size_t loadSize (LoadState *S) {
112 return loadVarint(S, MAX_SIZE); 112 return cast_sizet(loadVarint(S, MAX_SIZE));
113} 113}
114 114
115 115
@@ -127,9 +127,12 @@ static lua_Number loadNumber (LoadState *S) {
127 127
128 128
129static lua_Integer loadInteger (LoadState *S) { 129static lua_Integer loadInteger (LoadState *S) {
130 lua_Integer x; 130 lua_Unsigned cx = loadVarint(S, LUA_MAXUNSIGNED);
131 loadVar(S, x); 131 /* decode unsigned to signed */
132 return x; 132 if ((cx & 1) != 0)
133 return l_castU2S(~(cx >> 1));
134 else
135 return l_castU2S(cx >> 1);
133} 136}
134 137
135 138
@@ -149,10 +152,11 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
149 return; 152 return;
150 } 153 }
151 else if (size == 1) { /* previously saved string? */ 154 else if (size == 1) { /* previously saved string? */
152 lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */ 155 lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED); /* get its index */
153 TValue stv; 156 TValue stv;
154 luaH_getint(S->h, idx, &stv); /* get its value */ 157 if (novariant(luaH_getint(S->h, l_castU2S(idx), &stv)) != LUA_TSTRING)
155 *sl = ts = tsvalue(&stv); 158 error(S, "invalid string index");
159 *sl = ts = tsvalue(&stv); /* get its value */
156 luaC_objbarrier(L, p, ts); 160 luaC_objbarrier(L, p, ts);
157 return; /* do not save it again */ 161 return; /* do not save it again */
158 } 162 }
@@ -175,7 +179,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
175 /* add string to list of saved strings */ 179 /* add string to list of saved strings */
176 S->nstr++; 180 S->nstr++;
177 setsvalue(L, &sv, ts); 181 setsvalue(L, &sv, ts);
178 luaH_setint(L, S->h, S->nstr, &sv); 182 luaH_setint(L, S->h, l_castU2S(S->nstr), &sv);
179 luaC_objbarrierback(L, obj2gco(S->h), ts); 183 luaC_objbarrierback(L, obj2gco(S->h), ts);
180} 184}
181 185
@@ -234,7 +238,7 @@ static void loadConstants (LoadState *S, Proto *f) {
234 f->source = NULL; 238 f->source = NULL;
235 break; 239 break;
236 } 240 }
237 default: lua_assert(0); 241 default: error(S, "invalid constant");
238 } 242 }
239 } 243 }
240} 244}
@@ -391,11 +395,10 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
391 LoadState S; 395 LoadState S;
392 LClosure *cl; 396 LClosure *cl;
393 if (*name == '@' || *name == '=') 397 if (*name == '@' || *name == '=')
394 S.name = name + 1; 398 name = name + 1;
395 else if (*name == LUA_SIGNATURE[0]) 399 else if (*name == LUA_SIGNATURE[0])
396 S.name = "binary string"; 400 name = "binary string";
397 else 401 S.name = name;
398 S.name = name;
399 S.L = L; 402 S.L = L;
400 S.Z = Z; 403 S.Z = Z;
401 S.fixed = cast_byte(fixed); 404 S.fixed = cast_byte(fixed);
diff --git a/lutf8lib.c b/lutf8lib.c
index 4c9784e0..df49c901 100644
--- a/lutf8lib.c
+++ b/lutf8lib.c
@@ -47,7 +47,7 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
47** Decode one UTF-8 sequence, returning NULL if byte sequence is 47** Decode one UTF-8 sequence, returning NULL if byte sequence is
48** invalid. The array 'limits' stores the minimum value for each 48** invalid. The array 'limits' stores the minimum value for each
49** sequence length, to check for overlong representations. Its first 49** sequence length, to check for overlong representations. Its first
50** entry forces an error for non-ascii bytes with no continuation 50** entry forces an error for non-ASCII bytes with no continuation
51** bytes (count == 0). 51** bytes (count == 0).
52*/ 52*/
53static const char *utf8_decode (const char *s, l_uint32 *val, int strict) { 53static const char *utf8_decode (const char *s, l_uint32 *val, int strict) {
@@ -55,7 +55,7 @@ static const char *utf8_decode (const char *s, l_uint32 *val, int strict) {
55 {~(l_uint32)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; 55 {~(l_uint32)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u};
56 unsigned int c = (unsigned char)s[0]; 56 unsigned int c = (unsigned char)s[0];
57 l_uint32 res = 0; /* final result */ 57 l_uint32 res = 0; /* final result */
58 if (c < 0x80) /* ascii? */ 58 if (c < 0x80) /* ASCII? */
59 res = c; 59 res = c;
60 else { 60 else {
61 int count = 0; /* to count number of continuation bytes */ 61 int count = 0; /* to count number of continuation bytes */
@@ -215,9 +215,10 @@ static int byteoffset (lua_State *L) {
215 } 215 }
216 lua_pushinteger(L, posi + 1); /* initial position */ 216 lua_pushinteger(L, posi + 1); /* initial position */
217 if ((s[posi] & 0x80) != 0) { /* multi-byte character? */ 217 if ((s[posi] & 0x80) != 0) { /* multi-byte character? */
218 do { 218 if (iscont(s[posi]))
219 posi++; 219 return luaL_error(L, "initial position is a continuation byte");
220 } while (iscontp(s + posi + 1)); /* skip to final byte */ 220 while (iscontp(s + posi + 1))
221 posi++; /* skip to last continuation byte */
221 } 222 }
222 /* else one-byte character: final position is the initial one */ 223 /* else one-byte character: final position is the initial one */
223 lua_pushinteger(L, posi + 1); /* 'posi' now is the final position */ 224 lua_pushinteger(L, posi + 1); /* 'posi' now is the final position */
diff --git a/lvm.c b/lvm.c
index e2c36ef5..cfdcf97a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -327,7 +327,7 @@ lu_byte luaV_finishget (lua_State *L, const TValue *t, TValue *key,
327** Finish a table assignment 't[key] = val'. 327** Finish a table assignment 't[key] = val'.
328** About anchoring the table before the call to 'luaH_finishset': 328** About anchoring the table before the call to 'luaH_finishset':
329** This call may trigger an emergency collection. When loop>0, 329** This call may trigger an emergency collection. When loop>0,
330** the table being acessed is a field in some metatable. If this 330** the table being accessed is a field in some metatable. If this
331** metatable is weak and the table is not anchored, this collection 331** metatable is weak and the table is not anchored, this collection
332** could collect that table while it is being updated. 332** could collect that table while it is being updated.
333*/ 333*/
@@ -573,52 +573,74 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
573*/ 573*/
574int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { 574int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
575 const TValue *tm; 575 const TValue *tm;
576 if (ttypetag(t1) != ttypetag(t2)) { /* not the same variant? */ 576 if (ttype(t1) != ttype(t2)) /* not the same type? */
577 if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) 577 return 0;
578 return 0; /* only numbers can be equal with different variants */ 578 else if (ttypetag(t1) != ttypetag(t2)) {
579 else { /* two numbers with different variants */ 579 switch (ttypetag(t1)) {
580 /* One of them is an integer. If the other does not have an 580 case LUA_VNUMINT: { /* integer == float? */
581 integer value, they cannot be equal; otherwise, compare their 581 /* integer and float can only be equal if float has an integer
582 integer values. */ 582 value equal to the integer */
583 lua_Integer i1, i2; 583 lua_Integer i2;
584 return (luaV_tointegerns(t1, &i1, F2Ieq) && 584 return (luaV_flttointeger(fltvalue(t2), &i2, F2Ieq) &&
585 luaV_tointegerns(t2, &i2, F2Ieq) && 585 ivalue(t1) == i2);
586 i1 == i2); 586 }
587 case LUA_VNUMFLT: { /* float == integer? */
588 lua_Integer i1; /* see comment in previous case */
589 return (luaV_flttointeger(fltvalue(t1), &i1, F2Ieq) &&
590 i1 == ivalue(t2));
591 }
592 case LUA_VSHRSTR: case LUA_VLNGSTR: {
593 /* compare two strings with different variants: they can be
594 equal when one string is a short string and the other is
595 an external string */
596 return luaS_eqstr(tsvalue(t1), tsvalue(t2));
597 }
598 default:
599 /* only numbers (integer/float) and strings (long/short) can have
600 equal values with different variants */
601 return 0;
587 } 602 }
588 } 603 }
589 /* values have same type and same variant */ 604 else { /* equal variants */
590 switch (ttypetag(t1)) { 605 switch (ttypetag(t1)) {
591 case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1; 606 case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
592 case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2)); 607 return 1;
593 case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); 608 case LUA_VNUMINT:
594 case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); 609 return (ivalue(t1) == ivalue(t2));
595 case LUA_VLCF: return fvalue(t1) == fvalue(t2); 610 case LUA_VNUMFLT:
596 case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); 611 return (fltvalue(t1) == fltvalue(t2));
597 case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); 612 case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
598 case LUA_VUSERDATA: { 613 case LUA_VSHRSTR:
599 if (uvalue(t1) == uvalue(t2)) return 1; 614 return eqshrstr(tsvalue(t1), tsvalue(t2));
600 else if (L == NULL) return 0; 615 case LUA_VLNGSTR:
601 tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); 616 return luaS_eqstr(tsvalue(t1), tsvalue(t2));
602 if (tm == NULL) 617 case LUA_VUSERDATA: {
603 tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); 618 if (uvalue(t1) == uvalue(t2)) return 1;
604 break; /* will try TM */ 619 else if (L == NULL) return 0;
620 tm = fasttm(L, uvalue(t1)->metatable, TM_EQ);
621 if (tm == NULL)
622 tm = fasttm(L, uvalue(t2)->metatable, TM_EQ);
623 break; /* will try TM */
624 }
625 case LUA_VTABLE: {
626 if (hvalue(t1) == hvalue(t2)) return 1;
627 else if (L == NULL) return 0;
628 tm = fasttm(L, hvalue(t1)->metatable, TM_EQ);
629 if (tm == NULL)
630 tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
631 break; /* will try TM */
632 }
633 case LUA_VLCF:
634 return (fvalue(t1) == fvalue(t2));
635 default: /* functions and threads */
636 return (gcvalue(t1) == gcvalue(t2));
605 } 637 }
606 case LUA_VTABLE: { 638 if (tm == NULL) /* no TM? */
607 if (hvalue(t1) == hvalue(t2)) return 1; 639 return 0; /* objects are different */
608 else if (L == NULL) return 0; 640 else {
609 tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); 641 int tag = luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */
610 if (tm == NULL) 642 return !tagisfalse(tag);
611 tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
612 break; /* will try TM */
613 } 643 }
614 default:
615 return gcvalue(t1) == gcvalue(t2);
616 }
617 if (tm == NULL) /* no TM? */
618 return 0; /* objects are different */
619 else {
620 int tag = luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */
621 return !tagisfalse(tag);
622 } 644 }
623} 645}
624 646
@@ -700,7 +722,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
700 Table *h = hvalue(rb); 722 Table *h = hvalue(rb);
701 tm = fasttm(L, h->metatable, TM_LEN); 723 tm = fasttm(L, h->metatable, TM_LEN);
702 if (tm) break; /* metamethod? break switch to call it */ 724 if (tm) break; /* metamethod? break switch to call it */
703 setivalue(s2v(ra), l_castU2S(luaH_getn(h))); /* else primitive len */ 725 setivalue(s2v(ra), l_castU2S(luaH_getn(L, h))); /* else primitive len */
704 return; 726 return;
705 } 727 }
706 case LUA_VSHRSTR: { 728 case LUA_VSHRSTR: {
diff --git a/manual/2html b/manual/2html
index ac5ea043..b7afd2a6 100755
--- a/manual/2html
+++ b/manual/2html
@@ -8,11 +8,11 @@
8 8
9--------------------------------------------------------------- 9---------------------------------------------------------------
10header = [[ 10header = [[
11<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> 11<!DOCTYPE html>
12<html> 12<html>
13 13
14<head> 14<head>
15<title>Lua 5.4 Reference Manual</title> 15<title>Lua 5.5 Reference Manual</title>
16<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 16<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
17<link rel="stylesheet" href="lua.css"> 17<link rel="stylesheet" href="lua.css">
18<link rel="stylesheet" href="manual.css"> 18<link rel="stylesheet" href="manual.css">
@@ -23,7 +23,7 @@ header = [[
23<hr> 23<hr>
24<h1> 24<h1>
25<a href="http://www.lua.org/home.html"><img src="logo.gif" alt="[Lua logo]" border="0"></a> 25<a href="http://www.lua.org/home.html"><img src="logo.gif" alt="[Lua logo]" border="0"></a>
26Lua 5.4 Reference Manual 26Lua 5.5 Reference Manual
27</h1> 27</h1>
28 28
29by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 29by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
diff --git a/manual/manual.of b/manual/manual.of
index 7cd0d4db..b2765774 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -213,11 +213,89 @@ of a given value @seeF{type}.
213 213
214} 214}
215 215
216@sect2{globalenv| @title{Environments and the Global Environment} 216@sect2{globalenv| @title{Scopes, Variables, and Environments}
217@index{visibility}
218
219A variable name refers to a global or a local variable according
220to the declaration that is in context at that point of the code.
221(For the purposes of this discussion,
222a function's formal parameter is equivalent to a local variable.)
223
224All chunks start with an implicit declaration @T{global *},
225which declares all free names as global variables;
226this preambular declaration becomes void inside the scope of any other
227@Rw{global} declaration,
228as the following example illustrates:
229@verbatim{
230X = 1 -- Ok, global by default
231do
232 global Y -- voids the implicit initial declaration
233 Y = 1 -- Ok, Y declared as global
234 X = 1 -- ERROR, X not declared
235end
236X = 2 -- Ok, global by default again
237}
238So, outside any global declaration,
239Lua works as @x{global-by-default}.
240Inside any global declaration,
241Lua works without a default:
242All variables must be declared.
243
244Lua is a lexically scoped language.
245The scope of a variable declaration begins at the first statement after
246the declaration and lasts until the last non-void statement
247of the innermost block that includes the declaration.
248(@emph{Void statements} are labels and empty statements.)
249
250A declaration shadows any declaration for the same name that
251is in context at the point of the declaration. Inside this
252shadow, any outer declaration for that name is void.
253See the next example:
254@verbatim{
255global print, x
256x = 10 -- global variable
257do -- new block
258 local x = x -- new 'x', with value 10
259 print(x) --> 10
260 x = x+1
261 do -- another block
262 local x = x+1 -- another 'x'
263 print(x) --> 12
264 end
265 print(x) --> 11
266end
267print(x) --> 10 (the global one)
268}
269
270Notice that, in a declaration like @T{local x = x},
271the new @id{x} being declared is not in scope yet,
272and so the @id{x} in the right-hand side refers to the outside variable.
273
274Because of the @x{lexical scoping} rules,
275local variables can be freely accessed by functions
276defined inside their scope.
277A local variable used by an inner function is called an @def{upvalue}
278(or @emphx{external local variable}, or simply @emphx{external variable})
279inside the inner function.
280
281Notice that each execution of a @Rw{local} statement
282defines new local variables.
283Consider the following example:
284@verbatim{
285a = {}
286local x = 20
287for i = 1, 10 do
288 local y = 0
289 a[i] = function () y = y + 1; return x + y end
290end
291}
292The loop creates ten closures
293(that is, ten instances of the anonymous function).
294Each of these closures uses a different @id{y} variable,
295while all of them share the same @id{x}.
217 296
218As we will discuss further in @refsec{variables} and @refsec{assignment}, 297As we will discuss further in @refsec{variables} and @refsec{assignment},
219any reference to a free name 298any reference to a global variable @id{var}
220(that is, a name not bound to any declaration) @id{var}
221is syntactically translated to @T{_ENV.var}. 299is syntactically translated to @T{_ENV.var}.
222Moreover, every chunk is compiled in the scope of 300Moreover, every chunk is compiled in the scope of
223an external local variable named @id{_ENV} @see{chunks}, 301an external local variable named @id{_ENV} @see{chunks},
@@ -225,12 +303,14 @@ so @id{_ENV} itself is never a free name in a chunk.
225 303
226Despite the existence of this external @id{_ENV} variable and 304Despite the existence of this external @id{_ENV} variable and
227the translation of free names, 305the translation of free names,
228@id{_ENV} is a completely regular name. 306@id{_ENV} is a regular name.
229In particular, 307In particular,
230you can define new variables and parameters with that name. 308you can define new variables and parameters with that name.
231Each reference to a free name uses the @id{_ENV} that is 309(However, you should not define @id{_ENV} as a global variable,
232visible at that point in the program, 310otherwise @T{_ENV.var} would translate to
233following the usual visibility rules of Lua @see{visibility}. 311@T{_ENV._ENV.var} and so on, in an infinite loop.)
312Each reference to a global variable name uses the @id{_ENV} that is
313visible at that point in the program.
234 314
235Any table used as the value of @id{_ENV} is called an @def{environment}. 315Any table used as the value of @id{_ENV} is called an @def{environment}.
236 316
@@ -244,8 +324,8 @@ When Lua loads a chunk,
244the default value for its @id{_ENV} variable 324the default value for its @id{_ENV} variable
245is the global environment @seeF{load}. 325is the global environment @seeF{load}.
246Therefore, by default, 326Therefore, by default,
247free names in Lua code refer to entries in the global environment 327global variables in Lua code refer to entries in the global environment
248and, therefore, they are also called @def{global variables}. 328and, therefore, they act as conventional global variables.
249Moreover, all standard libraries are loaded in the global environment 329Moreover, all standard libraries are loaded in the global environment
250and some functions there operate on that environment. 330and some functions there operate on that environment.
251You can use @Lid{load} (or @Lid{loadfile}) 331You can use @Lid{load} (or @Lid{loadfile})
@@ -1031,9 +1111,9 @@ and cannot be used as names:
1031@index{reserved words} 1111@index{reserved words}
1032@verbatim{ 1112@verbatim{
1033and break do else elseif end 1113and break do else elseif end
1034false for function goto if in 1114false for function global goto if
1035local nil not or repeat return 1115in local nil not or repeat
1036then true until while 1116return then true until while
1037} 1117}
1038 1118
1039Lua is a case-sensitive language: 1119Lua is a case-sensitive language:
@@ -1198,17 +1278,15 @@ global variables, local variables, and table fields.
1198 1278
1199A single name can denote a global variable or a local variable 1279A single name can denote a global variable or a local variable
1200(or a function's formal parameter, 1280(or a function's formal parameter,
1201which is a particular kind of local variable): 1281which is a particular kind of local variable) @see{globalenv}:
1202@Produc{ 1282@Produc{
1203@producname{var}@producbody{@bnfNter{Name}} 1283@producname{var}@producbody{@bnfNter{Name}}
1204} 1284}
1205@bnfNter{Name} denotes identifiers @see{lexical}. 1285@bnfNter{Name} denotes identifiers @see{lexical}.
1206 1286
1207Any variable name is assumed to be global unless explicitly declared 1287Because variables are @emph{lexically scoped},
1208as a local @see{localvar}.
1209@x{Local variables} are @emph{lexically scoped}:
1210local variables can be freely accessed by functions 1288local variables can be freely accessed by functions
1211defined inside their scope @see{visibility}. 1289defined inside their scope @see{globalenv}.
1212 1290
1213Before the first assignment to a variable, its value is @nil. 1291Before the first assignment to a variable, its value is @nil.
1214 1292
@@ -1227,8 +1305,6 @@ The syntax @id{var.Name} is just syntactic sugar for
1227 1305
1228An access to a global variable @id{x} 1306An access to a global variable @id{x}
1229is equivalent to @id{_ENV.x}. 1307is equivalent to @id{_ENV.x}.
1230Due to the way that chunks are compiled,
1231the variable @id{_ENV} itself is never global @see{globalenv}.
1232 1308
1233} 1309}
1234 1310
@@ -1326,6 +1402,8 @@ Chunks can also be precompiled into binary form;
1326see the program @idx{luac} and the function @Lid{string.dump} for details. 1402see the program @idx{luac} and the function @Lid{string.dump} for details.
1327Programs in source and compiled forms are interchangeable; 1403Programs in source and compiled forms are interchangeable;
1328Lua automatically detects the file type and acts accordingly @seeF{load}. 1404Lua automatically detects the file type and acts accordingly @seeF{load}.
1405Be aware that, unlike source code,
1406maliciously crafted binary chunks can crash the interpreter.
1329 1407
1330} 1408}
1331 1409
@@ -1428,7 +1506,7 @@ labels in Lua are considered statements too:
1428A label is visible in the entire block where it is defined, 1506A label is visible in the entire block where it is defined,
1429except inside nested functions. 1507except inside nested functions.
1430A goto can jump to any visible label as long as it does not 1508A goto can jump to any visible label as long as it does not
1431enter into the scope of a local variable. 1509enter into the scope of a variable declaration.
1432A label should not be declared 1510A label should not be declared
1433where a previous label with the same name is visible, 1511where a previous label with the same name is visible,
1434even if this other label has been declared in an enclosing block. 1512even if this other label has been declared in an enclosing block.
@@ -1571,35 +1649,85 @@ Function calls are explained in @See{functioncall}.
1571 1649
1572} 1650}
1573 1651
1574@sect3{localvar| @title{Local Declarations} 1652@sect3{localvar| @title{Variable Declarations}
1575@x{Local variables} can be declared anywhere inside a block. 1653Local and global variables can be declared anywhere inside a block.
1576The declaration can include an initialization: 1654The declaration can include an initialization:
1577@Produc{ 1655@Produc{
1578@producname{stat}@producbody{@Rw{local} attnamelist @bnfopt{@bnfter{=} explist}} 1656@producname{stat}@producbody{@Rw{local}
1579@producname{attnamelist}@producbody{ 1657 attnamelist @bnfopt{@bnfter{=} explist}}
1580 @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} 1658@producname{stat}@producbody{@Rw{global}
1659 attnamelist @bnfopt{@bnfter{=} explist}}
1581} 1660}
1582If present, an initial assignment has the same semantics 1661If present, an initial assignment has the same semantics
1583of a multiple assignment @see{assignment}. 1662of a multiple assignment @see{assignment}.
1584Otherwise, all variables are initialized with @nil. 1663Otherwise, all local variables are initialized with @nil.
1585 1664
1586Each variable name may be postfixed by an attribute 1665The list of names may be prefixed by an attribute
1587(a name between angle brackets): 1666(a name between angle brackets)
1667and each variable name may be postfixed by an attribute:
1588@Produc{ 1668@Produc{
1589@producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}} 1669@producname{attnamelist}@producbody{
1670 @bnfopt{attrib} @bnfNter{Name} @bnfopt{attrib}
1671 @bnfrep{@bnfter{,} @bnfNter{Name} @bnfopt{attrib}}}
1672@producname{attrib}@producbody{@bnfter{<} @bnfNter{Name} @bnfter{>}}
1590} 1673}
1674A prefixed attribute applies to all names in the list;
1675a postfixed attribute applies to its particular name.
1591There are two possible attributes: 1676There are two possible attributes:
1592@id{const}, which declares a @emph{constant} or @emph{read-only} variable, 1677@id{const}, which declares a @emph{constant} or @emph{read-only} variable,
1593@index{constant variable} 1678@index{constant variable}
1594that is, a variable that cannot be assigned to 1679that is, a variable that cannot be used as the left-hand side of an
1595after its initialization; 1680assignment,
1596and @id{close}, which declares a to-be-closed variable @see{to-be-closed}. 1681and @id{close}, which declares a to-be-closed variable @see{to-be-closed}.
1682Only local variables can have the @id{close} attribute.
1597A list of variables can contain at most one to-be-closed variable. 1683A list of variables can contain at most one to-be-closed variable.
1598 1684
1685Lua offers also a collective declaration for global variables:
1686@Produc{
1687@producname{stat}@producbody{@Rw{global} @bnfopt{attrib} @bnfter{*}}
1688}
1689This special form implicitly declares
1690as globals all names not explicitly declared previously.
1691In particular,
1692@T{global<const> *} implicitly declares
1693as read-only globals all names not explicitly declared previously;
1694see the following example:
1695@verbatim{
1696global X
1697global<const> *
1698print(math.pi) -- Ok, 'print' and 'math' are read-only
1699X = 1 -- Ok, declared as read-write
1700Y = 1 -- Error, Y is read-only
1701}
1702
1703As noted in @See{globalenv},
1704all chunks start with an implicit declaration @T{global *},
1705but this preambular declaration becomes void inside
1706the scope of any other @Rw{global} declaration.
1707Therefore, a program that does not use global declarations
1708or start with @T{global *}
1709has free read-write access to any global;
1710a program that starts with @T{global<const> *}
1711has free read-only access to any global;
1712and a program that starts with any other global declaration
1713(e.g., @T{global none}) can only refer to declared variables.
1714
1715Note that, for global variables,
1716the effect of any declaration is only syntactical
1717(except for the optional assignment):
1718@verbatim{
1719global X <const>, _G
1720X = 1 -- ERROR
1721_ENV.X = 1 -- Ok
1722_G.print(X) -- Ok
1723foo() -- 'foo' can freely change any global
1724}
1725
1599A chunk is also a block @see{chunks}, 1726A chunk is also a block @see{chunks},
1600and so local variables can be declared in a chunk outside any explicit block. 1727and so variables can be declared in a chunk outside any explicit block.
1601 1728
1602The visibility rules for local variables are explained in @See{visibility}. 1729The visibility rules for variable declarations
1730are explained in @See{globalenv}.
1603 1731
1604} 1732}
1605 1733
@@ -2142,6 +2270,7 @@ The following syntactic sugar simplifies function definitions:
2142@Produc{ 2270@Produc{
2143@producname{stat}@producbody{@Rw{function} funcname funcbody} 2271@producname{stat}@producbody{@Rw{function} funcname funcbody}
2144@producname{stat}@producbody{@Rw{local} @Rw{function} @bnfNter{Name} funcbody} 2272@producname{stat}@producbody{@Rw{local} @Rw{function} @bnfNter{Name} funcbody}
2273@producname{stat}@producbody{@Rw{global} @Rw{function} @bnfNter{Name} funcbody}
2145@producname{funcname}@producbody{@bnfNter{Name} @bnfrep{@bnfter{.} @bnfNter{Name}} @bnfopt{@bnfter{:} @bnfNter{Name}}} 2274@producname{funcname}@producbody{@bnfNter{Name} @bnfrep{@bnfter{.} @bnfNter{Name}} @bnfopt{@bnfter{:} @bnfNter{Name}}}
2146} 2275}
2147The statement 2276The statement
@@ -2160,6 +2289,7 @@ translates to
2160@verbatim{ 2289@verbatim{
2161t.a.b.c.f = function () @rep{body} end 2290t.a.b.c.f = function () @rep{body} end
2162} 2291}
2292
2163The statement 2293The statement
2164@verbatim{ 2294@verbatim{
2165local function f () @rep{body} end 2295local function f () @rep{body} end
@@ -2173,7 +2303,15 @@ not to
2173local f = function () @rep{body} end 2303local f = function () @rep{body} end
2174} 2304}
2175(This only makes a difference when the body of the function 2305(This only makes a difference when the body of the function
2176contains references to @id{f}.) 2306contains recursive references to @id{f}.)
2307Similarly, the statement
2308@verbatim{
2309global function f () @rep{body} end
2310}
2311translates to
2312@verbatim{
2313global f; f = function () @rep{body} end
2314}
2177 2315
2178A function definition is an executable expression, 2316A function definition is an executable expression,
2179whose value has type @emph{function}. 2317whose value has type @emph{function}.
@@ -2236,7 +2374,7 @@ then the function returns with no results.
2236@index{multiple return} 2374@index{multiple return}
2237There is a system-dependent limit on the number of values 2375There is a system-dependent limit on the number of values
2238that a function may return. 2376that a function may return.
2239This limit is guaranteed to be greater than 1000. 2377This limit is guaranteed to be at least 1000.
2240 2378
2241The @emphx{colon} syntax 2379The @emphx{colon} syntax
2242is used to emulate @def{methods}, 2380is used to emulate @def{methods},
@@ -2281,8 +2419,8 @@ for instance @T{foo(e1, e2, e3)} @see{functioncall}.}
2281@item{A multiple assignment, 2419@item{A multiple assignment,
2282for instance @T{a , b, c = e1, e2, e3} @see{assignment}.} 2420for instance @T{a , b, c = e1, e2, e3} @see{assignment}.}
2283 2421
2284@item{A local declaration, 2422@item{A local or global declaration,
2285for instance @T{local a , b, c = e1, e2, e3} @see{localvar}.} 2423which is a special case of multiple assignment.}
2286 2424
2287@item{The initial values in a generic @rw{for} loop, 2425@item{The initial values in a generic @rw{for} loop,
2288for instance @T{for k in e1, e2, e3 do ... end} @see{for}.} 2426for instance @T{for k in e1, e2, e3 do ... end} @see{for}.}
@@ -2293,8 +2431,7 @@ the list of values from the list of expressions
2293must be @emph{adjusted} to a specific length: 2431must be @emph{adjusted} to a specific length:
2294the number of parameters in a call to a non-variadic function 2432the number of parameters in a call to a non-variadic function
2295@see{func-def}, 2433@see{func-def},
2296the number of variables in a multiple assignment or 2434the number of variables in a multiple assignment or a declaration,
2297a local declaration,
2298and exactly four values for a generic @rw{for} loop. 2435and exactly four values for a generic @rw{for} loop.
2299The @def{adjustment} follows these rules: 2436The @def{adjustment} follows these rules:
2300If there are more values than needed, 2437If there are more values than needed,
@@ -2356,58 +2493,6 @@ return x,y,f() -- returns x, y, and all results from f().
2356 2493
2357} 2494}
2358 2495
2359@sect2{visibility| @title{Visibility Rules}
2360
2361@index{visibility}
2362Lua is a lexically scoped language.
2363The scope of a local variable begins at the first statement after
2364its declaration and lasts until the last non-void statement
2365of the innermost block that includes the declaration.
2366(@emph{Void statements} are labels and empty statements.)
2367Consider the following example:
2368@verbatim{
2369x = 10 -- global variable
2370do -- new block
2371 local x = x -- new 'x', with value 10
2372 print(x) --> 10
2373 x = x+1
2374 do -- another block
2375 local x = x+1 -- another 'x'
2376 print(x) --> 12
2377 end
2378 print(x) --> 11
2379end
2380print(x) --> 10 (the global one)
2381}
2382
2383Notice that, in a declaration like @T{local x = x},
2384the new @id{x} being declared is not in scope yet,
2385and so the second @id{x} refers to the outside variable.
2386
2387Because of the @x{lexical scoping} rules,
2388local variables can be freely accessed by functions
2389defined inside their scope.
2390A local variable used by an inner function is called an @def{upvalue}
2391(or @emphx{external local variable}, or simply @emphx{external variable})
2392inside the inner function.
2393
2394Notice that each execution of a @Rw{local} statement
2395defines new local variables.
2396Consider the following example:
2397@verbatim{
2398a = {}
2399local x = 20
2400for i = 1, 10 do
2401 local y = 0
2402 a[i] = function () y = y + 1; return x + y end
2403end
2404}
2405The loop creates ten closures
2406(that is, ten instances of the anonymous function).
2407Each of these closures uses a different @id{y} variable,
2408while all of them share the same @id{x}.
2409
2410}
2411 2496
2412} 2497}
2413 2498
@@ -3182,17 +3267,25 @@ when called through this function.
3182 3267
3183Resets a thread, cleaning its call stack and closing all pending 3268Resets a thread, cleaning its call stack and closing all pending
3184to-be-closed variables. 3269to-be-closed variables.
3185Returns a status code: 3270The parameter @id{from} represents the coroutine that is resetting @id{L}.
3271If there is no such coroutine,
3272this parameter can be @id{NULL}.
3273
3274Unless @id{L} is equal to @id{from},
3275the call returns a status code:
3186@Lid{LUA_OK} for no errors in the thread 3276@Lid{LUA_OK} for no errors in the thread
3187(either the original error that stopped the thread or 3277(either the original error that stopped the thread or
3188errors in closing methods), 3278errors in closing methods),
3189or an error status otherwise. 3279or an error status otherwise.
3190In case of error, 3280In case of error,
3191leaves the error object on the top of the stack. 3281the error object is put on the top of the stack.
3192 3282
3193The parameter @id{from} represents the coroutine that is resetting @id{L}. 3283If @id{L} is equal to @id{from},
3194If there is no such coroutine, 3284it corresponds to a thread closing itself.
3195this parameter can be @id{NULL}. 3285In that case,
3286the call does not return;
3287instead, the resume that (re)started the thread returns.
3288The thread must be running inside a resume.
3196 3289
3197} 3290}
3198 3291
@@ -3832,8 +3925,8 @@ This macro may evaluate its arguments more than once.
3832 3925
3833} 3926}
3834 3927
3835@APIEntry{unsigned (lua_numbertocstring) (lua_State *L, int idx, 3928@APIEntry{unsigned lua_numbertocstring (lua_State *L, int idx,
3836 char *buff);| 3929 char *buff);|
3837@apii{0,0,-} 3930@apii{0,0,-}
3838 3931
3839Converts the number at acceptable index @id{idx} to a string 3932Converts the number at acceptable index @id{idx} to a string
@@ -3958,7 +4051,7 @@ This function is equivalent to @Lid{lua_pushcclosure} with no upvalues.
3958 4051
3959} 4052}
3960 4053
3961@APIEntry{const char *(lua_pushexternalstring) (lua_State *L, 4054@APIEntry{const char *lua_pushexternalstring (lua_State *L,
3962 const char *s, size_t len, lua_Alloc falloc, void *ud);| 4055 const char *s, size_t len, lua_Alloc falloc, void *ud);|
3963@apii{0,1,m} 4056@apii{0,1,m}
3964 4057
@@ -3981,11 +4074,6 @@ the string @id{s} as the block,
3981the length plus one (to account for the ending zero) as the old size, 4074the length plus one (to account for the ending zero) as the old size,
3982and 0 as the new size. 4075and 0 as the new size.
3983 4076
3984Lua always @x{internalizes} strings with lengths up to 40 characters.
3985So, for strings in that range,
3986this function will immediately internalize the string
3987and call @id{falloc} to free the buffer.
3988
3989Even when using an external buffer, 4077Even when using an external buffer,
3990Lua still has to allocate a header for the string. 4078Lua still has to allocate a header for the string.
3991In case of a memory-allocation error, 4079In case of a memory-allocation error,
@@ -6601,11 +6689,10 @@ It may be the string @St{b} (only @x{binary chunk}s),
6601or @St{bt} (both binary and text). 6689or @St{bt} (both binary and text).
6602The default is @St{bt}. 6690The default is @St{bt}.
6603 6691
6604It is safe to load malformed binary chunks; 6692Lua does not check the consistency of binary chunks.
6605@id{load} signals an appropriate error. 6693Maliciously crafted binary chunks can crash
6606However, 6694the interpreter.
6607Lua does not check the consistency of the code inside binary chunks; 6695You can use the @id{mode} parameter to prevent loading binary chunks.
6608running maliciously crafted bytecode can crash the interpreter.
6609 6696
6610} 6697}
6611 6698
@@ -6817,7 +6904,7 @@ and @St{userdata}.
6817 6904
6818A global variable (not a function) that 6905A global variable (not a function) that
6819holds a string containing the running Lua version. 6906holds a string containing the running Lua version.
6820The current value of this variable is @St{Lua 5.4}. 6907The current value of this variable is @St{Lua 5.5}.
6821 6908
6822} 6909}
6823 6910
@@ -6854,18 +6941,26 @@ which come inside the table @defid{coroutine}.
6854See @See{coroutine} for a general description of coroutines. 6941See @See{coroutine} for a general description of coroutines.
6855 6942
6856 6943
6857@LibEntry{coroutine.close (co)| 6944@LibEntry{coroutine.close ([co])|
6858 6945
6859Closes coroutine @id{co}, 6946Closes coroutine @id{co},
6860that is, 6947that is,
6861closes all its pending to-be-closed variables 6948closes all its pending to-be-closed variables
6862and puts the coroutine in a dead state. 6949and puts the coroutine in a dead state.
6863The given coroutine must be dead or suspended. 6950The default for @id{co} is the running coroutine.
6864In case of error 6951
6952The given coroutine must be dead, suspended,
6953or be the running coroutine.
6954For the running coroutine,
6955this function does not return.
6956Instead, the resume that (re)started the coroutine returns.
6957
6958For other coroutines,
6959in case of error
6865(either the original error that stopped the coroutine or 6960(either the original error that stopped the coroutine or
6866errors in closing methods), 6961errors in closing methods),
6867returns @false plus the error object; 6962this function returns @false plus the error object;
6868otherwise returns @true. 6963otherwise ir returns @true.
6869 6964
6870} 6965}
6871 6966
@@ -7055,7 +7150,7 @@ to search for a @N{C loader}.
7055 7150
7056Lua initializes the @N{C path} @Lid{package.cpath} in the same way 7151Lua initializes the @N{C path} @Lid{package.cpath} in the same way
7057it initializes the Lua path @Lid{package.path}, 7152it initializes the Lua path @Lid{package.path},
7058using the environment variable @defid{LUA_CPATH_5_4}, 7153using the environment variable @defid{LUA_CPATH_5_5},
7059or the environment variable @defid{LUA_CPATH}, 7154or the environment variable @defid{LUA_CPATH},
7060or a default path defined in @id{luaconf.h}. 7155or a default path defined in @id{luaconf.h}.
7061 7156
@@ -7124,7 +7219,7 @@ A string with the path used by @Lid{require}
7124to search for a Lua loader. 7219to search for a Lua loader.
7125 7220
7126At start-up, Lua initializes this variable with 7221At start-up, Lua initializes this variable with
7127the value of the environment variable @defid{LUA_PATH_5_4} or 7222the value of the environment variable @defid{LUA_PATH_5_5} or
7128the environment variable @defid{LUA_PATH} or 7223the environment variable @defid{LUA_PATH} or
7129with a default path defined in @id{luaconf.h}, 7224with a default path defined in @id{luaconf.h},
7130if those environment variables are not defined. 7225if those environment variables are not defined.
@@ -7495,9 +7590,9 @@ x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
7495 end) 7590 end)
7496-- x="4+5 = 9" 7591-- x="4+5 = 9"
7497 7592
7498local t = {name="lua", version="5.4"} 7593local t = {name="lua", version="5.5"}
7499x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) 7594x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
7500-- x="lua-5.4.tar.gz" 7595-- x="lua-5.5.tar.gz"
7501} 7596}
7502 7597
7503} 7598}
@@ -9233,7 +9328,7 @@ when the standard input (@id{stdin}) is a terminal,
9233and as @T{lua -} otherwise. 9328and as @T{lua -} otherwise.
9234 9329
9235When called without the option @T{-E}, 9330When called without the option @T{-E},
9236the interpreter checks for an environment variable @defid{LUA_INIT_5_4} 9331the interpreter checks for an environment variable @defid{LUA_INIT_5_5}
9237(or @defid{LUA_INIT} if the versioned name is not defined) 9332(or @defid{LUA_INIT} if the versioned name is not defined)
9238before running any argument. 9333before running any argument.
9239If the variable content has the format @T{@At@rep{filename}}, 9334If the variable content has the format @T{@At@rep{filename}},
@@ -9408,7 +9503,12 @@ change between versions.
9408@itemize{ 9503@itemize{
9409 9504
9410@item{ 9505@item{
9411The control variable in @Rw{for} loops are read only. 9506The word @Rw{global} is a reserved word.
9507Do not use it as a regular name.
9508}
9509
9510@item{
9511The control variable in @Rw{for} loops is read only.
9412If you need to change it, 9512If you need to change it,
9413declare a local variable with the same name in the loop body. 9513declare a local variable with the same name in the loop body.
9414} 9514}
@@ -9534,13 +9634,17 @@ and @bnfNter{LiteralString}, see @See{lexical}.)
9534@OrNL @Rw{for} namelist @Rw{in} explist @Rw{do} block @Rw{end} 9634@OrNL @Rw{for} namelist @Rw{in} explist @Rw{do} block @Rw{end}
9535@OrNL @Rw{function} funcname funcbody 9635@OrNL @Rw{function} funcname funcbody
9536@OrNL @Rw{local} @Rw{function} @bnfNter{Name} funcbody 9636@OrNL @Rw{local} @Rw{function} @bnfNter{Name} funcbody
9637@OrNL @Rw{global} @Rw{function} @bnfNter{Name} funcbody
9537@OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} 9638@OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist}
9639@OrNL @Rw{global} attnamelist
9640@OrNL @Rw{global} @bnfopt{attrib} @bnfter{*}
9538} 9641}
9539 9642
9540@producname{attnamelist}@producbody{ 9643@producname{attnamelist}@producbody{
9541 @bnfNter{Name} attrib @bnfrep{@bnfter{,} @bnfNter{Name} attrib}} 9644 @bnfopt{attrib} @bnfNter{Name} @bnfopt{attrib}
9645 @bnfrep{@bnfter{,} @bnfNter{Name} @bnfopt{attrib}}}
9542 9646
9543@producname{attrib}@producbody{@bnfopt{@bnfter{<} @bnfNter{Name} @bnfter{>}}} 9647@producname{attrib}@producbody{@bnfter{<} @bnfNter{Name} @bnfter{>}}
9544 9648
9545@producname{retstat}@producbody{@Rw{return} 9649@producname{retstat}@producbody{@Rw{return}
9546 @bnfopt{explist} @bnfopt{@bnfter{;}}} 9650 @bnfopt{explist} @bnfopt{@bnfter{;}}}
diff --git a/testes/all.lua b/testes/all.lua
index 5c7ebfa5..d3e2f123 100755
--- a/testes/all.lua
+++ b/testes/all.lua
@@ -2,6 +2,10 @@
2-- $Id: testes/all.lua $ 2-- $Id: testes/all.lua $
3-- See Copyright Notice in file lua.h 3-- See Copyright Notice in file lua.h
4 4
5global <const> *
6
7global _soft, _port, _nomsg
8global T
5 9
6local version = "Lua 5.5" 10local version = "Lua 5.5"
7if _VERSION ~= version then 11if _VERSION ~= version then
@@ -34,7 +38,7 @@ if usertests then
34end 38end
35 39
36-- tests should require debug when needed 40-- tests should require debug when needed
37debug = nil 41global debug; debug = nil
38 42
39 43
40if usertests then 44if usertests then
@@ -71,7 +75,7 @@ do -- (
71 75
72-- track messages for tests not performed 76-- track messages for tests not performed
73local msgs = {} 77local msgs = {}
74function Message (m) 78global function Message (m)
75 if not _nomsg then 79 if not _nomsg then
76 print(m) 80 print(m)
77 msgs[#msgs+1] = string.sub(m, 3, -3) 81 msgs[#msgs+1] = string.sub(m, 3, -3)
diff --git a/testes/api.lua b/testes/api.lua
index 49e3f9b9..b3791654 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -114,7 +114,7 @@ end
114 114
115-- testing warnings 115-- testing warnings
116T.testC([[ 116T.testC([[
117 warningC "#This shold be a" 117 warningC "#This should be a"
118 warningC " single " 118 warningC " single "
119 warning "warning" 119 warning "warning"
120 warningC "#This should be " 120 warningC "#This should be "
@@ -162,7 +162,7 @@ do -- test returning more results than fit in the caller stack
162end 162end
163 163
164 164
165do -- testing multipe returns 165do -- testing multiple returns
166 local function foo (n) 166 local function foo (n)
167 if n > 0 then return n, foo(n - 1) end 167 if n > 0 then return n, foo(n - 1) end
168 end 168 end
@@ -902,7 +902,7 @@ F = function (x)
902 assert(T.udataval(A) == B) 902 assert(T.udataval(A) == B)
903 debug.getmetatable(A) -- just access it 903 debug.getmetatable(A) -- just access it
904 end 904 end
905 A = x -- ressurect userdata 905 A = x -- resurrect userdata
906 B = udval 906 B = udval
907 return 1,2,3 907 return 1,2,3
908end 908end
diff --git a/testes/attrib.lua b/testes/attrib.lua
index d8b6e0f3..f4156086 100644
--- a/testes/attrib.lua
+++ b/testes/attrib.lua
@@ -308,11 +308,11 @@ else
308 _ENV.x, _ENV.y = nil 308 _ENV.x, _ENV.y = nil
309end 309end
310 310
311
311_ENV = _G 312_ENV = _G
312 313
313 314
314-- testing preload 315-- testing preload
315
316do 316do
317 local p = package 317 local p = package
318 package = {} 318 package = {}
@@ -331,6 +331,26 @@ do
331 assert(type(package.path) == "string") 331 assert(type(package.path) == "string")
332end 332end
333 333
334
335do print("testing external strings")
336 package.cpath = DC"?"
337 local lib2 = require"lib2-v2"
338 local t = {}
339 for _, len in ipairs{0, 10, 39, 40, 41, 1000} do
340 local str = string.rep("a", len)
341 local str1 = lib2.newstr(str)
342 assert(str == str1)
343 assert(not T or T.hash(str) == T.hash(str1))
344 t[str1] = 20; assert(t[str] == 20 and t[str1] == 20)
345 t[str] = 10; assert(t[str1] == 10)
346 local tt = {[str1] = str1}
347 assert(next(tt) == str1 and next(tt, str1) == nil)
348 assert(tt[str] == str)
349 local str2 = lib2.newstr(str1)
350 assert(str == str2 and t[str2] == 10 and tt[str2] == str)
351 end
352end
353
334print('+') 354print('+')
335 355
336end --] 356end --]
@@ -447,7 +467,7 @@ do
447end 467end
448 468
449 469
450-- test of large float/integer indices 470-- test of large float/integer indices
451 471
452-- compute maximum integer where all bits fit in a float 472-- compute maximum integer where all bits fit in a float
453local maxint = math.maxinteger 473local maxint = math.maxinteger
diff --git a/testes/bwcoercion.lua b/testes/bwcoercion.lua
index cd735ab0..0544944d 100644
--- a/testes/bwcoercion.lua
+++ b/testes/bwcoercion.lua
@@ -4,7 +4,7 @@ local strsub = string.sub
4 4
5local print = print 5local print = print
6 6
7_ENV = nil 7global none
8 8
9-- Try to convert a value to an integer, without assuming any coercion. 9-- Try to convert a value to an integer, without assuming any coercion.
10local function toint (x) 10local function toint (x)
diff --git a/testes/calls.lua b/testes/calls.lua
index 942fad72..0dacb85a 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/calls.lua $ 1-- $Id: testes/calls.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4print("testing functions and calls") 6print("testing functions and calls")
5 7
6local debug = require "debug" 8local debug = require "debug"
@@ -22,7 +24,7 @@ assert(not pcall(type))
22 24
23 25
24-- testing local-function recursion 26-- testing local-function recursion
25fact = false 27global fact = false
26do 28do
27 local res = 1 29 local res = 1
28 local function fact (n) 30 local function fact (n)
@@ -63,7 +65,7 @@ a.b.c:f2('k', 12); assert(a.b.c.k == 12)
63 65
64print('+') 66print('+')
65 67
66t = nil -- 'declare' t 68global t = nil -- 'declare' t
67function f(a,b,c) local d = 'a'; t={a,b,c,d} end 69function f(a,b,c) local d = 'a'; t={a,b,c,d} end
68 70
69f( -- this line change must be valid 71f( -- this line change must be valid
@@ -75,7 +77,7 @@ assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
75 77
76t = nil -- delete 't' 78t = nil -- delete 't'
77 79
78function fat(x) 80global function fat(x)
79 if x <= 1 then return 1 81 if x <= 1 then return 1
80 else return x*load("return fat(" .. x-1 .. ")", "")() 82 else return x*load("return fat(" .. x-1 .. ")", "")()
81 end 83 end
@@ -107,7 +109,7 @@ end
107 109
108_G.deep = nil -- "declaration" (used by 'all.lua') 110_G.deep = nil -- "declaration" (used by 'all.lua')
109 111
110function deep (n) 112global function deep (n)
111 if n>0 then deep(n-1) end 113 if n>0 then deep(n-1) end
112end 114end
113deep(10) 115deep(10)
@@ -352,7 +354,7 @@ assert(not load(function () return true end))
352 354
353-- small bug 355-- small bug
354local t = {nil, "return ", "3"} 356local t = {nil, "return ", "3"}
355f, msg = load(function () return table.remove(t, 1) end) 357local f, msg = load(function () return table.remove(t, 1) end)
356assert(f() == nil) -- should read the empty chunk 358assert(f() == nil) -- should read the empty chunk
357 359
358-- another small bug (in 5.2.1) 360-- another small bug (in 5.2.1)
@@ -388,7 +390,8 @@ assert(load("return _ENV", nil, nil, 123)() == 123)
388 390
389 391
390-- load when _ENV is not first upvalue 392-- load when _ENV is not first upvalue
391local x; XX = 123 393global XX; local x
394XX = 123
392local function h () 395local function h ()
393 local y=x -- use 'x', so that it becomes 1st upvalue 396 local y=x -- use 'x', so that it becomes 1st upvalue
394 return XX -- global name 397 return XX -- global name
diff --git a/testes/closure.lua b/testes/closure.lua
index d3b9f621..0c2e96c0 100644
--- a/testes/closure.lua
+++ b/testes/closure.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/closure.lua $ 1-- $Id: testes/closure.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4print "testing closures" 6print "testing closures"
5 7
6do -- bug in 5.4.7 8do -- bug in 5.4.7
diff --git a/testes/code.lua b/testes/code.lua
index 111717ce..380ff70c 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/code.lua $ 1-- $Id: testes/code.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4if T==nil then 6if T==nil then
5 (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') 7 (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n')
6 return 8 return
@@ -405,8 +407,8 @@ do -- tests for table access in upvalues
405end 407end
406 408
407-- de morgan 409-- de morgan
408checkequal(function () local a; if not (a or b) then b=a end end, 410checkequal(function () local a, b; if not (a or b) then b=a end end,
409 function () local a; if (not a and not b) then b=a end end) 411 function () local a, b; if (not a and not b) then b=a end end)
410 412
411checkequal(function (l) local a; return 0 <= a and a <= l end, 413checkequal(function (l) local a; return 0 <= a and a <= l end,
412 function (l) local a; return not (not(a >= 0) or not(a <= l)) end) 414 function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
@@ -480,5 +482,23 @@ do -- basic check for SETLIST
480 assert(count == 1) 482 assert(count == 1)
481end 483end
482 484
485
486do print("testing code for integer limits")
487 local function checkints (n)
488 local source = string.format(
489 "local a = {[true] = 0X%x}; return a[true]", n)
490 local f = assert(load(source))
491 checkKlist(f, {n})
492 assert(f() == n)
493 f = load(string.dump(f))
494 assert(f() == n)
495 end
496
497 checkints(math.maxinteger)
498 checkints(math.mininteger)
499 checkints(-1)
500
501end
502
483print 'OK' 503print 'OK'
484 504
diff --git a/testes/constructs.lua b/testes/constructs.lua
index 3f6d506f..94f670c7 100644
--- a/testes/constructs.lua
+++ b/testes/constructs.lua
@@ -60,7 +60,7 @@ assert((x>y) and x or y == 2);
60 60
61assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) 61assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891)
62 62
63do -- testing operators with diffent kinds of constants 63do -- testing operators with different kinds of constants
64 -- operands to consider: 64 -- operands to consider:
65 -- * fit in register 65 -- * fit in register
66 -- * constant doesn't fit in register 66 -- * constant doesn't fit in register
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 17f6ceba..4881d964 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -156,12 +156,12 @@ do
156 st, msg = coroutine.close(co) 156 st, msg = coroutine.close(co)
157 assert(st and msg == nil) 157 assert(st and msg == nil)
158 158
159 local main = coroutine.running()
159 160
160 -- cannot close the running coroutine 161 -- cannot close 'main'
161 local st, msg = pcall(coroutine.close, coroutine.running()) 162 local st, msg = pcall(coroutine.close, main);
162 assert(not st and string.find(msg, "running")) 163 assert(not st and string.find(msg, "main"))
163 164
164 local main = coroutine.running()
165 165
166 -- cannot close a "normal" coroutine 166 -- cannot close a "normal" coroutine
167 ;(coroutine.wrap(function () 167 ;(coroutine.wrap(function ()
@@ -169,20 +169,19 @@ do
169 assert(not st and string.find(msg, "normal")) 169 assert(not st and string.find(msg, "normal"))
170 end))() 170 end))()
171 171
172 -- cannot close a coroutine while closing it 172 do -- close a coroutine while closing it
173 do
174 local co 173 local co
175 co = coroutine.create( 174 co = coroutine.create(
176 function() 175 function()
177 local x <close> = func2close(function() 176 local x <close> = func2close(function()
178 coroutine.close(co) -- try to close it again 177 coroutine.close(co) -- close it again
179 end) 178 end)
180 coroutine.yield(20) 179 coroutine.yield(20)
181 end) 180 end)
182 local st, msg = coroutine.resume(co) 181 local st, msg = coroutine.resume(co)
183 assert(st and msg == 20) 182 assert(st and msg == 20)
184 st, msg = coroutine.close(co) 183 st, msg = coroutine.close(co)
185 assert(not st and string.find(msg, "running coroutine")) 184 assert(st and msg == nil)
186 end 185 end
187 186
188 -- to-be-closed variables in coroutines 187 -- to-be-closed variables in coroutines
@@ -289,6 +288,56 @@ do
289end 288end
290 289
291 290
291do print("coroutines closing itself")
292 global <const> coroutine, string, os
293 global <const> assert, error, pcall
294
295 local X = nil
296
297 local function new ()
298 return coroutine.create(function (what)
299
300 local <close>var = func2close(function (t, err)
301 if what == "yield" then
302 coroutine.yield()
303 elseif what == "error" then
304 error(200)
305 else
306 X = "Ok"
307 return X
308 end
309 end)
310
311 -- do an unprotected call so that coroutine becomes non-yieldable
312 string.gsub("a", "a", function ()
313 assert(not coroutine.isyieldable())
314 -- do protected calls while non-yieldable, to add recovery
315 -- entries (setjmp) to the stack
316 assert(pcall(pcall, function ()
317 -- 'close' works even while non-yieldable
318 coroutine.close() -- close itself
319 os.exit(false) -- not reacheable
320 end))
321 end)
322 end)
323 end
324
325 local co = new()
326 local st, msg = coroutine.resume(co, "ret")
327 assert(st and msg == nil)
328 assert(X == "Ok")
329
330 local co = new()
331 local st, msg = coroutine.resume(co, "error")
332 assert(not st and msg == 200)
333
334 local co = new()
335 local st, msg = coroutine.resume(co, "yield")
336 assert(not st and string.find(msg, "attempt to yield"))
337
338end
339
340
292-- yielding across C boundaries 341-- yielding across C boundaries
293 342
294local co = coroutine.wrap(function() 343local co = coroutine.wrap(function()
diff --git a/testes/db.lua b/testes/db.lua
index 3c821ab7..0f174f17 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -349,8 +349,11 @@ end, "crl")
349 349
350 350
351function f(a,b) 351function f(a,b)
352 -- declare some globals to check that they don't interfere with 'getlocal'
353 global collectgarbage
352 collectgarbage() 354 collectgarbage()
353 local _, x = debug.getlocal(1, 1) 355 local _, x = debug.getlocal(1, 1)
356 global assert, g, string
354 local _, y = debug.getlocal(1, 2) 357 local _, y = debug.getlocal(1, 2)
355 assert(x == a and y == b) 358 assert(x == a and y == b)
356 assert(debug.setlocal(2, 3, "pera") == "AA".."AA") 359 assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
@@ -386,7 +389,9 @@ function g (...)
386 f(AAAA,B) 389 f(AAAA,B)
387 assert(AAAA == "pera" and B == "manga") 390 assert(AAAA == "pera" and B == "manga")
388 do 391 do
392 global *
389 local B = 13 393 local B = 13
394 global<const> assert
390 local x,y = debug.getlocal(1,5) 395 local x,y = debug.getlocal(1,5)
391 assert(x == 'B' and y == 13) 396 assert(x == 'B' and y == 13)
392 end 397 end
@@ -431,7 +436,7 @@ do
431 assert(a == nil and not b) 436 assert(a == nil and not b)
432end 437end
433 438
434-- testing iteraction between multiple values x hooks 439-- testing interaction between multiple values x hooks
435do 440do
436 local function f(...) return 3, ... end 441 local function f(...) return 3, ... end
437 local count = 0 442 local count = 0
@@ -587,7 +592,7 @@ t = getupvalues(foo2)
587assert(t.a == 1 and t.b == 2 and t.c == 3) 592assert(t.a == 1 and t.b == 2 and t.c == 3)
588assert(debug.setupvalue(foo1, 1, "xuxu") == "b") 593assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
589assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu") 594assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
590-- upvalues of C functions are allways "called" "" (the empty string) 595-- upvalues of C functions are always named "" (the empty string)
591assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "") 596assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "")
592 597
593 598
@@ -701,7 +706,7 @@ assert(debug.traceback(print, 4) == print)
701assert(string.find(debug.traceback("hi", 4), "^hi\n")) 706assert(string.find(debug.traceback("hi", 4), "^hi\n"))
702assert(string.find(debug.traceback("hi"), "^hi\n")) 707assert(string.find(debug.traceback("hi"), "^hi\n"))
703assert(not string.find(debug.traceback("hi"), "'debug.traceback'")) 708assert(not string.find(debug.traceback("hi"), "'debug.traceback'"))
704assert(string.find(debug.traceback("hi", 0), "'debug.traceback'")) 709assert(string.find(debug.traceback("hi", 0), "'traceback'"))
705assert(string.find(debug.traceback(), "^stack traceback:\n")) 710assert(string.find(debug.traceback(), "^stack traceback:\n"))
706 711
707do -- C-function names in traceback 712do -- C-function names in traceback
@@ -829,7 +834,7 @@ end
829 834
830co = coroutine.create(function (x) f(x) end) 835co = coroutine.create(function (x) f(x) end)
831a, b = coroutine.resume(co, 3) 836a, b = coroutine.resume(co, 3)
832t = {"'coroutine.yield'", "'f'", "in function <"} 837t = {"'yield'", "'f'", "in function <"}
833while coroutine.status(co) == "suspended" do 838while coroutine.status(co) == "suspended" do
834 checktraceback(co, t) 839 checktraceback(co, t)
835 a, b = coroutine.resume(co) 840 a, b = coroutine.resume(co)
@@ -839,7 +844,7 @@ t[1] = "'error'"
839checktraceback(co, t) 844checktraceback(co, t)
840 845
841 846
842-- test acessing line numbers of a coroutine from a resume inside 847-- test accessing line numbers of a coroutine from a resume inside
843-- a C function (this is a known bug in Lua 5.0) 848-- a C function (this is a known bug in Lua 5.0)
844 849
845local function g(x) 850local function g(x)
@@ -966,9 +971,9 @@ local debug = require'debug'
966local a = 12 -- a local variable 971local a = 12 -- a local variable
967 972
968local n, v = debug.getlocal(1, 1) 973local n, v = debug.getlocal(1, 1)
969assert(n == "(temporary)" and v == debug) -- unkown name but known value 974assert(n == "(temporary)" and v == debug) -- unknown name but known value
970n, v = debug.getlocal(1, 2) 975n, v = debug.getlocal(1, 2)
971assert(n == "(temporary)" and v == 12) -- unkown name but known value 976assert(n == "(temporary)" and v == 12) -- unknown name but known value
972 977
973-- a function with an upvalue 978-- a function with an upvalue
974local f = function () local x; return a end 979local f = function () local x; return a end
@@ -1018,7 +1023,7 @@ do -- bug in 5.4.0: line hooks in stripped code
1018 line = l 1023 line = l
1019 end, "l") 1024 end, "l")
1020 assert(s() == 2); debug.sethook(nil) 1025 assert(s() == 2); debug.sethook(nil)
1021 assert(line == nil) -- hook called withoug debug info for 1st instruction 1026 assert(line == nil) -- hook called without debug info for 1st instruction
1022end 1027end
1023 1028
1024do -- tests for 'source' in binary dumps 1029do -- tests for 'source' in binary dumps
diff --git a/testes/errors.lua b/testes/errors.lua
index c1c40fec..4230a352 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -303,14 +303,14 @@ do
303 local f = function (a) return a + 1 end 303 local f = function (a) return a + 1 end
304 f = assert(load(string.dump(f, true))) 304 f = assert(load(string.dump(f, true)))
305 assert(f(3) == 4) 305 assert(f(3) == 4)
306 checkerr("^%?:%-1:", f, {}) 306 checkerr("^%?:%?:", f, {})
307 307
308 -- code with a move to a local var ('OP_MOV A B' with A<B) 308 -- code with a move to a local var ('OP_MOV A B' with A<B)
309 f = function () local a; a = {}; return a + 2 end 309 f = function () local a; a = {}; return a + 2 end
310 -- no debug info (so that 'a' is unknown) 310 -- no debug info (so that 'a' is unknown)
311 f = assert(load(string.dump(f, true))) 311 f = assert(load(string.dump(f, true)))
312 -- symbolic execution should not get lost 312 -- symbolic execution should not get lost
313 checkerr("^%?:%-1:.*table value", f) 313 checkerr("^%?:%?:.*table value", f)
314end 314end
315 315
316 316
@@ -489,6 +489,14 @@ if not b then
489 end 489 end
490end]], 5) 490end]], 5)
491 491
492lineerror([[
493_ENV = 1
494global function foo ()
495 local a = 10
496 return a
497end
498]], 2)
499
492 500
493-- bug in 5.4.0 501-- bug in 5.4.0
494lineerror([[ 502lineerror([[
@@ -507,7 +515,7 @@ end
507 515
508 516
509if not _soft then 517if not _soft then
510 -- several tests that exaust the Lua stack 518 -- several tests that exhaust the Lua stack
511 collectgarbage() 519 collectgarbage()
512 print"testing stack overflow" 520 print"testing stack overflow"
513 local C = 0 521 local C = 0
@@ -734,7 +742,7 @@ assert(c > 255 and string.find(b, "too many upvalues") and
734 742
735-- local variables 743-- local variables
736s = "\nfunction foo ()\n local " 744s = "\nfunction foo ()\n local "
737for j = 1,300 do 745for j = 1,200 do
738 s = s.."a"..j..", " 746 s = s.."a"..j..", "
739end 747end
740s = s.."b\n" 748s = s.."b\n"
diff --git a/testes/files.lua b/testes/files.lua
index 53edf314..7146ac7c 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/files.lua $ 1-- $Id: testes/files.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4local debug = require "debug" 6local debug = require "debug"
5 7
6local maxint = math.maxinteger 8local maxint = math.maxinteger
@@ -478,7 +480,7 @@ do print("testing flush")
478end 480end
479 481
480 482
481-- test for multipe arguments in 'lines' 483-- test for multiple arguments in 'lines'
482io.output(file); io.write"0123456789\n":close() 484io.output(file); io.write"0123456789\n":close()
483for a,b in io.lines(file, 1, 1) do 485for a,b in io.lines(file, 1, 1) do
484 if a == "\n" then assert(not b) 486 if a == "\n" then assert(not b)
@@ -713,7 +715,7 @@ do
713end 715end
714 716
715 717
716if T and T.nonblock then 718if T and T.nonblock and not _port then
717 print("testing failed write") 719 print("testing failed write")
718 720
719 -- unable to write anything to /dev/full 721 -- unable to write anything to /dev/full
@@ -838,13 +840,13 @@ assert(os.date("!\0\0") == "\0\0")
838local x = string.rep("a", 10000) 840local x = string.rep("a", 10000)
839assert(os.date(x) == x) 841assert(os.date(x) == x)
840local t = os.time() 842local t = os.time()
841D = os.date("*t", t) 843global D = os.date("*t", t)
842assert(os.date(string.rep("%d", 1000), t) == 844assert(os.date(string.rep("%d", 1000), t) ==
843 string.rep(os.date("%d", t), 1000)) 845 string.rep(os.date("%d", t), 1000))
844assert(os.date(string.rep("%", 200)) == string.rep("%", 100)) 846assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
845 847
846local function checkDateTable (t) 848local function checkDateTable (t)
847 _G.D = os.date("*t", t) 849 D = os.date("*t", t)
848 assert(os.time(D) == t) 850 assert(os.time(D) == t)
849 load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and 851 load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
850 D.hour==%H and D.min==%M and D.sec==%S and 852 D.hour==%H and D.min==%M and D.sec==%S and
diff --git a/testes/gc.lua b/testes/gc.lua
index 0693837c..62713dac 100644
--- a/testes/gc.lua
+++ b/testes/gc.lua
@@ -288,6 +288,21 @@ x,y,z=nil
288collectgarbage() 288collectgarbage()
289assert(next(a) == string.rep('$', 11)) 289assert(next(a) == string.rep('$', 11))
290 290
291do -- invalid mode
292 local a = setmetatable({}, {__mode = 34})
293 collectgarbage()
294end
295
296
297if T then -- bug since 5.3: all-weak tables are not being revisited
298 T.gcstate("propagate")
299 local t = setmetatable({}, {__mode = "kv"})
300 T.gcstate("enteratomic") -- 't' was visited
301 setmetatable(t, {__mode = "kv"})
302 T.gcstate("pause") -- its new metatable is not being visited
303 assert(getmetatable(t).__mode == "kv")
304end
305
291 306
292-- 'bug' in 5.1 307-- 'bug' in 5.1
293a = {} 308a = {}
@@ -446,8 +461,8 @@ do -- tests for string keys in weak tables
446 local m = collectgarbage("count") -- current memory 461 local m = collectgarbage("count") -- current memory
447 local a = setmetatable({}, {__mode = "kv"}) 462 local a = setmetatable({}, {__mode = "kv"})
448 a[string.rep("a", 2^22)] = 25 -- long string key -> number value 463 a[string.rep("a", 2^22)] = 25 -- long string key -> number value
449 a[string.rep("b", 2^22)] = {} -- long string key -> colectable value 464 a[string.rep("b", 2^22)] = {} -- long string key -> collectable value
450 a[{}] = 14 -- colectable key 465 a[{}] = 14 -- collectable key
451 collectgarbage() 466 collectgarbage()
452 local k, v = next(a) -- string key with number value preserved 467 local k, v = next(a) -- string key with number value preserved
453 assert(k == string.rep("a", 2^22) and v == 25) 468 assert(k == string.rep("a", 2^22) and v == 25)
@@ -459,7 +474,7 @@ do -- tests for string keys in weak tables
459 assert(next(a) == nil) 474 assert(next(a) == nil)
460 -- make sure will not try to compare with dead key 475 -- make sure will not try to compare with dead key
461 assert(a[string.rep("b", 100)] == undef) 476 assert(a[string.rep("b", 100)] == undef)
462 assert(collectgarbage("count") <= m + 1) -- eveything collected 477 assert(collectgarbage("count") <= m + 1) -- everything collected
463end 478end
464 479
465 480
@@ -524,7 +539,7 @@ do
524 local co = coroutine.create(f) 539 local co = coroutine.create(f)
525 assert(coroutine.resume(co, co)) 540 assert(coroutine.resume(co, co))
526 end 541 end
527 -- Now, thread and closure are not reacheable any more. 542 -- Now, thread and closure are not reachable any more.
528 collectgarbage() 543 collectgarbage()
529 assert(collected) 544 assert(collected)
530 collectgarbage("restart") 545 collectgarbage("restart")
@@ -644,7 +659,7 @@ do
644 assert(getmetatable(o) == tt) 659 assert(getmetatable(o) == tt)
645 -- create new objects during GC 660 -- create new objects during GC
646 local a = 'xuxu'..(10+3)..'joao', {} 661 local a = 'xuxu'..(10+3)..'joao', {}
647 ___Glob = o -- ressurrect object! 662 ___Glob = o -- resurrect object!
648 setmetatable({}, tt) -- creates a new one with same metatable 663 setmetatable({}, tt) -- creates a new one with same metatable
649 print(">>> closing state " .. "<<<\n") 664 print(">>> closing state " .. "<<<\n")
650 end 665 end
diff --git a/testes/goto.lua b/testes/goto.lua
index eca68516..3310314d 100644
--- a/testes/goto.lua
+++ b/testes/goto.lua
@@ -1,6 +1,12 @@
1-- $Id: testes/goto.lua $ 1-- $Id: testes/goto.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global<const> require
5global<const> print, load, assert, string, setmetatable
6global<const> collectgarbage, error
7
8print("testing goto and global declarations")
9
4collectgarbage() 10collectgarbage()
5 11
6local function errmsg (code, m) 12local function errmsg (code, m)
@@ -17,15 +23,18 @@ errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
17errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'") 23errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'")
18 24
19 25
20-- undefined label
21errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")
22 26
23-- jumping over variable definition 27-- jumping over variable declaration
28errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "scope of 'aa'")
29
30errmsg([[ goto l2; global *; ::l1:: ::l2:: print(3) ]], "scope of '*'")
31
24errmsg([[ 32errmsg([[
25do local bb, cc; goto l1; end 33do local bb, cc; goto l1; end
26local aa 34local aa
27::l1:: print(3) 35::l1:: print(3)
28]], "local 'aa'") 36]], "scope of 'aa'")
37
29 38
30-- jumping into a block 39-- jumping into a block
31errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 40errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
@@ -38,7 +47,7 @@ errmsg([[
38 local xuxu = 10 47 local xuxu = 10
39 ::cont:: 48 ::cont::
40 until xuxu < x 49 until xuxu < x
41]], "local 'xuxu'") 50]], "scope of 'xuxu'")
42 51
43-- simple gotos 52-- simple gotos
44local x 53local x
@@ -252,6 +261,8 @@ assert(testG(5) == 10)
252 261
253do -- test goto's around to-be-closed variable 262do -- test goto's around to-be-closed variable
254 263
264 global *
265
255 -- set 'var' and return an object that will reset 'var' when 266 -- set 'var' and return an object that will reset 'var' when
256 -- it goes out of scope 267 -- it goes out of scope
257 local function newobj (var) 268 local function newobj (var)
@@ -263,16 +274,16 @@ do -- test goto's around to-be-closed variable
263 274
264 goto L1 275 goto L1
265 276
266 ::L4:: assert(not X); goto L5 -- varX dead here 277 ::L4:: assert(not varX); goto L5 -- varX dead here
267 278
268 ::L1:: 279 ::L1::
269 local varX <close> = newobj("X") 280 local varX <close> = newobj("X")
270 assert(X); goto L2 -- varX alive here 281 assert(varX); goto L2 -- varX alive here
271 282
272 ::L3:: 283 ::L3::
273 assert(X); goto L4 -- varX alive here 284 assert(varX); goto L4 -- varX alive here
274 285
275 ::L2:: assert(X); goto L3 -- varX alive here 286 ::L2:: assert(varX); goto L3 -- varX alive here
276 287
277 ::L5:: -- return 288 ::L5:: -- return
278end 289end
@@ -280,7 +291,146 @@ end
280 291
281 292
282foo() 293foo()
283-------------------------------------------------------------------------------- 294--------------------------------------------------------------------------
295
296local function checkerr (code, err)
297 local st, msg = load(code)
298 assert(not st and string.find(msg, err))
299end
300
301do
302 global T<const>
303
304 -- globals must be declared, after a global declaration
305 checkerr("global none; X = 1", "variable 'X'")
306 checkerr("global none; function XX() end", "variable 'XX'")
284 307
308 -- global variables cannot be to-be-closed
309 checkerr("global X<close>", "cannot be")
310 checkerr("global <close> *", "cannot be")
311
312 do
313 local X = 10
314 do global X; X = 20 end
315 assert(X == 10) -- local X
316 end
317 assert(_ENV.X == 20) -- global X
318
319 -- '_ENV' cannot be global
320 checkerr("global _ENV, a; a = 10", "variable 'a'")
321
322 -- global declarations inside functions
323 checkerr([[
324 global none
325 local function foo () XXX = 1 end --< ERROR]], "variable 'XXX'")
326
327 if not T then -- when not in "test mode", "global" isn't reserved
328 assert(load("global = 1; return global")() == 1)
329 print " ('global' is not a reserved word)"
330 else
331 -- "global" reserved, cannot be used as a variable
332 assert(not load("global = 1; return global"))
333 end
334
335 local foo = 20
336 do
337 global function foo (x)
338 if x == 0 then return 1 else return 2 * foo(x - 1) end
339 end
340 assert(foo == _ENV.foo and foo(4) == 16)
341 end
342 assert(_ENV.foo(4) == 16)
343 assert(foo == 20) -- local one is in context here
344
345 do
346 global foo;
347 function foo (x) return end -- Ok after declaration
348 end
349
350 checkerr([[
351 global<const> foo;
352 function foo (x) return end -- ERROR: foo is read-only
353 ]], "assign to const variable 'foo'")
354
355 checkerr([[
356 global foo <const>;
357 function foo (x) -- ERROR: foo is read-only
358 return
359 end
360 ]], "%:2%:") -- correct line in error message
361
362 checkerr([[
363 global<const> *;
364 print(X) -- Ok to use
365 Y = 1 -- ERROR
366 ]], "assign to const variable 'Y'")
367
368 checkerr([[
369 global *;
370 Y = X -- Ok to use
371 global<const> *;
372 Y = 1 -- ERROR
373 ]], "assign to const variable 'Y'")
374
375 global *
376 Y = 10
377 assert(_ENV.Y == 10)
378 global<const> *
379 local x = Y
380 global *
381 Y = x + Y
382 assert(_ENV.Y == 20)
383 Y = nil
384end
385
386
387do -- Ok to declare hundreds of globals
388 global table
389 local code = {}
390 for i = 1, 1000 do
391 code[#code + 1] = ";global x" .. i
392 end
393 code[#code + 1] = "; return x990"
394 code = table.concat(code)
395 _ENV.x990 = 11
396 assert(load(code)() == 11)
397 _ENV.x990 = nil
398end
399
400do -- mixing lots of global/local declarations
401 global table
402 local code = {}
403 for i = 1, 200 do
404 code[#code + 1] = ";global x" .. i
405 code[#code + 1] = ";local y" .. i .. "=" .. (2*i)
406 end
407 code[#code + 1] = "; return x200 + y200"
408 code = table.concat(code)
409 _ENV.x200 = 11
410 assert(assert(load(code))() == 2*200 + 11)
411 _ENV.x200 = nil
412end
413
414do print "testing initialization in global declarations"
415 global<const> a, b, c = 10, 20, 30
416 assert(_ENV.a == 10 and b == 20 and c == 30)
417
418 global<const> a, b, c = 10
419 assert(_ENV.a == 10 and b == nil and c == nil)
420
421 global table
422 global a, b, c, d = table.unpack{1, 2, 3, 6, 5}
423 assert(_ENV.a == 1 and b == 2 and c == 3 and d == 6)
424
425 local a, b = 100, 200
426 do
427 global a, b = a, b
428 end
429 assert(_ENV.a == 100 and _ENV.b == 200)
430
431
432 _ENV.a, _ENV.b, _ENV.c, _ENV.d = nil -- erase these globals
433end
285 434
286print'OK' 435print'OK'
436
diff --git a/testes/libs/lib22.c b/testes/libs/lib22.c
index 8e656502..b377cce5 100644
--- a/testes/libs/lib22.c
+++ b/testes/libs/lib22.c
@@ -1,3 +1,7 @@
1/* implementation for lib2-v2 */
2
3#include <string.h>
4
1#include "lua.h" 5#include "lua.h"
2#include "lauxlib.h" 6#include "lauxlib.h"
3 7
@@ -8,8 +12,54 @@ static int id (lua_State *L) {
8} 12}
9 13
10 14
15struct STR {
16 void *ud;
17 lua_Alloc allocf;
18};
19
20
21static void *t_freestr (void *ud, void *ptr, size_t osize, size_t nsize) {
22 struct STR *blk = (struct STR*)ptr - 1;
23 blk->allocf(blk->ud, blk, sizeof(struct STR) + osize, 0);
24 return NULL;
25}
26
27
28static int newstr (lua_State *L) {
29 size_t len;
30 const char *str = luaL_checklstring(L, 1, &len);
31 void *ud;
32 lua_Alloc allocf = lua_getallocf(L, &ud);
33 struct STR *blk = (struct STR*)allocf(ud, NULL, 0,
34 len + 1 + sizeof(struct STR));
35 if (blk == NULL) { /* allocation error? */
36 lua_pushliteral(L, "not enough memory");
37 lua_error(L); /* raise a memory error */
38 }
39 blk->ud = ud; blk->allocf = allocf;
40 memcpy(blk + 1, str, len + 1);
41 lua_pushexternalstring(L, (char *)(blk + 1), len, t_freestr, L);
42 return 1;
43}
44
45
46/*
47** Create an external string and keep it in the registry, so that it
48** will test that the library code is still available (to deallocate
49** this string) when closing the state.
50*/
51static void initstr (lua_State *L) {
52 lua_pushcfunction(L, newstr);
53 lua_pushstring(L,
54 "012345678901234567890123456789012345678901234567890123456789");
55 lua_call(L, 1, 1); /* call newstr("0123...") */
56 luaL_ref(L, LUA_REGISTRYINDEX); /* keep string in the registry */
57}
58
59
11static const struct luaL_Reg funcs[] = { 60static const struct luaL_Reg funcs[] = {
12 {"id", id}, 61 {"id", id},
62 {"newstr", newstr},
13 {NULL, NULL} 63 {NULL, NULL}
14}; 64};
15 65
@@ -18,6 +68,7 @@ LUAMOD_API int luaopen_lib2 (lua_State *L) {
18 lua_settop(L, 2); 68 lua_settop(L, 2);
19 lua_setglobal(L, "y"); /* y gets 2nd parameter */ 69 lua_setglobal(L, "y"); /* y gets 2nd parameter */
20 lua_setglobal(L, "x"); /* x gets 1st parameter */ 70 lua_setglobal(L, "x"); /* x gets 1st parameter */
71 initstr(L);
21 luaL_newlib(L, funcs); 72 luaL_newlib(L, funcs);
22 return 1; 73 return 1;
23} 74}
diff --git a/testes/literals.lua b/testes/literals.lua
index 28995718..336ef585 100644
--- a/testes/literals.lua
+++ b/testes/literals.lua
@@ -3,6 +3,8 @@
3 3
4print('testing scanner') 4print('testing scanner')
5 5
6global <const> *
7
6local debug = require "debug" 8local debug = require "debug"
7 9
8 10
diff --git a/testes/locals.lua b/testes/locals.lua
index ccea0a14..02f41980 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/locals.lua $ 1-- $Id: testes/locals.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4print('testing local variables and environments') 6print('testing local variables and environments')
5 7
6local debug = require"debug" 8local debug = require"debug"
@@ -39,9 +41,11 @@ f = nil
39local f 41local f
40local x = 1 42local x = 1
41 43
42a = nil 44do
43load('local a = {}')() 45 global a; a = nil
44assert(a == nil) 46 load('local a = {}')()
47 assert(a == nil)
48end
45 49
46function f (a) 50function f (a)
47 local _1, _2, _3, _4, _5 51 local _1, _2, _3, _4, _5
@@ -154,7 +158,7 @@ local _ENV = (function (...) return ... end)(_G, dummy) -- {
154do local _ENV = {assert=assert}; assert(true) end 158do local _ENV = {assert=assert}; assert(true) end
155local mt = {_G = _G} 159local mt = {_G = _G}
156local foo,x 160local foo,x
157A = false -- "declare" A 161global A; A = false -- "declare" A
158do local _ENV = mt 162do local _ENV = mt
159 function foo (x) 163 function foo (x)
160 A = x 164 A = x
@@ -177,20 +181,27 @@ assert(x==20)
177A = nil 181A = nil
178 182
179 183
180do -- constants 184do print("testing local constants")
185 global assert<const>, load, string, X
186 X = 1 -- not a constant
181 local a<const>, b, c<const> = 10, 20, 30 187 local a<const>, b, c<const> = 10, 20, 30
182 b = a + c + b -- 'b' is not constant 188 b = a + c + b -- 'b' is not constant
183 assert(a == 10 and b == 60 and c == 30) 189 assert(a == 10 and b == 60 and c == 30)
190
184 local function checkro (name, code) 191 local function checkro (name, code)
185 local st, msg = load(code) 192 local st, msg = load(code)
186 local gab = string.format("attempt to assign to const variable '%s'", name) 193 local gab = string.format("attempt to assign to const variable '%s'", name)
187 assert(not st and string.find(msg, gab)) 194 assert(not st and string.find(msg, gab))
188 end 195 end
196
189 checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12") 197 checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
190 checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11") 198 checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
191 checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11") 199 checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
192 checkro("foo", "local foo <const> = 10; function foo() end") 200 checkro("foo", "local<const> foo = 10; function foo() end")
193 checkro("foo", "local foo <const> = {}; function foo() end") 201 checkro("foo", "local<const> foo <const> = {}; function foo() end")
202 checkro("foo", "global<const> foo <const>; function foo() end")
203 checkro("XX", "global XX <const>; XX = 10")
204 checkro("XX", "local _ENV; global XX <const>; XX = 10")
194 205
195 checkro("z", [[ 206 checkro("z", [[
196 local a, z <const>, b = 10; 207 local a, z <const>, b = 10;
@@ -201,11 +212,26 @@ do -- constants
201 local a, var1 <const> = 10; 212 local a, var1 <const> = 10;
202 function foo() a = 20; z = function () var1 = 12; end end 213 function foo() a = 20; z = function () var1 = 12; end end
203 ]]) 214 ]])
215
216 checkro("var1", [[
217 global a, var1 <const>, z;
218 local function foo() a = 20; z = function () var1 = 12; end end
219 ]])
204end 220end
205 221
206 222
223
207print"testing to-be-closed variables" 224print"testing to-be-closed variables"
208 225
226
227do
228 local st, msg = load("local <close> a, b")
229 assert(not st and string.find(msg, "multiple"))
230
231 local st, msg = load("local a<close>, b<close>")
232 assert(not st and string.find(msg, "multiple"))
233end
234
209local function stack(n) n = ((n == 0) or stack(n - 1)) end 235local function stack(n) n = ((n == 0) or stack(n - 1)) end
210 236
211local function func2close (f, x, y) 237local function func2close (f, x, y)
@@ -1162,7 +1188,7 @@ do
1162 local function open (x) 1188 local function open (x)
1163 numopen = numopen + 1 1189 numopen = numopen + 1
1164 return 1190 return
1165 function () -- iteraction function 1191 function () -- iteration function
1166 x = x - 1 1192 x = x - 1
1167 if x > 0 then return x end 1193 if x > 0 then return x end
1168 end, 1194 end,
diff --git a/testes/main.lua b/testes/main.lua
index bf3c898e..dc48dc48 100644
--- a/testes/main.lua
+++ b/testes/main.lua
@@ -90,7 +90,7 @@ prepfile[[
901, a 901, a
91) 91)
92]] 92]]
93RUN('lua - < %s > %s', prog, out) 93RUN('lua - -- < %s > %s', prog, out)
94checkout("1\tnil\n") 94checkout("1\tnil\n")
95 95
96RUN('echo "print(10)\nprint(2)\n" | lua > %s', out) 96RUN('echo "print(10)\nprint(2)\n" | lua > %s', out)
@@ -133,7 +133,7 @@ checkout("-h\n")
133prepfile("print(package.path)") 133prepfile("print(package.path)")
134 134
135-- test LUA_PATH 135-- test LUA_PATH
136RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out) 136RUN('env LUA_INIT= LUA_PATH=x lua -- %s > %s', prog, out)
137checkout("x\n") 137checkout("x\n")
138 138
139-- test LUA_PATH_version 139-- test LUA_PATH_version
@@ -226,7 +226,7 @@ RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
226checkout("0.0\nALO ALO\t20\n") 226checkout("0.0\nALO ALO\t20\n")
227 227
228 228
229-- test module names with version sufix ("libs/lib2-v2") 229-- test module names with version suffix ("libs/lib2-v2")
230RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s", 230RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",
231 out) 231 out)
232checkout("true\n") 232checkout("true\n")
@@ -347,7 +347,7 @@ checkout("a\n")
347RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) 347RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
348checkout("1\n3\n") 348checkout("1\n3\n")
349 349
350-- test iteractive mode 350-- test interactive mode
351prepfile[[ 351prepfile[[
352(6*2-6) -- === 352(6*2-6) -- ===
353a = 353a =
@@ -358,7 +358,7 @@ RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
358checkprogout("6\n10\n10\n\n") 358checkprogout("6\n10\n10\n\n")
359 359
360prepfile("a = [[b\nc\nd\ne]]\na") 360prepfile("a = [[b\nc\nd\ne]]\na")
361RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 361RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i -- < %s > %s]], prog, out)
362checkprogout("b\nc\nd\ne\n\n") 362checkprogout("b\nc\nd\ne\n\n")
363 363
364-- input interrupted in continuation line 364-- input interrupted in continuation line
@@ -488,12 +488,13 @@ assert(not os.remove(out))
488-- invalid options 488-- invalid options
489NoRun("unrecognized option '-h'", "lua -h") 489NoRun("unrecognized option '-h'", "lua -h")
490NoRun("unrecognized option '---'", "lua ---") 490NoRun("unrecognized option '---'", "lua ---")
491NoRun("unrecognized option '-Ex'", "lua -Ex") 491NoRun("unrecognized option '-Ex'", "lua -Ex --")
492NoRun("unrecognized option '-vv'", "lua -vv") 492NoRun("unrecognized option '-vv'", "lua -vv")
493NoRun("unrecognized option '-iv'", "lua -iv") 493NoRun("unrecognized option '-iv'", "lua -iv")
494NoRun("'-e' needs argument", "lua -e") 494NoRun("'-e' needs argument", "lua -e")
495NoRun("syntax error", "lua -e a") 495NoRun("syntax error", "lua -e a")
496NoRun("'-l' needs argument", "lua -l") 496NoRun("'-l' needs argument", "lua -l")
497NoRun("-i", "lua -- -i") -- handles -i as a script name
497 498
498 499
499if T then -- test library? 500if T then -- test library?
diff --git a/testes/math.lua b/testes/math.lua
index bad8bc5e..0d228d09 100644
--- a/testes/math.lua
+++ b/testes/math.lua
@@ -3,8 +3,15 @@
3 3
4print("testing numbers and math lib") 4print("testing numbers and math lib")
5 5
6local minint <const> = math.mininteger 6local math = require "math"
7local maxint <const> = math.maxinteger 7local string = require "string"
8
9global none
10
11global<const> print, assert, pcall, type, pairs, load
12global<const> tonumber, tostring, select
13
14local<const> minint, maxint = math.mininteger, math.maxinteger
8 15
9local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1 16local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1
10assert((1 << intbits) == 0) 17assert((1 << intbits) == 0)
@@ -184,7 +191,7 @@ do
184 for i = -3, 3 do -- variables avoid constant folding 191 for i = -3, 3 do -- variables avoid constant folding
185 for j = -3, 3 do 192 for j = -3, 3 do
186 -- domain errors (0^(-n)) are not portable 193 -- domain errors (0^(-n)) are not portable
187 if not _port or i ~= 0 or j > 0 then 194 if not _ENV._port or i ~= 0 or j > 0 then
188 assert(eq(i^j, 1 / i^(-j))) 195 assert(eq(i^j, 1 / i^(-j)))
189 end 196 end
190 end 197 end
@@ -430,7 +437,7 @@ for i = 2,36 do
430 assert(tonumber('\t10000000000\t', i) == i10) 437 assert(tonumber('\t10000000000\t', i) == i10)
431end 438end
432 439
433if not _soft then 440if not _ENV._soft then
434 -- tests with very long numerals 441 -- tests with very long numerals
435 assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1) 442 assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1)
436 assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1) 443 assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1)
@@ -632,7 +639,7 @@ assert(maxint % -2 == -1)
632 639
633-- non-portable tests because Windows C library cannot compute 640-- non-portable tests because Windows C library cannot compute
634-- fmod(1, huge) correctly 641-- fmod(1, huge) correctly
635if not _port then 642if not _ENV._port then
636 local function anan (x) assert(isNaN(x)) end -- assert Not a Number 643 local function anan (x) assert(isNaN(x)) end -- assert Not a Number
637 anan(0.0 % 0) 644 anan(0.0 % 0)
638 anan(1.3 % 0) 645 anan(1.3 % 0)
@@ -779,6 +786,7 @@ assert(a == '10' and b == '20')
779 786
780do 787do
781 print("testing -0 and NaN") 788 print("testing -0 and NaN")
789 global rawset, undef
782 local mz <const> = -0.0 790 local mz <const> = -0.0
783 local z <const> = 0.0 791 local z <const> = 0.0
784 assert(mz == z) 792 assert(mz == z)
@@ -1071,9 +1079,10 @@ do
1071 assert(x == tonumber(tostring(x))) 1079 assert(x == tonumber(tostring(x)))
1072 end 1080 end
1073 1081
1074 -- different numbers shold print differently. 1082 -- different numbers should print differently.
1075 -- check pairs of floats with minimum detectable difference 1083 -- check pairs of floats with minimum detectable difference
1076 local p = floatbits - 1 1084 local p = floatbits - 1
1085 global ipairs
1077 for i = 1, maxexp - 1 do 1086 for i = 1, maxexp - 1 do
1078 for _, i in ipairs{-i, i} do 1087 for _, i in ipairs{-i, i} do
1079 local x = 2^i 1088 local x = 2^i
diff --git a/testes/nextvar.lua b/testes/nextvar.lua
index 031ad3fd..7e5bed56 100644
--- a/testes/nextvar.lua
+++ b/testes/nextvar.lua
@@ -1,6 +1,8 @@
1-- $Id: testes/nextvar.lua $ 1-- $Id: testes/nextvar.lua $
2-- See Copyright Notice in file lua.h 2-- See Copyright Notice in file lua.h
3 3
4global <const> *
5
4print('testing tables, next, and for') 6print('testing tables, next, and for')
5 7
6local function checkerror (msg, f, ...) 8local function checkerror (msg, f, ...)
@@ -227,7 +229,7 @@ for i = 1,lim do
227end 229end
228 230
229 231
230-- insert and delete elements until a rehash occurr. Caller must ensure 232-- insert and delete elements until a rehash occur. Caller must ensure
231-- that a rehash will change the shape of the table. Must repeat because 233-- that a rehash will change the shape of the table. Must repeat because
232-- the insertion may collide with the deleted element, and then there is 234-- the insertion may collide with the deleted element, and then there is
233-- no rehash. 235-- no rehash.
@@ -343,13 +345,22 @@ do
343 end 345 end
344end 346end
345 347
346local nofind = {}
347 348
348a,b,c = 1,2,3 349do print("testing attack on table length")
349a,b,c = nil 350 local t = {}
351 local lim = math.floor(math.log(math.maxinteger, 2)) - 1
352 for i = lim, 0, -1 do
353 t[2^i] = true
354 end
355 assert(t[1 << lim])
356 -- next loop should not take forever
357 for i = 1, #t do end
358end
359
360local nofind = {}
350 361
351 362
352-- next uses always the same iteraction function 363-- next uses always the same iteration function
353assert(next{} == next{}) 364assert(next{} == next{})
354 365
355local function find (name) 366local function find (name)
@@ -396,7 +407,7 @@ for i=0,10000 do
396 end 407 end
397end 408end
398 409
399n = {n=0} 410local n = {n=0}
400for i,v in pairs(a) do 411for i,v in pairs(a) do
401 n.n = n.n+1 412 n.n = n.n+1
402 assert(i and v and a[i] == v) 413 assert(i and v and a[i] == v)
diff --git a/testes/pm.lua b/testes/pm.lua
index 2a0cfb0b..720d2a35 100644
--- a/testes/pm.lua
+++ b/testes/pm.lua
@@ -6,6 +6,8 @@
6 6
7print('testing pattern matching') 7print('testing pattern matching')
8 8
9global <const> *
10
9local function checkerror (msg, f, ...) 11local function checkerror (msg, f, ...)
10 local s, err = pcall(f, ...) 12 local s, err = pcall(f, ...)
11 assert(not s and string.find(err, msg)) 13 assert(not s and string.find(err, msg))
@@ -23,9 +25,9 @@ a,b = string.find('alo', '')
23assert(a == 1 and b == 0) 25assert(a == 1 and b == 0)
24a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position 26a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position
25assert(a == 1 and b == 1) 27assert(a == 1 and b == 1)
26a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the midle 28a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the middle
27assert(a == 5 and b == 7) 29assert(a == 5 and b == 7)
28a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the midle 30a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the middle
29assert(a == 9 and b == 11) 31assert(a == 9 and b == 11)
30a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end 32a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end
31assert(a == 9 and b == 11); 33assert(a == 9 and b == 11);
diff --git a/testes/strings.lua b/testes/strings.lua
index ce28e4c5..46912d43 100644
--- a/testes/strings.lua
+++ b/testes/strings.lua
@@ -3,6 +3,7 @@
3 3
4-- ISO Latin encoding 4-- ISO Latin encoding
5 5
6global <const> *
6 7
7print('testing strings and string library') 8print('testing strings and string library')
8 9
diff --git a/testes/tracegc.lua b/testes/tracegc.lua
index 9c5c1b3f..a8c929df 100644
--- a/testes/tracegc.lua
+++ b/testes/tracegc.lua
@@ -6,7 +6,7 @@ local M = {}
6local setmetatable, stderr, collectgarbage = 6local setmetatable, stderr, collectgarbage =
7 setmetatable, io.stderr, collectgarbage 7 setmetatable, io.stderr, collectgarbage
8 8
9_ENV = nil 9global none
10 10
11local active = false 11local active = false
12 12
diff --git a/testes/utf8.lua b/testes/utf8.lua
index 0704782c..028995a4 100644
--- a/testes/utf8.lua
+++ b/testes/utf8.lua
@@ -3,6 +3,8 @@
3 3
4-- UTF-8 file 4-- UTF-8 file
5 5
6global <const> *
7
6print "testing UTF-8 library" 8print "testing UTF-8 library"
7 9
8local utf8 = require'utf8' 10local utf8 = require'utf8'
@@ -134,7 +136,7 @@ do
134 errorcodes("\xbfinvalid") 136 errorcodes("\xbfinvalid")
135 errorcodes("αλφ\xBFα") 137 errorcodes("αλφ\xBFα")
136 138
137 -- calling interation function with invalid arguments 139 -- calling iteration function with invalid arguments
138 local f = utf8.codes("") 140 local f = utf8.codes("")
139 assert(f("", 2) == nil) 141 assert(f("", 2) == nil)
140 assert(f("", -1) == nil) 142 assert(f("", -1) == nil)
@@ -150,11 +152,20 @@ checkerror("position out of bounds", utf8.offset, "", 1, -1)
150checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 152checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
151checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 153checkerror("continuation byte", utf8.offset, "𦧺", 1, 2)
152checkerror("continuation byte", utf8.offset, "\x80", 1) 154checkerror("continuation byte", utf8.offset, "\x80", 1)
155checkerror("continuation byte", utf8.offset, "\x9c", -1)
153 156
154-- error in indices for len 157-- error in indices for len
155checkerror("out of bounds", utf8.len, "abc", 0, 2) 158checkerror("out of bounds", utf8.len, "abc", 0, 2)
156checkerror("out of bounds", utf8.len, "abc", 1, 4) 159checkerror("out of bounds", utf8.len, "abc", 1, 4)
157 160
161do -- missing continuation bytes
162 -- get what is available
163 local p, e = utf8.offset("\xE0", 1)
164 assert(p == 1 and e == 1)
165 local p, e = utf8.offset("\xE0\x9e", -1)
166 assert(p == 1 and e == 2)
167end
168
158 169
159local s = "hello World" 170local s = "hello World"
160local t = {string.byte(s, 1, -1)} 171local t = {string.byte(s, 1, -1)}