aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-10-29 13:14:48 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-10-29 13:14:48 -0300
commitd4eff00234dc55dac4cb86b6187f5607c1254f9b (patch)
tree3f080f35cfd23249166a4311946cf0ea766d71d0 /lparser.c
parentfca974486d12aa29bb6d731fdb5b25055157ece8 (diff)
downloadlua-d4eff00234dc55dac4cb86b6187f5607c1254f9b.tar.gz
lua-d4eff00234dc55dac4cb86b6187f5607c1254f9b.tar.bz2
lua-d4eff00234dc55dac4cb86b6187f5607c1254f9b.zip
Fixed initialization of global variables
When calling 'luaK_storevar', the 'expdesc' for the variable must be created before the one for the expression, to satisfy the assumptions for register allocation. So, in a statement like 'global a = exp', where 'a' is actually '_ENV.a', this variable must be handled before the initializing expression 'exp'.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c41
1 files changed, 29 insertions, 12 deletions
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