aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-21 12:04:59 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-21 12:04:59 -0300
commitb2f7b3b79f3117885b265575f6c5dbf934757797 (patch)
treead7ac30fb9a05e1e6635110f03c45b9cd41190c8 /lparser.c
parent540d8052265776451bb9f0ab4dee4ec860563cbe (diff)
downloadlua-b2f7b3b79f3117885b265575f6c5dbf934757797.tar.gz
lua-b2f7b3b79f3117885b265575f6c5dbf934757797.tar.bz2
lua-b2f7b3b79f3117885b265575f6c5dbf934757797.zip
Control variables in for loops are read only
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/lparser.c b/lparser.c
index 24668c24..79b2317b 100644
--- a/lparser.c
+++ b/lparser.c
@@ -187,10 +187,10 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
187 187
188 188
189/* 189/*
190** Create a new local variable with the given 'name'. Return its index 190** Create a new local variable with the given 'name' and given 'kind'.
191** in the function. 191** Return its index in the function.
192*/ 192*/
193static int new_localvar (LexState *ls, TString *name) { 193static int new_localvarkind (LexState *ls, TString *name, int kind) {
194 lua_State *L = ls->L; 194 lua_State *L = ls->L;
195 FuncState *fs = ls->fs; 195 FuncState *fs = ls->fs;
196 Dyndata *dyd = ls->dyd; 196 Dyndata *dyd = ls->dyd;
@@ -200,11 +200,19 @@ static int new_localvar (LexState *ls, TString *name) {
200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); 201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
202 var = &dyd->actvar.arr[dyd->actvar.n++]; 202 var = &dyd->actvar.arr[dyd->actvar.n++];
203 var->vd.kind = VDKREG; /* default */ 203 var->vd.kind = kind; /* default */
204 var->vd.name = name; 204 var->vd.name = name;
205 return dyd->actvar.n - 1 - fs->firstlocal; 205 return dyd->actvar.n - 1 - fs->firstlocal;
206} 206}
207 207
208
209/*
210** Create a new local variable with the given 'name' and regular kind.
211*/
212static int new_localvar (LexState *ls, TString *name) {
213 return new_localvarkind(ls, name, VDKREG);
214}
215
208#define new_localvarliteral(ls,v) \ 216#define new_localvarliteral(ls,v) \
209 new_localvar(ls, \ 217 new_localvar(ls, \
210 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 218 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
@@ -1573,7 +1581,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1573 new_localvarliteral(ls, "(for state)"); 1581 new_localvarliteral(ls, "(for state)");
1574 new_localvarliteral(ls, "(for state)"); 1582 new_localvarliteral(ls, "(for state)");
1575 new_localvarliteral(ls, "(for state)"); 1583 new_localvarliteral(ls, "(for state)");
1576 new_localvar(ls, varname); 1584 new_localvarkind(ls, varname, RDKCONST); /* control variable */
1577 checknext(ls, '='); 1585 checknext(ls, '=');
1578 exp1(ls); /* initial value */ 1586 exp1(ls); /* initial value */
1579 checknext(ls, ','); 1587 checknext(ls, ',');
@@ -1601,8 +1609,8 @@ static void forlist (LexState *ls, TString *indexname) {
1601 new_localvarliteral(ls, "(for state)"); 1609 new_localvarliteral(ls, "(for state)");
1602 new_localvarliteral(ls, "(for state)"); 1610 new_localvarliteral(ls, "(for state)");
1603 new_localvarliteral(ls, "(for state)"); 1611 new_localvarliteral(ls, "(for state)");
1604 /* create declared variables */ 1612 new_localvarkind(ls, indexname, RDKCONST); /* control variable */
1605 new_localvar(ls, indexname); 1613 /* other declared variables */
1606 while (testnext(ls, ',')) { 1614 while (testnext(ls, ',')) {
1607 new_localvar(ls, str_checkname(ls)); 1615 new_localvar(ls, str_checkname(ls));
1608 nvars++; 1616 nvars++;
@@ -1728,14 +1736,14 @@ static void localstat (LexState *ls) {
1728 FuncState *fs = ls->fs; 1736 FuncState *fs = ls->fs;
1729 int toclose = -1; /* index of to-be-closed variable (if any) */ 1737 int toclose = -1; /* index of to-be-closed variable (if any) */
1730 Vardesc *var; /* last variable */ 1738 Vardesc *var; /* last variable */
1731 int vidx, kind; /* index and kind of last variable */ 1739 int vidx; /* index of last variable */
1732 int nvars = 0; 1740 int nvars = 0;
1733 int nexps; 1741 int nexps;
1734 expdesc e; 1742 expdesc e;
1735 do { 1743 do {
1736 vidx = new_localvar(ls, str_checkname(ls)); 1744 TString *vname = str_checkname(ls);
1737 kind = getlocalattribute(ls); 1745 int kind = getlocalattribute(ls);
1738 getlocalvardesc(fs, vidx)->vd.kind = kind; 1746 vidx = new_localvarkind(ls, vname, kind);
1739 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1747 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1740 if (toclose != -1) /* one already present? */ 1748 if (toclose != -1) /* one already present? */
1741 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1749 luaK_semerror(ls, "multiple to-be-closed variables in local list");