aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-01-05 16:48:53 +0800
committerLi Jin <dragon-fly@qq.com>2021-01-05 16:48:53 +0800
commit71b9532659abb531bd1597d88451426dcc895824 (patch)
treec9b50856b37f759c9a31e1a6e761e77b51996fa6
parente3a31f9945053d8e8d9e4ef3d2e4c9abe563cff2 (diff)
downloadyuescript-71b9532659abb531bd1597d88451426dcc895824.tar.gz
yuescript-71b9532659abb531bd1597d88451426dcc895824.tar.bz2
yuescript-71b9532659abb531bd1597d88451426dcc895824.zip
update Lua.
-rw-r--r--src/lua/lapi.c29
-rw-r--r--src/lua/lauxlib.c96
-rw-r--r--src/lua/lauxlib.h16
-rw-r--r--src/lua/lcode.c28
-rw-r--r--src/lua/ldblib.c4
-rw-r--r--src/lua/ldo.c18
-rw-r--r--src/lua/lgc.c4
-rw-r--r--src/lua/liolib.c18
-rw-r--r--src/lua/llex.c56
-rw-r--r--src/lua/llimits.h3
-rw-r--r--src/lua/lobject.c2
-rw-r--r--src/lua/lparser.c104
-rw-r--r--src/lua/lparser.h11
-rw-r--r--src/lua/lstate.c11
-rw-r--r--src/lua/ltable.c69
-rw-r--r--src/lua/ltable.h8
-rw-r--r--src/lua/lualib.h6
-rw-r--r--src/lua/lvm.c5
18 files changed, 270 insertions, 218 deletions
diff --git a/src/lua/lapi.c b/src/lua/lapi.c
index c824da2..03e756d 100644
--- a/src/lua/lapi.c
+++ b/src/lua/lapi.c
@@ -629,11 +629,21 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
629} 629}
630 630
631 631
632/*
633** Get the global table in the registry. Since all predefined
634** indices in the registry were inserted right when the registry
635** was created and never removed, they must always be in the array
636** part of the registry.
637*/
638#define getGtable(L) \
639 (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1])
640
641
632LUA_API int lua_getglobal (lua_State *L, const char *name) { 642LUA_API int lua_getglobal (lua_State *L, const char *name) {
633 Table *reg; 643 const TValue *G;
634 lua_lock(L); 644 lua_lock(L);
635 reg = hvalue(&G(L)->l_registry); 645 G = getGtable(L);
636 return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); 646 return auxgetstr(L, G, name);
637} 647}
638 648
639 649
@@ -811,10 +821,10 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
811 821
812 822
813LUA_API void lua_setglobal (lua_State *L, const char *name) { 823LUA_API void lua_setglobal (lua_State *L, const char *name) {
814 Table *reg; 824 const TValue *G;
815 lua_lock(L); /* unlock done in 'auxsetstr' */ 825 lua_lock(L); /* unlock done in 'auxsetstr' */
816 reg = hvalue(&G(L)->l_registry); 826 G = getGtable(L);
817 auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); 827 auxsetstr(L, G, name);
818} 828}
819 829
820 830
@@ -861,12 +871,10 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
861 871
862static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { 872static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
863 Table *t; 873 Table *t;
864 TValue *slot;
865 lua_lock(L); 874 lua_lock(L);
866 api_checknelems(L, n); 875 api_checknelems(L, n);
867 t = gettable(L, idx); 876 t = gettable(L, idx);
868 slot = luaH_set(L, t, key); 877 luaH_set(L, t, key, s2v(L->top - 1));
869 setobj2t(L, slot, s2v(L->top - 1));
870 invalidateTMcache(t); 878 invalidateTMcache(t);
871 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); 879 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
872 L->top -= n; 880 L->top -= n;
@@ -1063,8 +1071,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
1063 LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */ 1071 LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */
1064 if (f->nupvalues >= 1) { /* does it have an upvalue? */ 1072 if (f->nupvalues >= 1) { /* does it have an upvalue? */
1065 /* get global table from registry */ 1073 /* get global table from registry */
1066 Table *reg = hvalue(&G(L)->l_registry); 1074 const TValue *gt = getGtable(L);
1067 const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
1068 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ 1075 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1069 setobj(L, f->upvals[0]->v, gt); 1076 setobj(L, f->upvals[0]->v, gt);
1070 luaC_barrier(L, f->upvals[0], gt); 1077 luaC_barrier(L, f->upvals[0], gt);
diff --git a/src/lua/lauxlib.c b/src/lua/lauxlib.c
index cbe9ed3..074ff08 100644
--- a/src/lua/lauxlib.c
+++ b/src/lua/lauxlib.c
@@ -283,10 +283,10 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
283 283
284 284
285LUALIB_API int luaL_execresult (lua_State *L, int stat) { 285LUALIB_API int luaL_execresult (lua_State *L, int stat) {
286 const char *what = "exit"; /* type of termination */
287 if (stat != 0 && errno != 0) /* error with an 'errno'? */ 286 if (stat != 0 && errno != 0) /* error with an 'errno'? */
288 return luaL_fileresult(L, 0, NULL); 287 return luaL_fileresult(L, 0, NULL);
289 else { 288 else {
289 const char *what = "exit"; /* type of termination */
290 l_inspectstat(stat, what); /* interpret result */ 290 l_inspectstat(stat, what); /* interpret result */
291 if (*what == 'e' && stat == 0) /* successful termination? */ 291 if (*what == 'e' && stat == 0) /* successful termination? */
292 lua_pushboolean(L, 1); 292 lua_pushboolean(L, 1);
@@ -639,10 +639,14 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
639** ======================================================= 639** =======================================================
640*/ 640*/
641 641
642/* index of free-list header */ 642/* index of free-list header (after the predefined values) */
643#define freelist 0 643#define freelist (LUA_RIDX_LAST + 1)
644
645 644
645/*
646** The previously freed references form a linked list:
647** t[freelist] is the index of a first free index, or zero if list is
648** empty; t[t[freelist]] is the index of the second element; etc.
649*/
646LUALIB_API int luaL_ref (lua_State *L, int t) { 650LUALIB_API int luaL_ref (lua_State *L, int t) {
647 int ref; 651 int ref;
648 if (lua_isnil(L, -1)) { 652 if (lua_isnil(L, -1)) {
@@ -650,9 +654,16 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
650 return LUA_REFNIL; /* 'nil' has a unique fixed reference */ 654 return LUA_REFNIL; /* 'nil' has a unique fixed reference */
651 } 655 }
652 t = lua_absindex(L, t); 656 t = lua_absindex(L, t);
653 lua_rawgeti(L, t, freelist); /* get first free element */ 657 if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */
654 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ 658 ref = 0; /* list is empty */
655 lua_pop(L, 1); /* remove it from stack */ 659 lua_pushinteger(L, 0); /* initialize as an empty list */
660 lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */
661 }
662 else { /* already initialized */
663 lua_assert(lua_isinteger(L, -1));
664 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
665 }
666 lua_pop(L, 1); /* remove element from stack */
656 if (ref != 0) { /* any free element? */ 667 if (ref != 0) { /* any free element? */
657 lua_rawgeti(L, t, ref); /* remove it from list */ 668 lua_rawgeti(L, t, ref); /* remove it from list */
658 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ 669 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
@@ -668,6 +679,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
668 if (ref >= 0) { 679 if (ref >= 0) {
669 t = lua_absindex(L, t); 680 t = lua_absindex(L, t);
670 lua_rawgeti(L, t, freelist); 681 lua_rawgeti(L, t, freelist);
682 lua_assert(lua_isinteger(L, -1));
671 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ 683 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
672 lua_pushinteger(L, ref); 684 lua_pushinteger(L, ref);
673 lua_rawseti(L, t, freelist); /* t[freelist] = ref */ 685 lua_rawseti(L, t, freelist); /* t[freelist] = ref */
@@ -1006,43 +1018,67 @@ static int panic (lua_State *L) {
1006 1018
1007 1019
1008/* 1020/*
1009** Emit a warning. '*warnstate' means: 1021** Warning functions:
1010** 0 - warning system is off; 1022** warnfoff: warning system is off
1011** 1 - ready to start a new message; 1023** warnfon: ready to start a new message
1012** 2 - previous message is to be continued. 1024** warnfcont: previous message is to be continued
1013*/ 1025*/
1014static void warnf (void *ud, const char *message, int tocont) { 1026static void warnfoff (void *ud, const char *message, int tocont);
1015 int *warnstate = (int *)ud; 1027static void warnfon (void *ud, const char *message, int tocont);
1016 if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */ 1028static void warnfcont (void *ud, const char *message, int tocont);
1017 if (strcmp(message, "@off") == 0) 1029
1018 *warnstate = 0; 1030
1019 else if (strcmp(message, "@on") == 0) 1031/*
1020 *warnstate = 1; 1032** Check whether message is a control message. If so, execute the
1021 return; 1033** control or ignore it if unknown.
1034*/
1035static int checkcontrol (lua_State *L, const char *message, int tocont) {
1036 if (tocont || *(message++) != '@') /* not a control message? */
1037 return 0;
1038 else {
1039 if (strcmp(message, "off") == 0)
1040 lua_setwarnf(L, warnfoff, L); /* turn warnings off */
1041 else if (strcmp(message, "on") == 0)
1042 lua_setwarnf(L, warnfon, L); /* turn warnings on */
1043 return 1; /* it was a control message */
1022 } 1044 }
1023 else if (*warnstate == 0) /* warnings off? */ 1045}
1024 return; 1046
1025 if (*warnstate == 1) /* previous message was the last? */ 1047
1026 lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ 1048static void warnfoff (void *ud, const char *message, int tocont) {
1049 checkcontrol((lua_State *)ud, message, tocont);
1050}
1051
1052
1053/*
1054** Writes the message and handle 'tocont', finishing the message
1055** if needed and setting the next warn function.
1056*/
1057static void warnfcont (void *ud, const char *message, int tocont) {
1058 lua_State *L = (lua_State *)ud;
1027 lua_writestringerror("%s", message); /* write message */ 1059 lua_writestringerror("%s", message); /* write message */
1028 if (tocont) /* not the last part? */ 1060 if (tocont) /* not the last part? */
1029 *warnstate = 2; /* to be continued */ 1061 lua_setwarnf(L, warnfcont, L); /* to be continued */
1030 else { /* last part */ 1062 else { /* last part */
1031 lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ 1063 lua_writestringerror("%s", "\n"); /* finish message with end-of-line */
1032 *warnstate = 1; /* ready to start a new message */ 1064 lua_setwarnf(L, warnfon, L); /* next call is a new message */
1033 } 1065 }
1034} 1066}
1035 1067
1036 1068
1069static void warnfon (void *ud, const char *message, int tocont) {
1070 if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */
1071 return; /* nothing else to be done */
1072 lua_writestringerror("%s", "Lua warning: "); /* start a new warning */
1073 warnfcont(ud, message, tocont); /* finish processing */
1074}
1075
1076
1037LUALIB_API lua_State *luaL_newstate (void) { 1077LUALIB_API lua_State *luaL_newstate (void) {
1038 lua_State *L = lua_newstate(l_alloc, NULL); 1078 lua_State *L = lua_newstate(l_alloc, NULL);
1039 if (L) { 1079 if (L) {
1040 int *warnstate; /* space for warning state */
1041 lua_atpanic(L, &panic); 1080 lua_atpanic(L, &panic);
1042 warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0); 1081 lua_setwarnf(L, warnfoff, L); /* default is warnings off */
1043 luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */
1044 *warnstate = 0; /* default is warnings off */
1045 lua_setwarnf(L, warnf, warnstate);
1046 } 1082 }
1047 return L; 1083 return L;
1048} 1084}
diff --git a/src/lua/lauxlib.h b/src/lua/lauxlib.h
index 59fef6a..6571491 100644
--- a/src/lua/lauxlib.h
+++ b/src/lua/lauxlib.h
@@ -158,6 +158,22 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
158 158
159 159
160/* 160/*
161** Internal assertions for in-house debugging
162*/
163#if !defined(lua_assert)
164
165#if defined LUAI_ASSERT
166 #include <assert.h>
167 #define lua_assert(c) assert(c)
168#else
169 #define lua_assert(c) ((void)0)
170#endif
171
172#endif
173
174
175
176/*
161** {====================================================== 177** {======================================================
162** Generic Buffer manipulation 178** Generic Buffer manipulation
163** ======================================================= 179** =======================================================
diff --git a/src/lua/lcode.c b/src/lua/lcode.c
index 6f241c9..d8d353f 100644
--- a/src/lua/lcode.c
+++ b/src/lua/lcode.c
@@ -545,11 +545,14 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
545** and try to reuse constants. Because some values should not be used 545** and try to reuse constants. Because some values should not be used
546** as keys (nil cannot be a key, integer keys can collapse with float 546** as keys (nil cannot be a key, integer keys can collapse with float
547** keys), the caller must provide a useful 'key' for indexing the cache. 547** keys), the caller must provide a useful 'key' for indexing the cache.
548** Note that all functions share the same table, so entering or exiting
549** a function can make some indices wrong.
548*/ 550*/
549static int addk (FuncState *fs, TValue *key, TValue *v) { 551static int addk (FuncState *fs, TValue *key, TValue *v) {
552 TValue val;
550 lua_State *L = fs->ls->L; 553 lua_State *L = fs->ls->L;
551 Proto *f = fs->f; 554 Proto *f = fs->f;
552 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ 555 const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */
553 int k, oldsize; 556 int k, oldsize;
554 if (ttisinteger(idx)) { /* is there an index there? */ 557 if (ttisinteger(idx)) { /* is there an index there? */
555 k = cast_int(ivalue(idx)); 558 k = cast_int(ivalue(idx));
@@ -563,7 +566,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
563 k = fs->nk; 566 k = fs->nk;
564 /* numerical value does not need GC barrier; 567 /* numerical value does not need GC barrier;
565 table has no metatable, so it does not need to invalidate cache */ 568 table has no metatable, so it does not need to invalidate cache */
566 setivalue(idx, k); 569 setivalue(&val, k);
570 luaH_finishset(L, fs->ls->h, key, idx, &val);
567 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); 571 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
568 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); 572 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
569 setobj(L, &f->k[k], v); 573 setobj(L, &f->k[k], v);
@@ -753,7 +757,7 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
753 757
754 758
755/* 759/*
756** Ensure that expression 'e' is not a variable (nor a constant). 760** Ensure that expression 'e' is not a variable (nor a <const>).
757** (Expression still may have jump lists.) 761** (Expression still may have jump lists.)
758*/ 762*/
759void luaK_dischargevars (FuncState *fs, expdesc *e) { 763void luaK_dischargevars (FuncState *fs, expdesc *e) {
@@ -763,7 +767,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
763 break; 767 break;
764 } 768 }
765 case VLOCAL: { /* already in a register */ 769 case VLOCAL: { /* already in a register */
766 e->u.info = e->u.var.sidx; 770 e->u.info = e->u.var.ridx;
767 e->k = VNONRELOC; /* becomes a non-relocatable value */ 771 e->k = VNONRELOC; /* becomes a non-relocatable value */
768 break; 772 break;
769 } 773 }
@@ -805,8 +809,8 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
805 809
806 810
807/* 811/*
808** Ensures expression value is in register 'reg' (and therefore 812** Ensure expression value is in register 'reg', making 'e' a
809** 'e' will become a non-relocatable expression). 813** non-relocatable expression.
810** (Expression still may have jump lists.) 814** (Expression still may have jump lists.)
811*/ 815*/
812static void discharge2reg (FuncState *fs, expdesc *e, int reg) { 816static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
@@ -860,7 +864,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
860 864
861 865
862/* 866/*
863** Ensures expression value is in any register. 867** Ensure expression value is in a register, making 'e' a
868** non-relocatable expression.
864** (Expression still may have jump lists.) 869** (Expression still may have jump lists.)
865*/ 870*/
866static void discharge2anyreg (FuncState *fs, expdesc *e) { 871static void discharge2anyreg (FuncState *fs, expdesc *e) {
@@ -946,8 +951,11 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
946 exp2reg(fs, e, e->u.info); /* put final result in it */ 951 exp2reg(fs, e, e->u.info); /* put final result in it */
947 return e->u.info; 952 return e->u.info;
948 } 953 }
954 /* else expression has jumps and cannot change its register
955 to hold the jump values, because it is a local variable.
956 Go through to the default case. */
949 } 957 }
950 luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ 958 luaK_exp2nextreg(fs, e); /* default: use next available register */
951 return e->u.info; 959 return e->u.info;
952} 960}
953 961
@@ -1032,7 +1040,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
1032 switch (var->k) { 1040 switch (var->k) {
1033 case VLOCAL: { 1041 case VLOCAL: {
1034 freeexp(fs, ex); 1042 freeexp(fs, ex);
1035 exp2reg(fs, ex, var->u.var.sidx); /* compute 'ex' into proper place */ 1043 exp2reg(fs, ex, var->u.var.ridx); /* compute 'ex' into proper place */
1036 return; 1044 return;
1037 } 1045 }
1038 case VUPVAL: { 1046 case VUPVAL: {
@@ -1272,7 +1280,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1272 } 1280 }
1273 else { 1281 else {
1274 /* register index of the table */ 1282 /* register index of the table */
1275 t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info; 1283 t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info;
1276 if (isKstr(fs, k)) { 1284 if (isKstr(fs, k)) {
1277 t->u.ind.idx = k->u.info; /* literal string */ 1285 t->u.ind.idx = k->u.info; /* literal string */
1278 t->k = VINDEXSTR; 1286 t->k = VINDEXSTR;
diff --git a/src/lua/ldblib.c b/src/lua/ldblib.c
index 5a326ad..15593bf 100644
--- a/src/lua/ldblib.c
+++ b/src/lua/ldblib.c
@@ -377,7 +377,7 @@ static int db_sethook (lua_State *L) {
377 } 377 }
378 if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) { 378 if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) {
379 /* table just created; initialize it */ 379 /* table just created; initialize it */
380 lua_pushstring(L, "k"); 380 lua_pushliteral(L, "k");
381 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ 381 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
382 lua_pushvalue(L, -1); 382 lua_pushvalue(L, -1);
383 lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */ 383 lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */
@@ -420,7 +420,7 @@ static int db_debug (lua_State *L) {
420 for (;;) { 420 for (;;) {
421 char buffer[250]; 421 char buffer[250];
422 lua_writestringerror("%s", "lua_debug> "); 422 lua_writestringerror("%s", "lua_debug> ");
423 if (fgets(buffer, sizeof(buffer), stdin) == 0 || 423 if (fgets(buffer, sizeof(buffer), stdin) == NULL ||
424 strcmp(buffer, "cont\n") == 0) 424 strcmp(buffer, "cont\n") == 0)
425 return 0; 425 return 0;
426 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || 426 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
diff --git a/src/lua/ldo.c b/src/lua/ldo.c
index 5729b19..4b55c31 100644
--- a/src/lua/ldo.c
+++ b/src/lua/ldo.c
@@ -192,7 +192,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
192 else return 0; /* do not raise an error */ 192 else return 0; /* do not raise an error */
193 } 193 }
194 for (; lim < newsize; lim++) 194 for (; lim < newsize; lim++)
195 setnilvalue(s2v(newstack + lim)); /* erase new segment */ 195 setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */
196 correctstack(L, L->stack, newstack); 196 correctstack(L, L->stack, newstack);
197 L->stack = newstack; 197 L->stack = newstack;
198 L->stack_last = L->stack + newsize; 198 L->stack_last = L->stack + newsize;
@@ -534,11 +534,11 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
534 534
535 535
536/* 536/*
537** Call a function (C or Lua). 'inc' can be 1 (increment number 537** Call a function (C or Lua) through C. 'inc' can be 1 (increment
538** of recursive invocations in the C stack) or nyci (the same plus 538** number of recursive invocations in the C stack) or nyci (the same
539** increment number of non-yieldable calls). 539** plus increment number of non-yieldable calls).
540*/ 540*/
541static void docall (lua_State *L, StkId func, int nResults, int inc) { 541static void ccall (lua_State *L, StkId func, int nResults, int inc) {
542 CallInfo *ci; 542 CallInfo *ci;
543 L->nCcalls += inc; 543 L->nCcalls += inc;
544 if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) 544 if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
@@ -552,10 +552,10 @@ static void docall (lua_State *L, StkId func, int nResults, int inc) {
552 552
553 553
554/* 554/*
555** External interface for 'docall' 555** External interface for 'ccall'
556*/ 556*/
557void luaD_call (lua_State *L, StkId func, int nResults) { 557void luaD_call (lua_State *L, StkId func, int nResults) {
558 return docall(L, func, nResults, 1); 558 ccall(L, func, nResults, 1);
559} 559}
560 560
561 561
@@ -563,7 +563,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
563** Similar to 'luaD_call', but does not allow yields during the call. 563** Similar to 'luaD_call', but does not allow yields during the call.
564*/ 564*/
565void luaD_callnoyield (lua_State *L, StkId func, int nResults) { 565void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
566 return docall(L, func, nResults, nyci); 566 ccall(L, func, nResults, nyci);
567} 567}
568 568
569 569
@@ -678,7 +678,7 @@ static void resume (lua_State *L, void *ud) {
678 StkId firstArg = L->top - n; /* first argument */ 678 StkId firstArg = L->top - n; /* first argument */
679 CallInfo *ci = L->ci; 679 CallInfo *ci = L->ci;
680 if (L->status == LUA_OK) /* starting a coroutine? */ 680 if (L->status == LUA_OK) /* starting a coroutine? */
681 docall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ 681 ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
682 else { /* resuming from previous yield */ 682 else { /* resuming from previous yield */
683 lua_assert(L->status == LUA_YIELD); 683 lua_assert(L->status == LUA_YIELD);
684 L->status = LUA_OK; /* mark that it is running (again) */ 684 L->status = LUA_OK; /* mark that it is running (again) */
diff --git a/src/lua/lgc.c b/src/lua/lgc.c
index 5dba56f..bab9beb 100644
--- a/src/lua/lgc.c
+++ b/src/lua/lgc.c
@@ -632,8 +632,8 @@ static int traversethread (global_State *g, lua_State *th) {
632 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) 632 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
633 markobject(g, uv); /* open upvalues cannot be collected */ 633 markobject(g, uv); /* open upvalues cannot be collected */
634 if (g->gcstate == GCSatomic) { /* final traversal? */ 634 if (g->gcstate == GCSatomic) { /* final traversal? */
635 for (; o < th->stack_last; o++) /* clear not-marked stack slice */ 635 for (; o < th->stack_last + EXTRA_STACK; o++)
636 setnilvalue(s2v(o)); 636 setnilvalue(s2v(o)); /* clear dead stack slice */
637 /* 'remarkupvals' may have removed thread from 'twups' list */ 637 /* 'remarkupvals' may have removed thread from 'twups' list */
638 if (!isintwups(th) && th->openupval != NULL) { 638 if (!isintwups(th) && th->openupval != NULL) {
639 th->twups = g->twups; /* link it back to the list */ 639 th->twups = g->twups; /* link it back to the list */
diff --git a/src/lua/liolib.c b/src/lua/liolib.c
index 60ab1bf..7951672 100644
--- a/src/lua/liolib.c
+++ b/src/lua/liolib.c
@@ -52,12 +52,6 @@ static int l_checkmode (const char *mode) {
52** ======================================================= 52** =======================================================
53*/ 53*/
54 54
55#if !defined(l_checkmodep)
56/* By default, Lua accepts only "r" or "w" as mode */
57#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
58#endif
59
60
61#if !defined(l_popen) /* { */ 55#if !defined(l_popen) /* { */
62 56
63#if defined(LUA_USE_POSIX) /* { */ 57#if defined(LUA_USE_POSIX) /* { */
@@ -70,6 +64,12 @@ static int l_checkmode (const char *mode) {
70#define l_popen(L,c,m) (_popen(c,m)) 64#define l_popen(L,c,m) (_popen(c,m))
71#define l_pclose(L,file) (_pclose(file)) 65#define l_pclose(L,file) (_pclose(file))
72 66
67#if !defined(l_checkmodep)
68/* Windows accepts "[rw][bt]?" as valid modes */
69#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && \
70 (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0')))
71#endif
72
73#else /* }{ */ 73#else /* }{ */
74 74
75/* ISO C definitions */ 75/* ISO C definitions */
@@ -83,6 +83,12 @@ static int l_checkmode (const char *mode) {
83 83
84#endif /* } */ 84#endif /* } */
85 85
86
87#if !defined(l_checkmodep)
88/* By default, Lua accepts only "r" or "w" as valid modes */
89#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
90#endif
91
86/* }====================================================== */ 92/* }====================================================== */
87 93
88 94
diff --git a/src/lua/llex.c b/src/lua/llex.c
index 3d6b2b9..e991517 100644
--- a/src/lua/llex.c
+++ b/src/lua/llex.c
@@ -122,26 +122,29 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
122 122
123 123
124/* 124/*
125** creates a new string and anchors it in scanner's table so that 125** Creates a new string and anchors it in scanner's table so that it
126** it will not be collected until the end of the compilation 126** will not be collected until the end of the compilation; by that time
127** (by that time it should be anchored somewhere) 127** it should be anchored somewhere. It also internalizes long strings,
128** ensuring there is only one copy of each unique string. The table
129** here is used as a set: the string enters as the key, while its value
130** is irrelevant. We use the string itself as the value only because it
131** is a TValue readly available. Later, the code generation can change
132** this value.
128*/ 133*/
129TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 134TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
130 lua_State *L = ls->L; 135 lua_State *L = ls->L;
131 TValue *o; /* entry for 'str' */
132 TString *ts = luaS_newlstr(L, str, l); /* create new string */ 136 TString *ts = luaS_newlstr(L, str, l); /* create new string */
133 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ 137 const TValue *o = luaH_getstr(ls->h, ts);
134 o = luaH_set(L, ls->h, s2v(L->top - 1)); 138 if (!ttisnil(o)) /* string already present? */
135 if (isempty(o)) { /* not in use yet? */ 139 ts = keystrval(nodefromval(o)); /* get saved copy */
136 /* boolean value does not need GC barrier; 140 else { /* not in use yet */
137 table is not a metatable, so it does not need to invalidate cache */ 141 TValue *stv = s2v(L->top++); /* reserve stack space for string */
138 setbtvalue(o); /* t[string] = true */ 142 setsvalue(L, stv, ts); /* temporarily anchor the string */
143 luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
144 /* table is not a metatable, so it does not need to invalidate cache */
139 luaC_checkGC(L); 145 luaC_checkGC(L);
146 L->top--; /* remove string from stack */
140 } 147 }
141 else { /* string already present */
142 ts = keystrval(nodefromval(o)); /* re-use value previously stored */
143 }
144 L->top--; /* remove string from stack */
145 return ts; 148 return ts;
146} 149}
147 150
@@ -254,9 +257,10 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
254 257
255 258
256/* 259/*
257** reads a sequence '[=*[' or ']=*]', leaving the last bracket. 260** read a sequence '[=*[' or ']=*]', leaving the last bracket. If
258** If sequence is well formed, return its number of '='s + 2; otherwise, 261** sequence is well formed, return its number of '='s + 2; otherwise,
259** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). 262** return 1 if it is a single bracket (no '='s and no 2nd bracket);
263** otherwise (an unfinished '[==...') return 0.
260*/ 264*/
261static size_t skip_sep (LexState *ls) { 265static size_t skip_sep (LexState *ls) {
262 size_t count = 0; 266 size_t count = 0;
@@ -481,34 +485,34 @@ static int llex (LexState *ls, SemInfo *seminfo) {
481 } 485 }
482 case '=': { 486 case '=': {
483 next(ls); 487 next(ls);
484 if (check_next1(ls, '=')) return TK_EQ; 488 if (check_next1(ls, '=')) return TK_EQ; /* '==' */
485 else return '='; 489 else return '=';
486 } 490 }
487 case '<': { 491 case '<': {
488 next(ls); 492 next(ls);
489 if (check_next1(ls, '=')) return TK_LE; 493 if (check_next1(ls, '=')) return TK_LE; /* '<=' */
490 else if (check_next1(ls, '<')) return TK_SHL; 494 else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */
491 else return '<'; 495 else return '<';
492 } 496 }
493 case '>': { 497 case '>': {
494 next(ls); 498 next(ls);
495 if (check_next1(ls, '=')) return TK_GE; 499 if (check_next1(ls, '=')) return TK_GE; /* '>=' */
496 else if (check_next1(ls, '>')) return TK_SHR; 500 else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */
497 else return '>'; 501 else return '>';
498 } 502 }
499 case '/': { 503 case '/': {
500 next(ls); 504 next(ls);
501 if (check_next1(ls, '/')) return TK_IDIV; 505 if (check_next1(ls, '/')) return TK_IDIV; /* '//' */
502 else return '/'; 506 else return '/';
503 } 507 }
504 case '~': { 508 case '~': {
505 next(ls); 509 next(ls);
506 if (check_next1(ls, '=')) return TK_NE; 510 if (check_next1(ls, '=')) return TK_NE; /* '~=' */
507 else return '~'; 511 else return '~';
508 } 512 }
509 case ':': { 513 case ':': {
510 next(ls); 514 next(ls);
511 if (check_next1(ls, ':')) return TK_DBCOLON; 515 if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */
512 else return ':'; 516 else return ':';
513 } 517 }
514 case '"': case '\'': { /* short literal strings */ 518 case '"': case '\'': { /* short literal strings */
@@ -547,7 +551,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
547 return TK_NAME; 551 return TK_NAME;
548 } 552 }
549 } 553 }
550 else { /* single-char tokens (+ - / ...) */ 554 else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
551 int c = ls->current; 555 int c = ls->current;
552 next(ls); 556 next(ls);
553 return c; 557 return c;
diff --git a/src/lua/llimits.h b/src/lua/llimits.h
index a76c13e..d039483 100644
--- a/src/lua/llimits.h
+++ b/src/lua/llimits.h
@@ -326,7 +326,8 @@ typedef l_uint32 Instruction;
326 326
327/* exponentiation */ 327/* exponentiation */
328#if !defined(luai_numpow) 328#if !defined(luai_numpow)
329#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) 329#define luai_numpow(L,a,b) \
330 ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b))
330#endif 331#endif
331 332
332/* the others are quite standard operations */ 333/* the others are quite standard operations */
diff --git a/src/lua/lobject.c b/src/lua/lobject.c
index f8ea917..0e504be 100644
--- a/src/lua/lobject.c
+++ b/src/lua/lobject.c
@@ -258,7 +258,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
258 if (endptr == NULL) { /* failed? may be a different locale */ 258 if (endptr == NULL) { /* failed? may be a different locale */
259 char buff[L_MAXLENNUM + 1]; 259 char buff[L_MAXLENNUM + 1];
260 const char *pdot = strchr(s, '.'); 260 const char *pdot = strchr(s, '.');
261 if (strlen(s) > L_MAXLENNUM || pdot == NULL) 261 if (pdot == NULL || strlen(s) > L_MAXLENNUM)
262 return NULL; /* string too long or no dot; fail */ 262 return NULL; /* string too long or no dot; fail */
263 strcpy(buff, s); /* copy string to buffer */ 263 strcpy(buff, s); /* copy string to buffer */
264 buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ 264 buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
diff --git a/src/lua/lparser.c b/src/lua/lparser.c
index bcdcfb6..249ba9a 100644
--- a/src/lua/lparser.c
+++ b/src/lua/lparser.c
@@ -222,26 +222,26 @@ static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
222 222
223 223
224/* 224/*
225** Convert 'nvar', a compiler index level, to it corresponding 225** Convert 'nvar', a compiler index level, to its corresponding
226** stack index level. For that, search for the highest variable 226** register. For that, search for the highest variable below that level
227** below that level that is in the stack and uses its stack 227** that is in a register and uses its register index ('ridx') plus one.
228** index ('sidx').
229*/ 228*/
230static int stacklevel (FuncState *fs, int nvar) { 229static int reglevel (FuncState *fs, int nvar) {
231 while (nvar-- > 0) { 230 while (nvar-- > 0) {
232 Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */ 231 Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */
233 if (vd->vd.kind != RDKCTC) /* is in the stack? */ 232 if (vd->vd.kind != RDKCTC) /* is in a register? */
234 return vd->vd.sidx + 1; 233 return vd->vd.ridx + 1;
235 } 234 }
236 return 0; /* no variables in the stack */ 235 return 0; /* no variables in registers */
237} 236}
238 237
239 238
240/* 239/*
241** Return the number of variables in the stack for function 'fs' 240** Return the number of variables in the register stack for the given
241** function.
242*/ 242*/
243int luaY_nvarstack (FuncState *fs) { 243int luaY_nvarstack (FuncState *fs) {
244 return stacklevel(fs, fs->nactvar); 244 return reglevel(fs, fs->nactvar);
245} 245}
246 246
247 247
@@ -267,7 +267,7 @@ static void init_var (FuncState *fs, expdesc *e, int vidx) {
267 e->f = e->t = NO_JUMP; 267 e->f = e->t = NO_JUMP;
268 e->k = VLOCAL; 268 e->k = VLOCAL;
269 e->u.var.vidx = vidx; 269 e->u.var.vidx = vidx;
270 e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx; 270 e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx;
271} 271}
272 272
273 273
@@ -310,12 +310,12 @@ static void check_readonly (LexState *ls, expdesc *e) {
310*/ 310*/
311static void adjustlocalvars (LexState *ls, int nvars) { 311static void adjustlocalvars (LexState *ls, int nvars) {
312 FuncState *fs = ls->fs; 312 FuncState *fs = ls->fs;
313 int stklevel = luaY_nvarstack(fs); 313 int reglevel = luaY_nvarstack(fs);
314 int i; 314 int i;
315 for (i = 0; i < nvars; i++) { 315 for (i = 0; i < nvars; i++) {
316 int vidx = fs->nactvar++; 316 int vidx = fs->nactvar++;
317 Vardesc *var = getlocalvardesc(fs, vidx); 317 Vardesc *var = getlocalvardesc(fs, vidx);
318 var->vd.sidx = stklevel++; 318 var->vd.ridx = reglevel++;
319 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); 319 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
320 } 320 }
321} 321}
@@ -366,7 +366,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
366 FuncState *prev = fs->prev; 366 FuncState *prev = fs->prev;
367 if (v->k == VLOCAL) { 367 if (v->k == VLOCAL) {
368 up->instack = 1; 368 up->instack = 1;
369 up->idx = v->u.var.sidx; 369 up->idx = v->u.var.ridx;
370 up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; 370 up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind;
371 lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); 371 lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name));
372 } 372 }
@@ -620,7 +620,7 @@ static void movegotosout (FuncState *fs, BlockCnt *bl) {
620 for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ 620 for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */
621 Labeldesc *gt = &gl->arr[i]; 621 Labeldesc *gt = &gl->arr[i];
622 /* leaving a variable scope? */ 622 /* leaving a variable scope? */
623 if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar)) 623 if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar))
624 gt->close |= bl->upval; /* jump may need a close */ 624 gt->close |= bl->upval; /* jump may need a close */
625 gt->nactvar = bl->nactvar; /* update goto level */ 625 gt->nactvar = bl->nactvar; /* update goto level */
626 } 626 }
@@ -661,7 +661,7 @@ static void leaveblock (FuncState *fs) {
661 BlockCnt *bl = fs->bl; 661 BlockCnt *bl = fs->bl;
662 LexState *ls = fs->ls; 662 LexState *ls = fs->ls;
663 int hasclose = 0; 663 int hasclose = 0;
664 int stklevel = stacklevel(fs, bl->nactvar); /* level outside the block */ 664 int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */
665 if (bl->isloop) /* fix pending breaks? */ 665 if (bl->isloop) /* fix pending breaks? */
666 hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); 666 hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
667 if (!hasclose && bl->previous && bl->upval) 667 if (!hasclose && bl->previous && bl->upval)
@@ -945,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) {
945 945
946 946
947static void parlist (LexState *ls) { 947static void parlist (LexState *ls) {
948 /* parlist -> [ param { ',' param } ] */ 948 /* parlist -> [ {NAME ','} (NAME | '...') ] */
949 FuncState *fs = ls->fs; 949 FuncState *fs = ls->fs;
950 Proto *f = fs->f; 950 Proto *f = fs->f;
951 int nparams = 0; 951 int nparams = 0;
@@ -953,12 +953,12 @@ static void parlist (LexState *ls) {
953 if (ls->t.token != ')') { /* is 'parlist' not empty? */ 953 if (ls->t.token != ')') { /* is 'parlist' not empty? */
954 do { 954 do {
955 switch (ls->t.token) { 955 switch (ls->t.token) {
956 case TK_NAME: { /* param -> NAME */ 956 case TK_NAME: {
957 new_localvar(ls, str_checkname(ls)); 957 new_localvar(ls, str_checkname(ls));
958 nparams++; 958 nparams++;
959 break; 959 break;
960 } 960 }
961 case TK_DOTS: { /* param -> '...' */ 961 case TK_DOTS: {
962 luaX_next(ls); 962 luaX_next(ls);
963 isvararg = 1; 963 isvararg = 1;
964 break; 964 break;
@@ -1330,13 +1330,13 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1330 } 1330 }
1331 } 1331 }
1332 else { /* table is a register */ 1332 else { /* table is a register */
1333 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) { 1333 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) {
1334 conflict = 1; /* table is the local being assigned now */ 1334 conflict = 1; /* table is the local being assigned now */
1335 lh->v.u.ind.t = extra; /* assignment will use safe copy */ 1335 lh->v.u.ind.t = extra; /* assignment will use safe copy */
1336 } 1336 }
1337 /* is index the local being assigned? */ 1337 /* is index the local being assigned? */
1338 if (lh->v.k == VINDEXED && v->k == VLOCAL && 1338 if (lh->v.k == VINDEXED && v->k == VLOCAL &&
1339 lh->v.u.ind.idx == v->u.var.sidx) { 1339 lh->v.u.ind.idx == v->u.var.ridx) {
1340 conflict = 1; 1340 conflict = 1;
1341 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 1341 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
1342 } 1342 }
@@ -1346,7 +1346,7 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1346 if (conflict) { 1346 if (conflict) {
1347 /* copy upvalue/local value to a temporary (in position 'extra') */ 1347 /* copy upvalue/local value to a temporary (in position 'extra') */
1348 if (v->k == VLOCAL) 1348 if (v->k == VLOCAL)
1349 luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0); 1349 luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0);
1350 else 1350 else
1351 luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); 1351 luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0);
1352 luaK_reserveregs(fs, 1); 1352 luaK_reserveregs(fs, 1);
@@ -1411,7 +1411,7 @@ static void gotostat (LexState *ls) {
1411 newgotoentry(ls, name, line, luaK_jump(fs)); 1411 newgotoentry(ls, name, line, luaK_jump(fs));
1412 else { /* found a label */ 1412 else { /* found a label */
1413 /* backward jump; will be resolved here */ 1413 /* backward jump; will be resolved here */
1414 int lblevel = stacklevel(fs, lb->nactvar); /* label level */ 1414 int lblevel = reglevel(fs, lb->nactvar); /* label level */
1415 if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ 1415 if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */
1416 luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); 1416 luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0);
1417 /* create jump and link it to the label */ 1417 /* create jump and link it to the label */
@@ -1488,7 +1488,7 @@ static void repeatstat (LexState *ls, int line) {
1488 if (bl2.upval) { /* upvalues? */ 1488 if (bl2.upval) { /* upvalues? */
1489 int exit = luaK_jump(fs); /* normal exit must jump over fix */ 1489 int exit = luaK_jump(fs); /* normal exit must jump over fix */
1490 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ 1490 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */
1491 luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0); 1491 luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0);
1492 condexit = luaK_jump(fs); /* repeat after closing upvalues */ 1492 condexit = luaK_jump(fs); /* repeat after closing upvalues */
1493 luaK_patchtohere(fs, exit); /* normal exit comes to here */ 1493 luaK_patchtohere(fs, exit); /* normal exit comes to here */
1494 } 1494 }
@@ -1623,59 +1623,21 @@ static void forstat (LexState *ls, int line) {
1623} 1623}
1624 1624
1625 1625
1626/*
1627** Check whether next instruction is a single jump (a 'break', a 'goto'
1628** to a forward label, or a 'goto' to a backward label with no variable
1629** to close). If so, set the name of the 'label' it is jumping to
1630** ("break" for a 'break') or to where it is jumping to ('target') and
1631** return true. If not a single jump, leave input unchanged, to be
1632** handled as a regular statement.
1633*/
1634static int issinglejump (LexState *ls, TString **label, int *target) {
1635 if (testnext(ls, TK_BREAK)) { /* a break? */
1636 *label = luaS_newliteral(ls->L, "break");
1637 return 1;
1638 }
1639 else if (ls->t.token != TK_GOTO || luaX_lookahead(ls) != TK_NAME)
1640 return 0; /* not a valid goto */
1641 else {
1642 TString *lname = ls->lookahead.seminfo.ts; /* label's id */
1643 Labeldesc *lb = findlabel(ls, lname);
1644 if (lb) { /* a backward jump? */
1645 /* does it need to close variables? */
1646 if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar))
1647 return 0; /* not a single jump; cannot optimize */
1648 *target = lb->pc;
1649 }
1650 else /* jump forward */
1651 *label = lname;
1652 luaX_next(ls); /* skip goto */
1653 luaX_next(ls); /* skip name */
1654 return 1;
1655 }
1656}
1657
1658
1659static void test_then_block (LexState *ls, int *escapelist) { 1626static void test_then_block (LexState *ls, int *escapelist) {
1660 /* test_then_block -> [IF | ELSEIF] cond THEN block */ 1627 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1661 BlockCnt bl; 1628 BlockCnt bl;
1662 int line;
1663 FuncState *fs = ls->fs; 1629 FuncState *fs = ls->fs;
1664 TString *jlb = NULL;
1665 int target = NO_JUMP;
1666 expdesc v; 1630 expdesc v;
1667 int jf; /* instruction to skip 'then' code (if condition is false) */ 1631 int jf; /* instruction to skip 'then' code (if condition is false) */
1668 luaX_next(ls); /* skip IF or ELSEIF */ 1632 luaX_next(ls); /* skip IF or ELSEIF */
1669 expr(ls, &v); /* read condition */ 1633 expr(ls, &v); /* read condition */
1670 checknext(ls, TK_THEN); 1634 checknext(ls, TK_THEN);
1671 line = ls->linenumber; 1635 if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */
1672 if (issinglejump(ls, &jlb, &target)) { /* 'if x then goto' ? */ 1636 int line = ls->linenumber;
1673 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ 1637 luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */
1638 luaX_next(ls); /* skip 'break' */
1674 enterblock(fs, &bl, 0); /* must enter block before 'goto' */ 1639 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1675 if (jlb != NULL) /* forward jump? */ 1640 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t);
1676 newgotoentry(ls, jlb, line, v.t); /* will be resolved later */
1677 else /* backward jump */
1678 luaK_patchlist(fs, v.t, target); /* jump directly to 'target' */
1679 while (testnext(ls, ';')) {} /* skip semicolons */ 1641 while (testnext(ls, ';')) {} /* skip semicolons */
1680 if (block_follow(ls, 0)) { /* jump is the entire block? */ 1642 if (block_follow(ls, 0)) { /* jump is the entire block? */
1681 leaveblock(fs); 1643 leaveblock(fs);
@@ -1684,7 +1646,7 @@ static void test_then_block (LexState *ls, int *escapelist) {
1684 else /* must skip over 'then' part if condition is false */ 1646 else /* must skip over 'then' part if condition is false */
1685 jf = luaK_jump(fs); 1647 jf = luaK_jump(fs);
1686 } 1648 }
1687 else { /* regular case (not a jump) */ 1649 else { /* regular case (not a break) */
1688 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ 1650 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1689 enterblock(fs, &bl, 0); 1651 enterblock(fs, &bl, 0);
1690 jf = v.f; 1652 jf = v.f;
@@ -1746,13 +1708,13 @@ static void checktoclose (LexState *ls, int level) {
1746 FuncState *fs = ls->fs; 1708 FuncState *fs = ls->fs;
1747 markupval(fs, level + 1); 1709 markupval(fs, level + 1);
1748 fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ 1710 fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */
1749 luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0); 1711 luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0);
1750 } 1712 }
1751} 1713}
1752 1714
1753 1715
1754static void localstat (LexState *ls) { 1716static void localstat (LexState *ls) {
1755 /* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ 1717 /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */
1756 FuncState *fs = ls->fs; 1718 FuncState *fs = ls->fs;
1757 int toclose = -1; /* index of to-be-closed variable (if any) */ 1719 int toclose = -1; /* index of to-be-closed variable (if any) */
1758 Vardesc *var; /* last variable */ 1720 Vardesc *var; /* last variable */
diff --git a/src/lua/lparser.h b/src/lua/lparser.h
index 618cb01..5e4500f 100644
--- a/src/lua/lparser.h
+++ b/src/lua/lparser.h
@@ -23,7 +23,7 @@
23 23
24/* kinds of variables/expressions */ 24/* kinds of variables/expressions */
25typedef enum { 25typedef enum {
26 VVOID, /* when 'expdesc' describes the last expression a list, 26 VVOID, /* when 'expdesc' describes the last expression of a list,
27 this kind means an empty list (so, no expression) */ 27 this kind means an empty list (so, no expression) */
28 VNIL, /* constant nil */ 28 VNIL, /* constant nil */
29 VTRUE, /* constant true */ 29 VTRUE, /* constant true */
@@ -35,10 +35,11 @@ typedef enum {
35 (string is fixed by the lexer) */ 35 (string is fixed by the lexer) */
36 VNONRELOC, /* expression has its value in a fixed register; 36 VNONRELOC, /* expression has its value in a fixed register;
37 info = result register */ 37 info = result register */
38 VLOCAL, /* local variable; var.sidx = stack index (local register); 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 VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 40 VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
41 VCONST, /* compile-time constant; info = absolute index in 'actvar.arr' */ 41 VCONST, /* compile-time <const> variable;
42 info = absolute index in 'actvar.arr' */
42 VINDEXED, /* indexed variable; 43 VINDEXED, /* indexed variable;
43 ind.t = table register; 44 ind.t = table register;
44 ind.idx = key's R index */ 45 ind.idx = key's R index */
@@ -76,7 +77,7 @@ typedef struct expdesc {
76 lu_byte t; /* table (register or upvalue) */ 77 lu_byte t; /* table (register or upvalue) */
77 } ind; 78 } ind;
78 struct { /* for local variables */ 79 struct { /* for local variables */
79 lu_byte sidx; /* index in the stack */ 80 lu_byte ridx; /* register holding the variable */
80 unsigned short vidx; /* compiler index (in 'actvar.arr') */ 81 unsigned short vidx; /* compiler index (in 'actvar.arr') */
81 } var; 82 } var;
82 } u; 83 } u;
@@ -96,7 +97,7 @@ typedef union Vardesc {
96 struct { 97 struct {
97 TValuefields; /* constant value (if it is a compile-time constant) */ 98 TValuefields; /* constant value (if it is a compile-time constant) */
98 lu_byte kind; 99 lu_byte kind;
99 lu_byte sidx; /* index of the variable in the stack */ 100 lu_byte ridx; /* register holding the variable */
100 short pidx; /* index of the variable in the Proto's 'locvars' array */ 101 short pidx; /* index of the variable in the Proto's 'locvars' array */
101 TString *name; /* variable name */ 102 TString *name; /* variable name */
102 } vd; 103 } vd;
diff --git a/src/lua/lstate.c b/src/lua/lstate.c
index 4227429..1596b51 100644
--- a/src/lua/lstate.c
+++ b/src/lua/lstate.c
@@ -181,7 +181,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
181 int i; CallInfo *ci; 181 int i; CallInfo *ci;
182 /* initialize stack array */ 182 /* initialize stack array */
183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); 183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
184 for (i = 0; i < BASIC_STACK_SIZE; i++) 184 for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
185 setnilvalue(s2v(L1->stack + i)); /* erase new stack */ 185 setnilvalue(s2v(L1->stack + i)); /* erase new stack */
186 L1->top = L1->stack; 186 L1->top = L1->stack;
187 L1->stack_last = L1->stack + BASIC_STACK_SIZE; 187 L1->stack_last = L1->stack + BASIC_STACK_SIZE;
@@ -213,17 +213,14 @@ static void freestack (lua_State *L) {
213** Create registry table and its predefined values 213** Create registry table and its predefined values
214*/ 214*/
215static void init_registry (lua_State *L, global_State *g) { 215static void init_registry (lua_State *L, global_State *g) {
216 TValue temp;
217 /* create registry */ 216 /* create registry */
218 Table *registry = luaH_new(L); 217 Table *registry = luaH_new(L);
219 sethvalue(L, &g->l_registry, registry); 218 sethvalue(L, &g->l_registry, registry);
220 luaH_resize(L, registry, LUA_RIDX_LAST, 0); 219 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
221 /* registry[LUA_RIDX_MAINTHREAD] = L */ 220 /* registry[LUA_RIDX_MAINTHREAD] = L */
222 setthvalue(L, &temp, L); /* temp = L */ 221 setthvalue(L, &registry->array[LUA_RIDX_MAINTHREAD - 1], L);
223 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); 222 /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */
224 /* registry[LUA_RIDX_GLOBALS] = table of globals */ 223 sethvalue(L, &registry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L));
225 sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
226 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
227} 224}
228 225
229 226
diff --git a/src/lua/ltable.c b/src/lua/ltable.c
index 38bee1d..e9410f9 100644
--- a/src/lua/ltable.c
+++ b/src/lua/ltable.c
@@ -166,17 +166,24 @@ static Node *mainpositionTV (const Table *t, const TValue *key) {
166 166
167 167
168/* 168/*
169** Check whether key 'k1' is equal to the key in node 'n2'. 169** Check whether key 'k1' is equal to the key in node 'n2'. This
170** This equality is raw, so there are no metamethods. Floats 170** equality is raw, so there are no metamethods. Floats with integer
171** with integer values have been normalized, so integers cannot 171** values have been normalized, so integers cannot be equal to
172** be equal to floats. It is assumed that 'eqshrstr' is simply 172** floats. It is assumed that 'eqshrstr' is simply pointer equality, so
173** pointer equality, so that short strings are handled in the 173** that short strings are handled in the default case.
174** default case.
175** A true 'deadok' means to accept dead keys as equal to their original 174** A true 'deadok' means to accept dead keys as equal to their original
176** values, which can only happen if the original key was collectable. 175** values. All dead keys are compared in the default case, by pointer
177** All dead values are compared in the default case, by pointer 176** identity. (Only collectable objects can produce dead keys.) Note that
178** identity. (Note that dead long strings are also compared by 177** dead long strings are also compared by identity.
179** identity). 178** Once a key is dead, its corresponding value may be collected, and
179** then another value can be created with the same address. If this
180** other value is given to 'next', 'equalkey' will signal a false
181** positive. In a regular traversal, this situation should never happen,
182** as all keys given to 'next' came from the table itself, and therefore
183** could not have been collected. Outside a regular traversal, we
184** have garbage in, garbage out. What is relevant is that this false
185** positive does not break anything. (In particular, 'next' will return
186** some other valid item on the table or nil.)
180*/ 187*/
181static int equalkey (const TValue *k1, const Node *n2, int deadok) { 188static int equalkey (const TValue *k1, const Node *n2, int deadok) {
182 if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ 189 if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */
@@ -478,7 +485,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
478 already present in the table */ 485 already present in the table */
479 TValue k; 486 TValue k;
480 getnodekey(L, &k, old); 487 getnodekey(L, &k, old);
481 setobjt2t(L, luaH_set(L, t, &k), gval(old)); 488 luaH_set(L, t, &k, gval(old));
482 } 489 }
483 } 490 }
484} 491}
@@ -625,7 +632,7 @@ static Node *getfreepos (Table *t) {
625** put new key in its main position; otherwise (colliding node is in its main 632** put new key in its main position; otherwise (colliding node is in its main
626** position), new key goes to an empty position. 633** position), new key goes to an empty position.
627*/ 634*/
628TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { 635void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
629 Node *mp; 636 Node *mp;
630 TValue aux; 637 TValue aux;
631 if (unlikely(ttisnil(key))) 638 if (unlikely(ttisnil(key)))
@@ -647,7 +654,8 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
647 if (f == NULL) { /* cannot find a free place? */ 654 if (f == NULL) { /* cannot find a free place? */
648 rehash(L, t, key); /* grow table */ 655 rehash(L, t, key); /* grow table */
649 /* whatever called 'newkey' takes care of TM cache */ 656 /* whatever called 'newkey' takes care of TM cache */
650 return luaH_set(L, t, key); /* insert key into grown table */ 657 luaH_set(L, t, key, value); /* insert key into grown table */
658 return;
651 } 659 }
652 lua_assert(!isdummy(t)); 660 lua_assert(!isdummy(t));
653 othern = mainposition(t, keytt(mp), &keyval(mp)); 661 othern = mainposition(t, keytt(mp), &keyval(mp));
@@ -675,7 +683,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
675 setnodekey(L, mp, key); 683 setnodekey(L, mp, key);
676 luaC_barrierback(L, obj2gco(t), key); 684 luaC_barrierback(L, obj2gco(t), key);
677 lua_assert(isempty(gval(mp))); 685 lua_assert(isempty(gval(mp)));
678 return gval(mp); 686 setobj2t(L, gval(mp), value);
679} 687}
680 688
681 689
@@ -763,28 +771,39 @@ const TValue *luaH_get (Table *t, const TValue *key) {
763 771
764 772
765/* 773/*
774** Finish a raw "set table" operation, where 'slot' is where the value
775** should have been (the result of a previous "get table").
776** Beware: when using this function you probably need to check a GC
777** barrier and invalidate the TM cache.
778*/
779void luaH_finishset (lua_State *L, Table *t, const TValue *key,
780 const TValue *slot, TValue *value) {
781 if (isabstkey(slot))
782 luaH_newkey(L, t, key, value);
783 else
784 setobj2t(L, cast(TValue *, slot), value);
785}
786
787
788/*
766** beware: when using this function you probably need to check a GC 789** beware: when using this function you probably need to check a GC
767** barrier and invalidate the TM cache. 790** barrier and invalidate the TM cache.
768*/ 791*/
769TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 792void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
770 const TValue *p = luaH_get(t, key); 793 const TValue *slot = luaH_get(t, key);
771 if (!isabstkey(p)) 794 luaH_finishset(L, t, key, slot, value);
772 return cast(TValue *, p);
773 else return luaH_newkey(L, t, key);
774} 795}
775 796
776 797
777void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 798void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
778 const TValue *p = luaH_getint(t, key); 799 const TValue *p = luaH_getint(t, key);
779 TValue *cell; 800 if (isabstkey(p)) {
780 if (!isabstkey(p))
781 cell = cast(TValue *, p);
782 else {
783 TValue k; 801 TValue k;
784 setivalue(&k, key); 802 setivalue(&k, key);
785 cell = luaH_newkey(L, t, &k); 803 luaH_newkey(L, t, &k, value);
786 } 804 }
787 setobj2t(L, cell, value); 805 else
806 setobj2t(L, cast(TValue *, p), value);
788} 807}
789 808
790 809
diff --git a/src/lua/ltable.h b/src/lua/ltable.h
index c0060f4..7bbbcb2 100644
--- a/src/lua/ltable.h
+++ b/src/lua/ltable.h
@@ -41,8 +41,12 @@ LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
41LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 41LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
42LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 42LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
43LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 43LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
44LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 44LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
45LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 45 TValue *value);
46LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
47 TValue *value);
48LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
49 const TValue *slot, TValue *value);
46LUAI_FUNC Table *luaH_new (lua_State *L); 50LUAI_FUNC Table *luaH_new (lua_State *L);
47LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 51LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
48 unsigned int nhsize); 52 unsigned int nhsize);
diff --git a/src/lua/lualib.h b/src/lua/lualib.h
index eb08b53..2625529 100644
--- a/src/lua/lualib.h
+++ b/src/lua/lualib.h
@@ -49,10 +49,4 @@ LUAMOD_API int (luaopen_package) (lua_State *L);
49LUALIB_API void (luaL_openlibs) (lua_State *L); 49LUALIB_API void (luaL_openlibs) (lua_State *L);
50 50
51 51
52
53#if !defined(lua_assert)
54#define lua_assert(x) ((void)0)
55#endif
56
57
58#endif 52#endif
diff --git a/src/lua/lvm.c b/src/lua/lvm.c
index aa3b22b..ccebdbe 100644
--- a/src/lua/lvm.c
+++ b/src/lua/lvm.c
@@ -337,10 +337,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
337 lua_assert(isempty(slot)); /* slot must be empty */ 337 lua_assert(isempty(slot)); /* slot must be empty */
338 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 338 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
339 if (tm == NULL) { /* no metamethod? */ 339 if (tm == NULL) { /* no metamethod? */
340 if (isabstkey(slot)) /* no previous entry? */ 340 luaH_finishset(L, h, key, slot, val); /* set new value */
341 slot = luaH_newkey(L, h, key); /* create one */
342 /* no metamethod and (now) there is an entry with given key */
343 setobj2t(L, cast(TValue *, slot), val); /* set its new value */
344 invalidateTMcache(h); 341 invalidateTMcache(h);
345 luaC_barrierback(L, obj2gco(h), val); 342 luaC_barrierback(L, obj2gco(h), val);
346 return; 343 return;