3030
3131
3232
33- /* maximum number of variable declarationss per function (must be
33+ /* maximum number of variable declarations per function (must be
3434 smaller than 250, due to the bytecode format) */
3535#define MAXVARS 200
3636
@@ -197,7 +197,7 @@ static int new_varkind (LexState *ls, TString *name, lu_byte kind) {
197197 Dyndata * dyd = ls -> dyd ;
198198 Vardesc * var ;
199199 luaM_growvector (L , dyd -> actvar .arr , dyd -> actvar .n + 1 ,
200- dyd -> actvar .size , Vardesc , SHRT_MAX , "variable declarationss " );
200+ dyd -> actvar .size , Vardesc , SHRT_MAX , "variable declarations " );
201201 var = & dyd -> actvar .arr [dyd -> actvar .n ++ ];
202202 var -> vd .kind = kind ; /* default */
203203 var -> vd .name = name ;
@@ -485,6 +485,20 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
485485}
486486
487487
488+ static 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+
488502/*
489503** Find a variable with the given name 'n', handling global variables
490504** too.
@@ -494,18 +508,11 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) {
494508 init_exp (var , VGLOBAL , -1 ); /* global by default */
495509 singlevaraux (fs , varname , var , 1 );
496510 if (var -> k == VGLOBAL ) { /* global name? */
497- expdesc key ;
498511 int info = var -> u .info ;
499512 /* global by default in the scope of a global declaration? */
500513 if (info == -2 )
501514 luaK_semerror (ls , "variable '%s' not declared" , getstr (varname ));
502- singlevaraux (fs , ls -> envn , var , 1 ); /* get environment variable */
503- if (var -> k == VGLOBAL )
504- luaK_semerror (ls , "_ENV is global when accessing variable '%s'" ,
505- getstr (varname ));
506- luaK_exp2anyregup (fs , var ); /* but could be a constant */
507- codestring (& key , varname ); /* key is variable name */
508- luaK_indexed (fs , var , & key ); /* env[varname] */
515+ buildglobal (ls , varname , var );
509516 if (info != -1 && ls -> dyd -> actvar .arr [info ].vd .kind == GDKCONST )
510517 var -> u .ind .ro = 1 ; /* mark variable as read-only */
511518 else /* anyway must be a global */
@@ -665,7 +672,7 @@ static void createlabel (LexState *ls, TString *name, int line, int last) {
665672
666673
667674/*
668- ** Traverse the pending goto's of the finishing block checking whether
675+ ** Traverse the pending gotos of the finishing block checking whether
669676** each match some label of that block. Those that do not match are
670677** "exported" to the outer block, to be solved there. In particular,
671678** its 'nactvar' is updated with the level of the inner block,
@@ -1435,6 +1442,15 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
14351442 }
14361443}
14371444
1445+
1446+ /* Create code to store the "top" register in 'var' */
1447+ static 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+
14381454/*
14391455** Parse and compile a multiple assignment. The first "variable"
14401456** (a 'suffixedexp') was already read by the caller.
@@ -1468,8 +1484,7 @@ static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
14681484 return ; /* avoid default */
14691485 }
14701486 }
1471- init_exp (& e , VNONRELOC , ls -> fs -> freereg - 1 ); /* default assignment */
1472- luaK_storevar (ls -> fs , & lh -> v , & e );
1487+ storevartop (ls -> fs , & lh -> v ); /* default assignment */
14731488}
14741489
14751490
@@ -1821,25 +1836,45 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
18211836}
18221837
18231838
1839+ static 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+
18241865static void globalstat (LexState * ls ) {
18251866 /* globalstat -> (GLOBAL) attrib '*'
18261867 globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */
18271868 FuncState * fs = ls -> fs ;
18281869 /* get prefixed attribute (if any); default is regular global variable */
18291870 lu_byte defkind = getglobalattribute (ls , GDKREG );
1830- if (testnext (ls , '*' )) {
1871+ if (!testnext (ls , '*' ))
1872+ globalnames (ls , defkind );
1873+ else {
18311874 /* use NULL as name to represent '*' entries */
18321875 new_varkind (ls , NULL , defkind );
18331876 fs -> nactvar ++ ; /* activate declaration */
18341877 }
1835- else {
1836- do { /* list of names */
1837- TString * vname = str_checkname (ls );
1838- lu_byte kind = getglobalattribute (ls , defkind );
1839- new_varkind (ls , vname , kind );
1840- fs -> nactvar ++ ; /* activate declaration */
1841- } while (testnext (ls , ',' ));
1842- }
18431878}
18441879
18451880
@@ -1850,7 +1885,7 @@ static void globalfunc (LexState *ls, int line) {
18501885 TString * fname = str_checkname (ls );
18511886 new_varkind (ls , fname , GDKREG ); /* declare global variable */
18521887 fs -> nactvar ++ ; /* enter its scope */
1853- buildvar (ls , fname , & var );
1888+ buildglobal (ls , fname , & var );
18541889 body (ls , & b , 0 , ls -> linenumber ); /* compile and return closure in 'b' */
18551890 luaK_storevar (fs , & var , & b );
18561891 luaK_fixline (fs , line ); /* definition "happens" in the first line */
0 commit comments