aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c2
-rw-r--r--lparser.c41
-rw-r--r--testes/goto.lua22
3 files changed, 52 insertions, 13 deletions
diff --git a/lcode.c b/lcode.c
index 429d4f80..7c63abb2 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1242,7 +1242,7 @@ static void codenot (FuncState *fs, expdesc *e) {
1242** Check whether expression 'e' is a short literal string 1242** Check whether expression 'e' is a short literal string
1243*/ 1243*/
1244static int isKstr (FuncState *fs, expdesc *e) { 1244static int isKstr (FuncState *fs, expdesc *e) {
1245 return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && 1245 return (e->k == VK && !hasjumps(e) && e->u.info <= MAXINDEXRK &&
1246 ttisshrstring(&fs->f->k[e->u.info])); 1246 ttisshrstring(&fs->f->k[e->u.info]));
1247} 1247}
1248 1248
diff --git a/lparser.c b/lparser.c
index dc646fea..e3538c16 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1875,6 +1875,33 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
1875} 1875}
1876 1876
1877 1877
1878/*
1879** Recursively traverse list of globals to be initalized. When
1880** going, generate table description for the global. In the end,
1881** after all indices have been generated, read list of initializing
1882** expressions. When returning, generate the assignment of the value on
1883** the stack to the corresponding table description. 'n' is the variable
1884** being handled, range [0, nvars - 1].
1885*/
1886static void initglobal (LexState *ls, int nvars, int firstidx, int n) {
1887 if (n == nvars) { /* traversed all variables? */
1888 expdesc e;
1889 int nexps = explist(ls, &e); /* read list of expressions */
1890 adjust_assign(ls, nvars, nexps, &e);
1891 }
1892 else { /* handle variable 'n' */
1893 FuncState *fs = ls->fs;
1894 expdesc var;
1895 TString *varname = getlocalvardesc(fs, firstidx + n)->vd.name;
1896 buildglobal(ls, varname, &var); /* create global variable in 'var' */
1897 enterlevel(ls); /* control recursion depth */
1898 initglobal(ls, nvars, firstidx, n + 1);
1899 leavelevel(ls);
1900 storevartop(fs, &var);
1901 }
1902}
1903
1904
1878static void globalnames (LexState *ls, lu_byte defkind) { 1905static void globalnames (LexState *ls, lu_byte defkind) {
1879 FuncState *fs = ls->fs; 1906 FuncState *fs = ls->fs;
1880 int nvars = 0; 1907 int nvars = 0;
@@ -1885,18 +1912,8 @@ static void globalnames (LexState *ls, lu_byte defkind) {
1885 lastidx = new_varkind(ls, vname, kind); 1912 lastidx = new_varkind(ls, vname, kind);
1886 nvars++; 1913 nvars++;
1887 } while (testnext(ls, ',')); 1914 } while (testnext(ls, ','));
1888 if (testnext(ls, '=')) { /* initialization? */ 1915 if (testnext(ls, '=')) /* initialization? */
1889 expdesc e; 1916 initglobal(ls, nvars, lastidx - nvars + 1, 0);
1890 int i;
1891 int nexps = explist(ls, &e); /* read list of expressions */
1892 adjust_assign(ls, nvars, nexps, &e);
1893 for (i = 0; i < nvars; i++) { /* for each variable */
1894 expdesc var;
1895 TString *varname = getlocalvardesc(fs, lastidx - i)->vd.name;
1896 buildglobal(ls, varname, &var); /* create global variable in 'var' */
1897 storevartop(fs, &var);
1898 }
1899 }
1900 fs->nactvar = cast_short(fs->nactvar + nvars); /* activate declaration */ 1917 fs->nactvar = cast_short(fs->nactvar + nvars); /* activate declaration */
1901} 1918}
1902 1919
diff --git a/testes/goto.lua b/testes/goto.lua
index 3310314d..a692a623 100644
--- a/testes/goto.lua
+++ b/testes/goto.lua
@@ -432,5 +432,27 @@ do print "testing initialization in global declarations"
432 _ENV.a, _ENV.b, _ENV.c, _ENV.d = nil -- erase these globals 432 _ENV.a, _ENV.b, _ENV.c, _ENV.d = nil -- erase these globals
433end 433end
434 434
435do
436 global table, string
437 -- global initialization when names don't fit in K
438
439 -- to fill constant table
440 local code = {}
441 for i = 1, 300 do code[i] = "'" .. i .. "'" end
442 code = table.concat(code, ",")
443 code = string.format([[
444 return function (_ENV)
445 local dummy = {%s} -- fill initial positions in constant table,
446 -- so that initialization must use registers for global names
447 global a, b, c = 10, 20, 30
448 end]], code)
449
450 local fun = assert(load(code))()
451
452 local env = {}
453 fun(env)
454 assert(env.a == 10 and env.b == 20 and env.c == 30)
455end
456
435print'OK' 457print'OK'
436 458