Mon Apr 17 20:07:32 2023 UTC ()
lua: apply upstream bugfix for "'break' may not properly close variable in a 'for' loop."

Function 'leaveblock' was generating "break" label before removing
variables from the closing block. If 'createlabel' created a 'close'
instruction (which it did when matching a goto/break that exited
the scope of an upvalue), that instruction would use the wrong level.


(nikita)
diff -r1.13 -r1.14 src/external/mit/lua/dist/src/lparser.c

cvs diff -r1.13 -r1.14 src/external/mit/lua/dist/src/lparser.c (switch to unified diff)

--- src/external/mit/lua/dist/src/lparser.c 2023/04/17 19:17:49 1.13
+++ src/external/mit/lua/dist/src/lparser.c 2023/04/17 20:07:32 1.14
@@ -1,1692 +1,1692 @@ @@ -1,1692 +1,1692 @@
1/* $NetBSD: lparser.c,v 1.13 2023/04/17 19:17:49 nikita Exp $ */ 1/* $NetBSD: lparser.c,v 1.14 2023/04/17 20:07:32 nikita Exp $ */
2 2
3/* 3/*
4** Id: lparser.c  4** Id: lparser.c
5** Lua Parser 5** Lua Parser
6** See Copyright Notice in lua.h 6** See Copyright Notice in lua.h
7*/ 7*/
8 8
9#define lparser_c 9#define lparser_c
10#define LUA_CORE 10#define LUA_CORE
11 11
12#include "lprefix.h" 12#include "lprefix.h"
13 13
14 14
15#ifndef _KERNEL 15#ifndef _KERNEL
16#include <limits.h> 16#include <limits.h>
17#include <string.h> 17#include <string.h>
18#endif /* _KERNEL */ 18#endif /* _KERNEL */
19 19
20#include "lua.h" 20#include "lua.h"
21 21
22#include "lcode.h" 22#include "lcode.h"
23#include "ldebug.h" 23#include "ldebug.h"
24#include "ldo.h" 24#include "ldo.h"
25#include "lfunc.h" 25#include "lfunc.h"
26#include "llex.h" 26#include "llex.h"
27#include "lmem.h" 27#include "lmem.h"
28#include "lobject.h" 28#include "lobject.h"
29#include "lopcodes.h" 29#include "lopcodes.h"
30#include "lparser.h" 30#include "lparser.h"
31#include "lstate.h" 31#include "lstate.h"
32#include "lstring.h" 32#include "lstring.h"
33#include "ltable.h" 33#include "ltable.h"
34 34
35 35
36 36
37/* maximum number of local variables per function (must be smaller 37/* maximum number of local variables per function (must be smaller
38 than 250, due to the bytecode format) */ 38 than 250, due to the bytecode format) */
39#define MAXVARS 200 39#define MAXVARS 200
40 40
41 41
42#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 42#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
43 43
44 44
45/* because all strings are unified by the scanner, the parser 45/* because all strings are unified by the scanner, the parser
46 can use pointer equality for string equality */ 46 can use pointer equality for string equality */
47#define eqstr(a,b) ((a) == (b)) 47#define eqstr(a,b) ((a) == (b))
48 48
49 49
50/* 50/*
51** nodes for block list (list of active blocks) 51** nodes for block list (list of active blocks)
52*/ 52*/
53typedef struct BlockCnt { 53typedef struct BlockCnt {
54 struct BlockCnt *previous; /* chain */ 54 struct BlockCnt *previous; /* chain */
55 int firstlabel; /* index of first label in this block */ 55 int firstlabel; /* index of first label in this block */
56 int firstgoto; /* index of first pending goto in this block */ 56 int firstgoto; /* index of first pending goto in this block */
57 lu_byte nactvar; /* # active locals outside the block */ 57 lu_byte nactvar; /* # active locals outside the block */
58 lu_byte upval; /* true if some variable in the block is an upvalue */ 58 lu_byte upval; /* true if some variable in the block is an upvalue */
59 lu_byte isloop; /* true if 'block' is a loop */ 59 lu_byte isloop; /* true if 'block' is a loop */
60 lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ 60 lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */
61} BlockCnt; 61} BlockCnt;
62 62
63 63
64 64
65/* 65/*
66** prototypes for recursive non-terminal functions 66** prototypes for recursive non-terminal functions
67*/ 67*/
68static void statement (LexState *ls); 68static void statement (LexState *ls);
69static void expr (LexState *ls, expdesc *v); 69static void expr (LexState *ls, expdesc *v);
70 70
71 71
72static l_noret error_expected (LexState *ls, int token) { 72static l_noret error_expected (LexState *ls, int token) {
73 luaX_syntaxerror(ls, 73 luaX_syntaxerror(ls,
74 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); 74 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
75} 75}
76 76
77 77
78static l_noret errorlimit (FuncState *fs, int limit, const char *what) { 78static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
79 lua_State *L = fs->ls->L; 79 lua_State *L = fs->ls->L;
80 const char *msg; 80 const char *msg;
81 int line = fs->f->linedefined; 81 int line = fs->f->linedefined;
82 const char *where = (line == 0) 82 const char *where = (line == 0)
83 ? "main function" 83 ? "main function"
84 : luaO_pushfstring(L, "function at line %d", line); 84 : luaO_pushfstring(L, "function at line %d", line);
85 msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", 85 msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
86 what, limit, where); 86 what, limit, where);
87 luaX_syntaxerror(fs->ls, msg); 87 luaX_syntaxerror(fs->ls, msg);
88} 88}
89 89
90 90
91static void checklimit (FuncState *fs, int v, int l, const char *what) { 91static void checklimit (FuncState *fs, int v, int l, const char *what) {
92 if (v > l) errorlimit(fs, l, what); 92 if (v > l) errorlimit(fs, l, what);
93} 93}
94 94
95 95
96/* 96/*
97** Test whether next token is 'c'; if so, skip it. 97** Test whether next token is 'c'; if so, skip it.
98*/ 98*/
99static int testnext (LexState *ls, int c) { 99static int testnext (LexState *ls, int c) {
100 if (ls->t.token == c) { 100 if (ls->t.token == c) {
101 luaX_next(ls); 101 luaX_next(ls);
102 return 1; 102 return 1;
103 } 103 }
104 else return 0; 104 else return 0;
105} 105}
106 106
107 107
108/* 108/*
109** Check that next token is 'c'. 109** Check that next token is 'c'.
110*/ 110*/
111static void check (LexState *ls, int c) { 111static void check (LexState *ls, int c) {
112 if (ls->t.token != c) 112 if (ls->t.token != c)
113 error_expected(ls, c); 113 error_expected(ls, c);
114} 114}
115 115
116 116
117/* 117/*
118** Check that next token is 'c' and skip it. 118** Check that next token is 'c' and skip it.
119*/ 119*/
120static void checknext (LexState *ls, int c) { 120static void checknext (LexState *ls, int c) {
121 check(ls, c); 121 check(ls, c);
122 luaX_next(ls); 122 luaX_next(ls);
123} 123}
124 124
125 125
126#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } 126#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
127 127
128 128
129/* 129/*
130** Check that next token is 'what' and skip it. In case of error, 130** Check that next token is 'what' and skip it. In case of error,
131** raise an error that the expected 'what' should match a 'who' 131** raise an error that the expected 'what' should match a 'who'
132** in line 'where' (if that is not the current line). 132** in line 'where' (if that is not the current line).
133*/ 133*/
134static void check_match (LexState *ls, int what, int who, int where) { 134static void check_match (LexState *ls, int what, int who, int where) {
135 if (l_unlikely(!testnext(ls, what))) { 135 if (l_unlikely(!testnext(ls, what))) {
136 if (where == ls->linenumber) /* all in the same line? */ 136 if (where == ls->linenumber) /* all in the same line? */
137 error_expected(ls, what); /* do not need a complex message */ 137 error_expected(ls, what); /* do not need a complex message */
138 else { 138 else {
139 luaX_syntaxerror(ls, luaO_pushfstring(ls->L, 139 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
140 "%s expected (to close %s at line %d)", 140 "%s expected (to close %s at line %d)",
141 luaX_token2str(ls, what), luaX_token2str(ls, who), where)); 141 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
142 } 142 }
143 } 143 }
144} 144}
145 145
146 146
147static TString *str_checkname (LexState *ls) { 147static TString *str_checkname (LexState *ls) {
148 TString *ts; 148 TString *ts;
149 check(ls, TK_NAME); 149 check(ls, TK_NAME);
150 ts = ls->t.seminfo.ts; 150 ts = ls->t.seminfo.ts;
151 luaX_next(ls); 151 luaX_next(ls);
152 return ts; 152 return ts;
153} 153}
154 154
155 155
156static void init_exp (expdesc *e, expkind k, int i) { 156static void init_exp (expdesc *e, expkind k, int i) {
157 e->f = e->t = NO_JUMP; 157 e->f = e->t = NO_JUMP;
158 e->k = k; 158 e->k = k;
159 e->u.info = i; 159 e->u.info = i;
160} 160}
161 161
162 162
163static void codestring (expdesc *e, TString *s) { 163static void codestring (expdesc *e, TString *s) {
164 e->f = e->t = NO_JUMP; 164 e->f = e->t = NO_JUMP;
165 e->k = VKSTR; 165 e->k = VKSTR;
166 e->u.strval = s; 166 e->u.strval = s;
167} 167}
168 168
169 169
170static void codename (LexState *ls, expdesc *e) { 170static void codename (LexState *ls, expdesc *e) {
171 codestring(e, str_checkname(ls)); 171 codestring(e, str_checkname(ls));
172} 172}
173 173
174 174
175/* 175/*
176** Register a new local variable in the active 'Proto' (for debug 176** Register a new local variable in the active 'Proto' (for debug
177** information). 177** information).
178*/ 178*/
179static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) { 179static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
180 Proto *f = fs->f; 180 Proto *f = fs->f;
181 int oldsize = f->sizelocvars; 181 int oldsize = f->sizelocvars;
182 luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars, 182 luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars,
183 LocVar, SHRT_MAX, "local variables"); 183 LocVar, SHRT_MAX, "local variables");
184 while (oldsize < f->sizelocvars) 184 while (oldsize < f->sizelocvars)
185 f->locvars[oldsize++].varname = NULL; 185 f->locvars[oldsize++].varname = NULL;
186 f->locvars[fs->ndebugvars].varname = varname; 186 f->locvars[fs->ndebugvars].varname = varname;
187 f->locvars[fs->ndebugvars].startpc = fs->pc; 187 f->locvars[fs->ndebugvars].startpc = fs->pc;
188 luaC_objbarrier(ls->L, f, varname); 188 luaC_objbarrier(ls->L, f, varname);
189 return fs->ndebugvars++; 189 return fs->ndebugvars++;
190} 190}
191 191
192 192
193/* 193/*
194** Create a new local variable with the given 'name'. Return its index 194** Create a new local variable with the given 'name'. Return its index
195** in the function. 195** in the function.
196*/ 196*/
197static int new_localvar (LexState *ls, TString *name) { 197static int new_localvar (LexState *ls, TString *name) {
198 lua_State *L = ls->L; 198 lua_State *L = ls->L;
199 FuncState *fs = ls->fs; 199 FuncState *fs = ls->fs;
200 Dyndata *dyd = ls->dyd; 200 Dyndata *dyd = ls->dyd;
201 Vardesc *var; 201 Vardesc *var;
202 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, 202 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
203 MAXVARS, "local variables"); 203 MAXVARS, "local variables");
204 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 204 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
205 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); 205 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
206 var = &dyd->actvar.arr[dyd->actvar.n++]; 206 var = &dyd->actvar.arr[dyd->actvar.n++];
207 var->vd.kind = VDKREG; /* default */ 207 var->vd.kind = VDKREG; /* default */
208 var->vd.name = name; 208 var->vd.name = name;
209 return dyd->actvar.n - 1 - fs->firstlocal; 209 return dyd->actvar.n - 1 - fs->firstlocal;
210} 210}
211 211
212#define new_localvarliteral(ls,v) \ 212#define new_localvarliteral(ls,v) \
213 new_localvar(ls, \ 213 new_localvar(ls, \
214 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 214 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
215 215
216 216
217 217
218/* 218/*
219** Return the "variable description" (Vardesc) of a given variable. 219** Return the "variable description" (Vardesc) of a given variable.
220** (Unless noted otherwise, all variables are referred to by their 220** (Unless noted otherwise, all variables are referred to by their
221** compiler indices.) 221** compiler indices.)
222*/ 222*/
223static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { 223static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
224 return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; 224 return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx];
225} 225}
226 226
227 227
228/* 228/*
229** Convert 'nvar', a compiler index level, to its corresponding 229** Convert 'nvar', a compiler index level, to its corresponding
230** register. For that, search for the highest variable below that level 230** register. For that, search for the highest variable below that level
231** that is in a register and uses its register index ('ridx') plus one. 231** that is in a register and uses its register index ('ridx') plus one.
232*/ 232*/
233static int reglevel (FuncState *fs, int nvar) { 233static int reglevel (FuncState *fs, int nvar) {
234 while (nvar-- > 0) { 234 while (nvar-- > 0) {
235 Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ 235 Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */
236 if (vd->vd.kind != RDKCTC) /* is in a register? */ 236 if (vd->vd.kind != RDKCTC) /* is in a register? */
237 return vd->vd.ridx + 1; 237 return vd->vd.ridx + 1;
238 } 238 }
239 return 0; /* no variables in registers */ 239 return 0; /* no variables in registers */
240} 240}
241 241
242 242
243/* 243/*
244** Return the number of variables in the register stack for the given 244** Return the number of variables in the register stack for the given
245** function. 245** function.
246*/ 246*/
247int luaY_nvarstack (FuncState *fs) { 247int luaY_nvarstack (FuncState *fs) {
248 return reglevel(fs, fs->nactvar); 248 return reglevel(fs, fs->nactvar);
249} 249}
250 250
251 251
252/* 252/*
253** Get the debug-information entry for current variable 'vidx'. 253** Get the debug-information entry for current variable 'vidx'.
254*/ 254*/
255static LocVar *localdebuginfo (FuncState *fs, int vidx) { 255static LocVar *localdebuginfo (FuncState *fs, int vidx) {
256 Vardesc *vd = getlocalvardesc(fs, vidx); 256 Vardesc *vd = getlocalvardesc(fs, vidx);
257 if (vd->vd.kind == RDKCTC) 257 if (vd->vd.kind == RDKCTC)
258 return NULL; /* no debug info. for constants */ 258 return NULL; /* no debug info. for constants */
259 else { 259 else {
260 int idx = vd->vd.pidx; 260 int idx = vd->vd.pidx;
261 lua_assert(idx < fs->ndebugvars); 261 lua_assert(idx < fs->ndebugvars);
262 return &fs->f->locvars[idx]; 262 return &fs->f->locvars[idx];
263 } 263 }
264} 264}
265 265
266 266
267/* 267/*
268** Create an expression representing variable 'vidx' 268** Create an expression representing variable 'vidx'
269*/ 269*/
270static void init_var (FuncState *fs, expdesc *e, int vidx) { 270static void init_var (FuncState *fs, expdesc *e, int vidx) {
271 e->f = e->t = NO_JUMP; 271 e->f = e->t = NO_JUMP;
272 e->k = VLOCAL; 272 e->k = VLOCAL;
273 e->u.var.vidx = vidx; 273 e->u.var.vidx = vidx;
274 e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; 274 e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx;
275} 275}
276 276
277 277
278/* 278/*
279** Raises an error if variable described by 'e' is read only 279** Raises an error if variable described by 'e' is read only
280*/ 280*/
281static void check_readonly (LexState *ls, expdesc *e) { 281static void check_readonly (LexState *ls, expdesc *e) {
282 FuncState *fs = ls->fs; 282 FuncState *fs = ls->fs;
283 TString *varname = NULL; /* to be set if variable is const */ 283 TString *varname = NULL; /* to be set if variable is const */
284 switch (e->k) { 284 switch (e->k) {
285 case VCONST: { 285 case VCONST: {
286 varname = ls->dyd->actvar.arr[e->u.info].vd.name; 286 varname = ls->dyd->actvar.arr[e->u.info].vd.name;
287 break; 287 break;
288 } 288 }
289 case VLOCAL: { 289 case VLOCAL: {
290 Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); 290 Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx);
291 if (vardesc->vd.kind != VDKREG) /* not a regular variable? */ 291 if (vardesc->vd.kind != VDKREG) /* not a regular variable? */
292 varname = vardesc->vd.name; 292 varname = vardesc->vd.name;
293 break; 293 break;
294 } 294 }
295 case VUPVAL: { 295 case VUPVAL: {
296 Upvaldesc *up = &fs->f->upvalues[e->u.info]; 296 Upvaldesc *up = &fs->f->upvalues[e->u.info];
297 if (up->kind != VDKREG) 297 if (up->kind != VDKREG)
298 varname = up->name; 298 varname = up->name;
299 break; 299 break;
300 } 300 }
301 default: 301 default:
302 return; /* other cases cannot be read-only */ 302 return; /* other cases cannot be read-only */
303 } 303 }
304 if (varname) { 304 if (varname) {
305 const char *msg = luaO_pushfstring(ls->L, 305 const char *msg = luaO_pushfstring(ls->L,
306 "attempt to assign to const variable '%s'", getstr(varname)); 306 "attempt to assign to const variable '%s'", getstr(varname));
307 luaK_semerror(ls, msg); /* error */ 307 luaK_semerror(ls, msg); /* error */
308 } 308 }
309} 309}
310 310
311 311
312/* 312/*
313** Start the scope for the last 'nvars' created variables. 313** Start the scope for the last 'nvars' created variables.
314*/ 314*/
315static void adjustlocalvars (LexState *ls, int nvars) { 315static void adjustlocalvars (LexState *ls, int nvars) {
316 FuncState *fs = ls->fs; 316 FuncState *fs = ls->fs;
317 int reglevel = luaY_nvarstack(fs); 317 int reglevel = luaY_nvarstack(fs);
318 int i; 318 int i;
319 for (i = 0; i < nvars; i++) { 319 for (i = 0; i < nvars; i++) {
320 int vidx = fs->nactvar++; 320 int vidx = fs->nactvar++;
321 Vardesc *var = getlocalvardesc(fs, vidx); 321 Vardesc *var = getlocalvardesc(fs, vidx);
322 var->vd.ridx = reglevel++; 322 var->vd.ridx = reglevel++;
323 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); 323 var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
324 } 324 }
325} 325}
326 326
327 327
328/* 328/*
329** Close the scope for all variables up to level 'tolevel'. 329** Close the scope for all variables up to level 'tolevel'.
330** (debug info.) 330** (debug info.)
331*/ 331*/
332static void removevars (FuncState *fs, int tolevel) { 332static void removevars (FuncState *fs, int tolevel) {
333 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); 333 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
334 while (fs->nactvar > tolevel) { 334 while (fs->nactvar > tolevel) {
335 LocVar *var = localdebuginfo(fs, --fs->nactvar); 335 LocVar *var = localdebuginfo(fs, --fs->nactvar);
336 if (var) /* does it have debug information? */ 336 if (var) /* does it have debug information? */
337 var->endpc = fs->pc; 337 var->endpc = fs->pc;
338 } 338 }
339} 339}
340 340
341 341
342/* 342/*
343** Search the upvalues of the function 'fs' for one 343** Search the upvalues of the function 'fs' for one
344** with the given 'name'. 344** with the given 'name'.
345*/ 345*/
346static int searchupvalue (FuncState *fs, TString *name) { 346static int searchupvalue (FuncState *fs, TString *name) {
347 int i; 347 int i;
348 Upvaldesc *up = fs->f->upvalues; 348 Upvaldesc *up = fs->f->upvalues;
349 for (i = 0; i < fs->nups; i++) { 349 for (i = 0; i < fs->nups; i++) {
350 if (eqstr(up[i].name, name)) return i; 350 if (eqstr(up[i].name, name)) return i;
351 } 351 }
352 return -1; /* not found */ 352 return -1; /* not found */
353} 353}
354 354
355 355
356static Upvaldesc *allocupvalue (FuncState *fs) { 356static Upvaldesc *allocupvalue (FuncState *fs) {
357 Proto *f = fs->f; 357 Proto *f = fs->f;
358 int oldsize = f->sizeupvalues; 358 int oldsize = f->sizeupvalues;
359 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); 359 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
360 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, 360 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
361 Upvaldesc, MAXUPVAL, "upvalues"); 361 Upvaldesc, MAXUPVAL, "upvalues");
362 while (oldsize < f->sizeupvalues) 362 while (oldsize < f->sizeupvalues)
363 f->upvalues[oldsize++].name = NULL; 363 f->upvalues[oldsize++].name = NULL;
364 return &f->upvalues[fs->nups++]; 364 return &f->upvalues[fs->nups++];
365} 365}
366 366
367 367
368static int newupvalue (FuncState *fs, TString *name, expdesc *v) { 368static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
369 Upvaldesc *up = allocupvalue(fs); 369 Upvaldesc *up = allocupvalue(fs);
370 FuncState *prev = fs->prev; 370 FuncState *prev = fs->prev;
371 if (v->k == VLOCAL) { 371 if (v->k == VLOCAL) {
372 up->instack = 1; 372 up->instack = 1;
373 up->idx = v->u.var.ridx; 373 up->idx = v->u.var.ridx;
374 up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; 374 up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind;
375 lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); 375 lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name));
376 } 376 }
377 else { 377 else {
378 up->instack = 0; 378 up->instack = 0;
379 up->idx = cast_byte(v->u.info); 379 up->idx = cast_byte(v->u.info);
380 up->kind = prev->f->upvalues[v->u.info].kind; 380 up->kind = prev->f->upvalues[v->u.info].kind;
381 lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name)); 381 lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name));
382 } 382 }
383 up->name = name; 383 up->name = name;
384 luaC_objbarrier(fs->ls->L, fs->f, name); 384 luaC_objbarrier(fs->ls->L, fs->f, name);
385 return fs->nups - 1; 385 return fs->nups - 1;
386} 386}
387 387
388 388
389/* 389/*
390** Look for an active local variable with the name 'n' in the 390** Look for an active local variable with the name 'n' in the
391** function 'fs'. If found, initialize 'var' with it and return 391** function 'fs'. If found, initialize 'var' with it and return
392** its expression kind; otherwise return -1. 392** its expression kind; otherwise return -1.
393*/ 393*/
394static int searchvar (FuncState *fs, TString *n, expdesc *var) { 394static int searchvar (FuncState *fs, TString *n, expdesc *var) {
395 int i; 395 int i;
396 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 396 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
397 Vardesc *vd = getlocalvardesc(fs, i); 397 Vardesc *vd = getlocalvardesc(fs, i);
398 if (eqstr(n, vd->vd.name)) { /* found? */ 398 if (eqstr(n, vd->vd.name)) { /* found? */
399 if (vd->vd.kind == RDKCTC) /* compile-time constant? */ 399 if (vd->vd.kind == RDKCTC) /* compile-time constant? */
400 init_exp(var, VCONST, fs->firstlocal + i); 400 init_exp(var, VCONST, fs->firstlocal + i);
401 else /* real variable */ 401 else /* real variable */
402 init_var(fs, var, i); 402 init_var(fs, var, i);
403 return var->k; 403 return var->k;
404 } 404 }
405 } 405 }
406 return -1; /* not found */ 406 return -1; /* not found */
407} 407}
408 408
409 409
410/* 410/*
411** Mark block where variable at given level was defined 411** Mark block where variable at given level was defined
412** (to emit close instructions later). 412** (to emit close instructions later).
413*/ 413*/
414static void markupval (FuncState *fs, int level) { 414static void markupval (FuncState *fs, int level) {
415 BlockCnt *bl = fs->bl; 415 BlockCnt *bl = fs->bl;
416 while (bl->nactvar > level) 416 while (bl->nactvar > level)
417 bl = bl->previous; 417 bl = bl->previous;
418 bl->upval = 1; 418 bl->upval = 1;
419 fs->needclose = 1; 419 fs->needclose = 1;
420} 420}
421 421
422 422
423/* 423/*
424** Mark that current block has a to-be-closed variable. 424** Mark that current block has a to-be-closed variable.
425*/ 425*/
426static void marktobeclosed (FuncState *fs) { 426static void marktobeclosed (FuncState *fs) {
427 BlockCnt *bl = fs->bl; 427 BlockCnt *bl = fs->bl;
428 bl->upval = 1; 428 bl->upval = 1;
429 bl->insidetbc = 1; 429 bl->insidetbc = 1;
430 fs->needclose = 1; 430 fs->needclose = 1;
431} 431}
432 432
433 433
434/* 434/*
435** Find a variable with the given name 'n'. If it is an upvalue, add 435** Find a variable with the given name 'n'. If it is an upvalue, add
436** this upvalue into all intermediate functions. If it is a global, set 436** this upvalue into all intermediate functions. If it is a global, set
437** 'var' as 'void' as a flag. 437** 'var' as 'void' as a flag.
438*/ 438*/
439static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 439static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
440 if (fs == NULL) /* no more levels? */ 440 if (fs == NULL) /* no more levels? */
441 init_exp(var, VVOID, 0); /* default is global */ 441 init_exp(var, VVOID, 0); /* default is global */
442 else { 442 else {
443 int v = searchvar(fs, n, var); /* look up locals at current level */ 443 int v = searchvar(fs, n, var); /* look up locals at current level */
444 if (v >= 0) { /* found? */ 444 if (v >= 0) { /* found? */
445 if (v == VLOCAL && !base) 445 if (v == VLOCAL && !base)
446 markupval(fs, var->u.var.vidx); /* local will be used as an upval */ 446 markupval(fs, var->u.var.vidx); /* local will be used as an upval */
447 } 447 }
448 else { /* not found as local at current level; try upvalues */ 448 else { /* not found as local at current level; try upvalues */
449 int idx = searchupvalue(fs, n); /* try existing upvalues */ 449 int idx = searchupvalue(fs, n); /* try existing upvalues */
450 if (idx < 0) { /* not found? */ 450 if (idx < 0) { /* not found? */
451 singlevaraux(fs->prev, n, var, 0); /* try upper levels */ 451 singlevaraux(fs->prev, n, var, 0); /* try upper levels */
452 if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ 452 if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */
453 idx = newupvalue(fs, n, var); /* will be a new upvalue */ 453 idx = newupvalue(fs, n, var); /* will be a new upvalue */
454 else /* it is a global or a constant */ 454 else /* it is a global or a constant */
455 return; /* don't need to do anything at this level */ 455 return; /* don't need to do anything at this level */
456 } 456 }
457 init_exp(var, VUPVAL, idx); /* new or old upvalue */ 457 init_exp(var, VUPVAL, idx); /* new or old upvalue */
458 } 458 }
459 } 459 }
460} 460}
461 461
462 462
463/* 463/*
464** Find a variable with the given name 'n', handling global variables 464** Find a variable with the given name 'n', handling global variables
465** too. 465** too.
466*/ 466*/
467static void singlevar (LexState *ls, expdesc *var) { 467static void singlevar (LexState *ls, expdesc *var) {
468 TString *varname = str_checkname(ls); 468 TString *varname = str_checkname(ls);
469 FuncState *fs = ls->fs; 469 FuncState *fs = ls->fs;
470 singlevaraux(fs, varname, var, 1); 470 singlevaraux(fs, varname, var, 1);
471 if (var->k == VVOID) { /* global name? */ 471 if (var->k == VVOID) { /* global name? */
472 expdesc key; 472 expdesc key;
473 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 473 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
474 lua_assert(var->k != VVOID); /* this one must exist */ 474 lua_assert(var->k != VVOID); /* this one must exist */
475 luaK_exp2anyregup(fs, var); /* but could be a constant */ 475 luaK_exp2anyregup(fs, var); /* but could be a constant */
476 codestring(&key, varname); /* key is variable name */ 476 codestring(&key, varname); /* key is variable name */
477 luaK_indexed(fs, var, &key); /* env[varname] */ 477 luaK_indexed(fs, var, &key); /* env[varname] */
478 } 478 }
479} 479}
480 480
481 481
482/* 482/*
483** Adjust the number of results from an expression list 'e' with 'nexps' 483** Adjust the number of results from an expression list 'e' with 'nexps'
484** expressions to 'nvars' values. 484** expressions to 'nvars' values.
485*/ 485*/
486static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 486static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
487 FuncState *fs = ls->fs; 487 FuncState *fs = ls->fs;
488 int needed = nvars - nexps; /* extra values needed */ 488 int needed = nvars - nexps; /* extra values needed */
489 if (hasmultret(e->k)) { /* last expression has multiple returns? */ 489 if (hasmultret(e->k)) { /* last expression has multiple returns? */
490 int extra = needed + 1; /* discount last expression itself */ 490 int extra = needed + 1; /* discount last expression itself */
491 if (extra < 0) 491 if (extra < 0)
492 extra = 0; 492 extra = 0;
493 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ 493 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
494 } 494 }
495 else { 495 else {
496 if (e->k != VVOID) /* at least one expression? */ 496 if (e->k != VVOID) /* at least one expression? */
497 luaK_exp2nextreg(fs, e); /* close last expression */ 497 luaK_exp2nextreg(fs, e); /* close last expression */
498 if (needed > 0) /* missing values? */ 498 if (needed > 0) /* missing values? */
499 luaK_nil(fs, fs->freereg, needed); /* complete with nils */ 499 luaK_nil(fs, fs->freereg, needed); /* complete with nils */
500 } 500 }
501 if (needed > 0) 501 if (needed > 0)
502 luaK_reserveregs(fs, needed); /* registers for extra values */ 502 luaK_reserveregs(fs, needed); /* registers for extra values */
503 else /* adding 'needed' is actually a subtraction */ 503 else /* adding 'needed' is actually a subtraction */
504 fs->freereg += needed; /* remove extra values */ 504 fs->freereg += needed; /* remove extra values */
505} 505}
506 506
507 507
508#define enterlevel(ls) luaE_incCstack(ls->L) 508#define enterlevel(ls) luaE_incCstack(ls->L)
509 509
510 510
511#define leavelevel(ls) ((ls)->L->nCcalls--) 511#define leavelevel(ls) ((ls)->L->nCcalls--)
512 512
513 513
514/* 514/*
515** Generates an error that a goto jumps into the scope of some 515** Generates an error that a goto jumps into the scope of some
516** local variable. 516** local variable.
517*/ 517*/
518static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { 518static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
519 const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); 519 const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name);
520 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; 520 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'";
521 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); 521 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname);
522 luaK_semerror(ls, msg); /* raise the error */ 522 luaK_semerror(ls, msg); /* raise the error */
523} 523}
524 524
525 525
526/* 526/*
527** Solves the goto at index 'g' to given 'label' and removes it 527** Solves the goto at index 'g' to given 'label' and removes it
528** from the list of pending goto's. 528** from the list of pending goto's.
529** If it jumps into the scope of some variable, raises an error. 529** If it jumps into the scope of some variable, raises an error.
530*/ 530*/
531static void solvegoto (LexState *ls, int g, Labeldesc *label) { 531static void solvegoto (LexState *ls, int g, Labeldesc *label) {
532 int i; 532 int i;
533 Labellist *gl = &ls->dyd->gt; /* list of goto's */ 533 Labellist *gl = &ls->dyd->gt; /* list of goto's */
534 Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ 534 Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */
535 lua_assert(eqstr(gt->name, label->name)); 535 lua_assert(eqstr(gt->name, label->name));
536 if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ 536 if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */
537 jumpscopeerror(ls, gt); 537 jumpscopeerror(ls, gt);
538 luaK_patchlist(ls->fs, gt->pc, label->pc); 538 luaK_patchlist(ls->fs, gt->pc, label->pc);
539 for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */ 539 for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */
540 gl->arr[i] = gl->arr[i + 1]; 540 gl->arr[i] = gl->arr[i + 1];
541 gl->n--; 541 gl->n--;
542} 542}
543 543
544 544
545/* 545/*
546** Search for an active label with the given name. 546** Search for an active label with the given name.
547*/ 547*/
548static Labeldesc *findlabel (LexState *ls, TString *name) { 548static Labeldesc *findlabel (LexState *ls, TString *name) {
549 int i; 549 int i;
550 Dyndata *dyd = ls->dyd; 550 Dyndata *dyd = ls->dyd;
551 /* check labels in current function for a match */ 551 /* check labels in current function for a match */
552 for (i = ls->fs->firstlabel; i < dyd->label.n; i++) { 552 for (i = ls->fs->firstlabel; i < dyd->label.n; i++) {
553 Labeldesc *lb = &dyd->label.arr[i]; 553 Labeldesc *lb = &dyd->label.arr[i];
554 if (eqstr(lb->name, name)) /* correct label? */ 554 if (eqstr(lb->name, name)) /* correct label? */
555 return lb; 555 return lb;
556 } 556 }
557 return NULL; /* label not found */ 557 return NULL; /* label not found */
558} 558}
559 559
560 560
561/* 561/*
562** Adds a new label/goto in the corresponding list. 562** Adds a new label/goto in the corresponding list.
563*/ 563*/
564static int newlabelentry (LexState *ls, Labellist *l, TString *name, 564static int newlabelentry (LexState *ls, Labellist *l, TString *name,
565 int line, int pc) { 565 int line, int pc) {
566 int n = l->n; 566 int n = l->n;
567 luaM_growvector(ls->L, l->arr, n, l->size, 567 luaM_growvector(ls->L, l->arr, n, l->size,
568 Labeldesc, SHRT_MAX, "labels/gotos"); 568 Labeldesc, SHRT_MAX, "labels/gotos");
569 l->arr[n].name = name; 569 l->arr[n].name = name;
570 l->arr[n].line = line; 570 l->arr[n].line = line;
571 l->arr[n].nactvar = ls->fs->nactvar; 571 l->arr[n].nactvar = ls->fs->nactvar;
572 l->arr[n].close = 0; 572 l->arr[n].close = 0;
573 l->arr[n].pc = pc; 573 l->arr[n].pc = pc;
574 l->n = n + 1; 574 l->n = n + 1;
575 return n; 575 return n;
576} 576}
577 577
578 578
579static int newgotoentry (LexState *ls, TString *name, int line, int pc) { 579static int newgotoentry (LexState *ls, TString *name, int line, int pc) {
580 return newlabelentry(ls, &ls->dyd->gt, name, line, pc); 580 return newlabelentry(ls, &ls->dyd->gt, name, line, pc);
581} 581}
582 582
583 583
584/* 584/*
585** Solves forward jumps. Check whether new label 'lb' matches any 585** Solves forward jumps. Check whether new label 'lb' matches any
586** pending gotos in current block and solves them. Return true 586** pending gotos in current block and solves them. Return true
587** if any of the goto's need to close upvalues. 587** if any of the goto's need to close upvalues.
588*/ 588*/
589static int solvegotos (LexState *ls, Labeldesc *lb) { 589static int solvegotos (LexState *ls, Labeldesc *lb) {
590 Labellist *gl = &ls->dyd->gt; 590 Labellist *gl = &ls->dyd->gt;
591 int i = ls->fs->bl->firstgoto; 591 int i = ls->fs->bl->firstgoto;
592 int needsclose = 0; 592 int needsclose = 0;
593 while (i < gl->n) { 593 while (i < gl->n) {
594 if (eqstr(gl->arr[i].name, lb->name)) { 594 if (eqstr(gl->arr[i].name, lb->name)) {
595 needsclose |= gl->arr[i].close; 595 needsclose |= gl->arr[i].close;
596 solvegoto(ls, i, lb); /* will remove 'i' from the list */ 596 solvegoto(ls, i, lb); /* will remove 'i' from the list */
597 } 597 }
598 else 598 else
599 i++; 599 i++;
600 } 600 }
601 return needsclose; 601 return needsclose;
602} 602}
603 603
604 604
605/* 605/*
606** Create a new label with the given 'name' at the given 'line'. 606** Create a new label with the given 'name' at the given 'line'.
607** 'last' tells whether label is the last non-op statement in its 607** 'last' tells whether label is the last non-op statement in its
608** block. Solves all pending goto's to this new label and adds 608** block. Solves all pending goto's to this new label and adds
609** a close instruction if necessary. 609** a close instruction if necessary.
610** Returns true iff it added a close instruction. 610** Returns true iff it added a close instruction.
611*/ 611*/
612static int createlabel (LexState *ls, TString *name, int line, 612static int createlabel (LexState *ls, TString *name, int line,
613 int last) { 613 int last) {
614 FuncState *fs = ls->fs; 614 FuncState *fs = ls->fs;
615 Labellist *ll = &ls->dyd->label; 615 Labellist *ll = &ls->dyd->label;
616 int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs)); 616 int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs));
617 if (last) { /* label is last no-op statement in the block? */ 617 if (last) { /* label is last no-op statement in the block? */
618 /* assume that locals are already out of scope */ 618 /* assume that locals are already out of scope */
619 ll->arr[l].nactvar = fs->bl->nactvar; 619 ll->arr[l].nactvar = fs->bl->nactvar;
620 } 620 }
621 if (solvegotos(ls, &ll->arr[l])) { /* need close? */ 621 if (solvegotos(ls, &ll->arr[l])) { /* need close? */
622 luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); 622 luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0);
623 return 1; 623 return 1;
624 } 624 }
625 return 0; 625 return 0;
626} 626}
627 627
628 628
629/* 629/*
630** Adjust pending gotos to outer level of a block. 630** Adjust pending gotos to outer level of a block.
631*/ 631*/
632static void movegotosout (FuncState *fs, BlockCnt *bl) { 632static void movegotosout (FuncState *fs, BlockCnt *bl) {
633 int i; 633 int i;
634 Labellist *gl = &fs->ls->dyd->gt; 634 Labellist *gl = &fs->ls->dyd->gt;
635 /* correct pending gotos to current block */ 635 /* correct pending gotos to current block */
636 for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ 636 for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */
637 Labeldesc *gt = &gl->arr[i]; 637 Labeldesc *gt = &gl->arr[i];
638 /* leaving a variable scope? */ 638 /* leaving a variable scope? */
639 if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar)) 639 if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar))
640 gt->close |= bl->upval; /* jump may need a close */ 640 gt->close |= bl->upval; /* jump may need a close */
641 gt->nactvar = bl->nactvar; /* update goto level */ 641 gt->nactvar = bl->nactvar; /* update goto level */
642 } 642 }
643} 643}
644 644
645 645
646static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { 646static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
647 bl->isloop = isloop; 647 bl->isloop = isloop;
648 bl->nactvar = fs->nactvar; 648 bl->nactvar = fs->nactvar;
649 bl->firstlabel = fs->ls->dyd->label.n; 649 bl->firstlabel = fs->ls->dyd->label.n;
650 bl->firstgoto = fs->ls->dyd->gt.n; 650 bl->firstgoto = fs->ls->dyd->gt.n;
651 bl->upval = 0; 651 bl->upval = 0;
652 bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); 652 bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc);
653 bl->previous = fs->bl; 653 bl->previous = fs->bl;
654 fs->bl = bl; 654 fs->bl = bl;
655 lua_assert(fs->freereg == luaY_nvarstack(fs)); 655 lua_assert(fs->freereg == luaY_nvarstack(fs));
656} 656}
657 657
658 658
659/* 659/*
660** generates an error for an undefined 'goto'. 660** generates an error for an undefined 'goto'.
661*/ 661*/
662static l_noret undefgoto (LexState *ls, Labeldesc *gt) { 662static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
663 const char *msg; 663 const char *msg;
664 if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) { 664 if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) {
665 msg = "break outside loop at line %d"; 665 msg = "break outside loop at line %d";
666 msg = luaO_pushfstring(ls->L, msg, gt->line); 666 msg = luaO_pushfstring(ls->L, msg, gt->line);
667 } 667 }
668 else { 668 else {
669 msg = "no visible label '%s' for <goto> at line %d"; 669 msg = "no visible label '%s' for <goto> at line %d";
670 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); 670 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
671 } 671 }
672 luaK_semerror(ls, msg); 672 luaK_semerror(ls, msg);
673} 673}
674 674
675 675
676static void leaveblock (FuncState *fs) { 676static void leaveblock (FuncState *fs) {
677 BlockCnt *bl = fs->bl; 677 BlockCnt *bl = fs->bl;
678 LexState *ls = fs->ls; 678 LexState *ls = fs->ls;
679 int hasclose = 0; 679 int hasclose = 0;
680 int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ 680 int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */
681 if (bl->isloop) /* fix pending breaks? */ 681 removevars(fs, bl->nactvar); /* remove block locals */
 682 lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
 683 if (bl->isloop) /* has to fix pending breaks? */
682 hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); 684 hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
683 if (!hasclose && bl->previous && bl->upval) 685 if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */
684 luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); 686 luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0);
685 fs->bl = bl->previous; 
686 removevars(fs, bl->nactvar); 
687 lua_assert(bl->nactvar == fs->nactvar); 
688 fs->freereg = stklevel; /* free registers */ 687 fs->freereg = stklevel; /* free registers */
689 ls->dyd->label.n = bl->firstlabel; /* remove local labels */ 688 ls->dyd->label.n = bl->firstlabel; /* remove local labels */
690 if (bl->previous) /* inner block? */ 689 fs->bl = bl->previous; /* current block now is previous one */
691 movegotosout(fs, bl); /* update pending gotos to outer block */ 690 if (bl->previous) /* was it a nested block? */
 691 movegotosout(fs, bl); /* update pending gotos to enclosing block */
692 else { 692 else {
693 if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ 693 if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */
694 undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ 694 undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
695 } 695 }
696} 696}
697 697
698 698
699/* 699/*
700** adds a new prototype into list of prototypes 700** adds a new prototype into list of prototypes
701*/ 701*/
702static Proto *addprototype (LexState *ls) { 702static Proto *addprototype (LexState *ls) {
703 Proto *clp; 703 Proto *clp;
704 lua_State *L = ls->L; 704 lua_State *L = ls->L;
705 FuncState *fs = ls->fs; 705 FuncState *fs = ls->fs;
706 Proto *f = fs->f; /* prototype of current function */ 706 Proto *f = fs->f; /* prototype of current function */
707 if (fs->np >= f->sizep) { 707 if (fs->np >= f->sizep) {
708 int oldsize = f->sizep; 708 int oldsize = f->sizep;
709 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); 709 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
710 while (oldsize < f->sizep) 710 while (oldsize < f->sizep)
711 f->p[oldsize++] = NULL; 711 f->p[oldsize++] = NULL;
712 } 712 }
713 f->p[fs->np++] = clp = luaF_newproto(L); 713 f->p[fs->np++] = clp = luaF_newproto(L);
714 luaC_objbarrier(L, f, clp); 714 luaC_objbarrier(L, f, clp);
715 return clp; 715 return clp;
716} 716}
717 717
718 718
719/* 719/*
720** codes instruction to create new closure in parent function. 720** codes instruction to create new closure in parent function.
721** The OP_CLOSURE instruction uses the last available register, 721** The OP_CLOSURE instruction uses the last available register,
722** so that, if it invokes the GC, the GC knows which registers 722** so that, if it invokes the GC, the GC knows which registers
723** are in use at that time. 723** are in use at that time.
724 724
725*/ 725*/
726static void codeclosure (LexState *ls, expdesc *v) { 726static void codeclosure (LexState *ls, expdesc *v) {
727 FuncState *fs = ls->fs->prev; 727 FuncState *fs = ls->fs->prev;
728 init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); 728 init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
729 luaK_exp2nextreg(fs, v); /* fix it at the last register */ 729 luaK_exp2nextreg(fs, v); /* fix it at the last register */
730} 730}
731 731
732 732
733static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { 733static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
734 Proto *f = fs->f; 734 Proto *f = fs->f;
735 fs->prev = ls->fs; /* linked list of funcstates */ 735 fs->prev = ls->fs; /* linked list of funcstates */
736 fs->ls = ls; 736 fs->ls = ls;
737 ls->fs = fs; 737 ls->fs = fs;
738 fs->pc = 0; 738 fs->pc = 0;
739 fs->previousline = f->linedefined; 739 fs->previousline = f->linedefined;
740 fs->iwthabs = 0; 740 fs->iwthabs = 0;
741 fs->lasttarget = 0; 741 fs->lasttarget = 0;
742 fs->freereg = 0; 742 fs->freereg = 0;
743 fs->nk = 0; 743 fs->nk = 0;
744 fs->nabslineinfo = 0; 744 fs->nabslineinfo = 0;
745 fs->np = 0; 745 fs->np = 0;
746 fs->nups = 0; 746 fs->nups = 0;
747 fs->ndebugvars = 0; 747 fs->ndebugvars = 0;
748 fs->nactvar = 0; 748 fs->nactvar = 0;
749 fs->needclose = 0; 749 fs->needclose = 0;
750 fs->firstlocal = ls->dyd->actvar.n; 750 fs->firstlocal = ls->dyd->actvar.n;
751 fs->firstlabel = ls->dyd->label.n; 751 fs->firstlabel = ls->dyd->label.n;
752 fs->bl = NULL; 752 fs->bl = NULL;
753 f->source = ls->source; 753 f->source = ls->source;
754 luaC_objbarrier(ls->L, f, f->source); 754 luaC_objbarrier(ls->L, f, f->source);
755 f->maxstacksize = 2; /* registers 0/1 are always valid */ 755 f->maxstacksize = 2; /* registers 0/1 are always valid */
756 enterblock(fs, bl, 0); 756 enterblock(fs, bl, 0);
757} 757}
758 758
759 759
760static void close_func (LexState *ls) { 760static void close_func (LexState *ls) {
761 lua_State *L = ls->L; 761 lua_State *L = ls->L;
762 FuncState *fs = ls->fs; 762 FuncState *fs = ls->fs;
763 Proto *f = fs->f; 763 Proto *f = fs->f;
764 luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ 764 luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */
765 leaveblock(fs); 765 leaveblock(fs);
766 lua_assert(fs->bl == NULL); 766 lua_assert(fs->bl == NULL);
767 luaK_finish(fs); 767 luaK_finish(fs);
768 luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); 768 luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction);
769 luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); 769 luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
770 luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo, 770 luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo,
771 fs->nabslineinfo, AbsLineInfo); 771 fs->nabslineinfo, AbsLineInfo);
772 luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); 772 luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue);
773 luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); 773 luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *);
774 luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); 774 luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar);
775 luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); 775 luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
776 ls->fs = fs->prev; 776 ls->fs = fs->prev;
777 luaC_checkGC(L); 777 luaC_checkGC(L);
778} 778}
779 779
780 780
781 781
782/*============================================================*/ 782/*============================================================*/
783/* GRAMMAR RULES */ 783/* GRAMMAR RULES */
784/*============================================================*/ 784/*============================================================*/
785 785
786 786
787/* 787/*
788** check whether current token is in the follow set of a block. 788** check whether current token is in the follow set of a block.
789** 'until' closes syntactical blocks, but do not close scope, 789** 'until' closes syntactical blocks, but do not close scope,
790** so it is handled in separate. 790** so it is handled in separate.
791*/ 791*/
792static int block_follow (LexState *ls, int withuntil) { 792static int block_follow (LexState *ls, int withuntil) {
793 switch (ls->t.token) { 793 switch (ls->t.token) {
794 case TK_ELSE: case TK_ELSEIF: 794 case TK_ELSE: case TK_ELSEIF:
795 case TK_END: case TK_EOS: 795 case TK_END: case TK_EOS:
796 return 1; 796 return 1;
797 case TK_UNTIL: return withuntil; 797 case TK_UNTIL: return withuntil;
798 default: return 0; 798 default: return 0;
799 } 799 }
800} 800}
801 801
802 802
803static void statlist (LexState *ls) { 803static void statlist (LexState *ls) {
804 /* statlist -> { stat [';'] } */ 804 /* statlist -> { stat [';'] } */
805 while (!block_follow(ls, 1)) { 805 while (!block_follow(ls, 1)) {
806 if (ls->t.token == TK_RETURN) { 806 if (ls->t.token == TK_RETURN) {
807 statement(ls); 807 statement(ls);
808 return; /* 'return' must be last statement */ 808 return; /* 'return' must be last statement */
809 } 809 }
810 statement(ls); 810 statement(ls);
811 } 811 }
812} 812}
813 813
814 814
815static void fieldsel (LexState *ls, expdesc *v) { 815static void fieldsel (LexState *ls, expdesc *v) {
816 /* fieldsel -> ['.' | ':'] NAME */ 816 /* fieldsel -> ['.' | ':'] NAME */
817 FuncState *fs = ls->fs; 817 FuncState *fs = ls->fs;
818 expdesc key; 818 expdesc key;
819 luaK_exp2anyregup(fs, v); 819 luaK_exp2anyregup(fs, v);
820 luaX_next(ls); /* skip the dot or colon */ 820 luaX_next(ls); /* skip the dot or colon */
821 codename(ls, &key); 821 codename(ls, &key);
822 luaK_indexed(fs, v, &key); 822 luaK_indexed(fs, v, &key);
823} 823}
824 824
825 825
826static void yindex (LexState *ls, expdesc *v) { 826static void yindex (LexState *ls, expdesc *v) {
827 /* index -> '[' expr ']' */ 827 /* index -> '[' expr ']' */
828 luaX_next(ls); /* skip the '[' */ 828 luaX_next(ls); /* skip the '[' */
829 expr(ls, v); 829 expr(ls, v);
830 luaK_exp2val(ls->fs, v); 830 luaK_exp2val(ls->fs, v);
831 checknext(ls, ']'); 831 checknext(ls, ']');
832} 832}
833 833
834 834
835/* 835/*
836** {====================================================================== 836** {======================================================================
837** Rules for Constructors 837** Rules for Constructors
838** ======================================================================= 838** =======================================================================
839*/ 839*/
840 840
841 841
842typedef struct ConsControl { 842typedef struct ConsControl {
843 expdesc v; /* last list item read */ 843 expdesc v; /* last list item read */
844 expdesc *t; /* table descriptor */ 844 expdesc *t; /* table descriptor */
845 int nh; /* total number of 'record' elements */ 845 int nh; /* total number of 'record' elements */
846 int na; /* number of array elements already stored */ 846 int na; /* number of array elements already stored */
847 int tostore; /* number of array elements pending to be stored */ 847 int tostore; /* number of array elements pending to be stored */
848} ConsControl; 848} ConsControl;
849 849
850 850
851static void recfield (LexState *ls, ConsControl *cc) { 851static void recfield (LexState *ls, ConsControl *cc) {
852 /* recfield -> (NAME | '['exp']') = exp */ 852 /* recfield -> (NAME | '['exp']') = exp */
853 FuncState *fs = ls->fs; 853 FuncState *fs = ls->fs;
854 int reg = ls->fs->freereg; 854 int reg = ls->fs->freereg;
855 expdesc tab, key, val; 855 expdesc tab, key, val;
856 if (ls->t.token == TK_NAME) { 856 if (ls->t.token == TK_NAME) {
857 checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); 857 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
858 codename(ls, &key); 858 codename(ls, &key);
859 } 859 }
860 else /* ls->t.token == '[' */ 860 else /* ls->t.token == '[' */
861 yindex(ls, &key); 861 yindex(ls, &key);
862 cc->nh++; 862 cc->nh++;
863 checknext(ls, '='); 863 checknext(ls, '=');
864 tab = *cc->t; 864 tab = *cc->t;
865 luaK_indexed(fs, &tab, &key); 865 luaK_indexed(fs, &tab, &key);
866 expr(ls, &val); 866 expr(ls, &val);
867 luaK_storevar(fs, &tab, &val); 867 luaK_storevar(fs, &tab, &val);
868 fs->freereg = reg; /* free registers */ 868 fs->freereg = reg; /* free registers */
869} 869}
870 870
871 871
872static void closelistfield (FuncState *fs, ConsControl *cc) { 872static void closelistfield (FuncState *fs, ConsControl *cc) {
873 if (cc->v.k == VVOID) return; /* there is no list item */ 873 if (cc->v.k == VVOID) return; /* there is no list item */
874 luaK_exp2nextreg(fs, &cc->v); 874 luaK_exp2nextreg(fs, &cc->v);
875 cc->v.k = VVOID; 875 cc->v.k = VVOID;
876 if (cc->tostore == LFIELDS_PER_FLUSH) { 876 if (cc->tostore == LFIELDS_PER_FLUSH) {
877 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ 877 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
878 cc->na += cc->tostore; 878 cc->na += cc->tostore;
879 cc->tostore = 0; /* no more items pending */ 879 cc->tostore = 0; /* no more items pending */
880 } 880 }
881} 881}
882 882
883 883
884static void lastlistfield (FuncState *fs, ConsControl *cc) { 884static void lastlistfield (FuncState *fs, ConsControl *cc) {
885 if (cc->tostore == 0) return; 885 if (cc->tostore == 0) return;
886 if (hasmultret(cc->v.k)) { 886 if (hasmultret(cc->v.k)) {
887 luaK_setmultret(fs, &cc->v); 887 luaK_setmultret(fs, &cc->v);
888 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); 888 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
889 cc->na--; /* do not count last expression (unknown number of elements) */ 889 cc->na--; /* do not count last expression (unknown number of elements) */
890 } 890 }
891 else { 891 else {
892 if (cc->v.k != VVOID) 892 if (cc->v.k != VVOID)
893 luaK_exp2nextreg(fs, &cc->v); 893 luaK_exp2nextreg(fs, &cc->v);
894 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); 894 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
895 } 895 }
896 cc->na += cc->tostore; 896 cc->na += cc->tostore;
897} 897}
898 898
899 899
900static void listfield (LexState *ls, ConsControl *cc) { 900static void listfield (LexState *ls, ConsControl *cc) {
901 /* listfield -> exp */ 901 /* listfield -> exp */
902 expr(ls, &cc->v); 902 expr(ls, &cc->v);
903 cc->tostore++; 903 cc->tostore++;
904} 904}
905 905
906 906
907static void field (LexState *ls, ConsControl *cc) { 907static void field (LexState *ls, ConsControl *cc) {
908 /* field -> listfield | recfield */ 908 /* field -> listfield | recfield */
909 switch(ls->t.token) { 909 switch(ls->t.token) {
910 case TK_NAME: { /* may be 'listfield' or 'recfield' */ 910 case TK_NAME: { /* may be 'listfield' or 'recfield' */
911 if (luaX_lookahead(ls) != '=') /* expression? */ 911 if (luaX_lookahead(ls) != '=') /* expression? */
912 listfield(ls, cc); 912 listfield(ls, cc);
913 else 913 else
914 recfield(ls, cc); 914 recfield(ls, cc);
915 break; 915 break;
916 } 916 }
917 case '[': { 917 case '[': {
918 recfield(ls, cc); 918 recfield(ls, cc);
919 break; 919 break;
920 } 920 }
921 default: { 921 default: {
922 listfield(ls, cc); 922 listfield(ls, cc);
923 break; 923 break;
924 } 924 }
925 } 925 }
926} 926}
927 927
928 928
929static void constructor (LexState *ls, expdesc *t) { 929static void constructor (LexState *ls, expdesc *t) {
930 /* constructor -> '{' [ field { sep field } [sep] ] '}' 930 /* constructor -> '{' [ field { sep field } [sep] ] '}'
931 sep -> ',' | ';' */ 931 sep -> ',' | ';' */
932 FuncState *fs = ls->fs; 932 FuncState *fs = ls->fs;
933 int line = ls->linenumber; 933 int line = ls->linenumber;
934 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); 934 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
935 ConsControl cc; 935 ConsControl cc;
936 luaK_code(fs, 0); /* space for extra arg. */ 936 luaK_code(fs, 0); /* space for extra arg. */
937 cc.na = cc.nh = cc.tostore = 0; 937 cc.na = cc.nh = cc.tostore = 0;
938 cc.t = t; 938 cc.t = t;
939 init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ 939 init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */
940 luaK_reserveregs(fs, 1); 940 luaK_reserveregs(fs, 1);
941 init_exp(&cc.v, VVOID, 0); /* no value (yet) */ 941 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
942 checknext(ls, '{'); 942 checknext(ls, '{');
943 do { 943 do {
944 lua_assert(cc.v.k == VVOID || cc.tostore > 0); 944 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
945 if (ls->t.token == '}') break; 945 if (ls->t.token == '}') break;
946 closelistfield(fs, &cc); 946 closelistfield(fs, &cc);
947 field(ls, &cc); 947 field(ls, &cc);
948 } while (testnext(ls, ',') || testnext(ls, ';')); 948 } while (testnext(ls, ',') || testnext(ls, ';'));
949 check_match(ls, '}', '{', line); 949 check_match(ls, '}', '{', line);
950 lastlistfield(fs, &cc); 950 lastlistfield(fs, &cc);
951 luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); 951 luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh);
952} 952}
953 953
954/* }====================================================================== */ 954/* }====================================================================== */
955 955
956 956
957static void setvararg (FuncState *fs, int nparams) { 957static void setvararg (FuncState *fs, int nparams) {
958 fs->f->is_vararg = 1; 958 fs->f->is_vararg = 1;
959 luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); 959 luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0);
960} 960}
961 961
962 962
963static void parlist (LexState *ls) { 963static void parlist (LexState *ls) {
964 /* parlist -> [ {NAME ','} (NAME | '...') ] */ 964 /* parlist -> [ {NAME ','} (NAME | '...') ] */
965 FuncState *fs = ls->fs; 965 FuncState *fs = ls->fs;
966 Proto *f = fs->f; 966 Proto *f = fs->f;
967 int nparams = 0; 967 int nparams = 0;
968 int isvararg = 0; 968 int isvararg = 0;
969 if (ls->t.token != ')') { /* is 'parlist' not empty? */ 969 if (ls->t.token != ')') { /* is 'parlist' not empty? */
970 do { 970 do {
971 switch (ls->t.token) { 971 switch (ls->t.token) {
972 case TK_NAME: { 972 case TK_NAME: {
973 new_localvar(ls, str_checkname(ls)); 973 new_localvar(ls, str_checkname(ls));
974 nparams++; 974 nparams++;
975 break; 975 break;
976 } 976 }
977 case TK_DOTS: { 977 case TK_DOTS: {
978 luaX_next(ls); 978 luaX_next(ls);
979 isvararg = 1; 979 isvararg = 1;
980 break; 980 break;
981 } 981 }
982 default: luaX_syntaxerror(ls, "<name> or '...' expected"); 982 default: luaX_syntaxerror(ls, "<name> or '...' expected");
983 } 983 }
984 } while (!isvararg && testnext(ls, ',')); 984 } while (!isvararg && testnext(ls, ','));
985 } 985 }
986 adjustlocalvars(ls, nparams); 986 adjustlocalvars(ls, nparams);
987 f->numparams = cast_byte(fs->nactvar); 987 f->numparams = cast_byte(fs->nactvar);
988 if (isvararg) 988 if (isvararg)
989 setvararg(fs, f->numparams); /* declared vararg */ 989 setvararg(fs, f->numparams); /* declared vararg */
990 luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ 990 luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */
991} 991}
992 992
993 993
994static void body (LexState *ls, expdesc *e, int ismethod, int line) { 994static void body (LexState *ls, expdesc *e, int ismethod, int line) {
995 /* body -> '(' parlist ')' block END */ 995 /* body -> '(' parlist ')' block END */
996 FuncState new_fs; 996 FuncState new_fs;
997 BlockCnt bl; 997 BlockCnt bl;
998 new_fs.f = addprototype(ls); 998 new_fs.f = addprototype(ls);
999 new_fs.f->linedefined = line; 999 new_fs.f->linedefined = line;
1000 open_func(ls, &new_fs, &bl); 1000 open_func(ls, &new_fs, &bl);
1001 checknext(ls, '('); 1001 checknext(ls, '(');
1002 if (ismethod) { 1002 if (ismethod) {
1003 new_localvarliteral(ls, "self"); /* create 'self' parameter */ 1003 new_localvarliteral(ls, "self"); /* create 'self' parameter */
1004 adjustlocalvars(ls, 1); 1004 adjustlocalvars(ls, 1);
1005 } 1005 }
1006 parlist(ls); 1006 parlist(ls);
1007 checknext(ls, ')'); 1007 checknext(ls, ')');
1008 statlist(ls); 1008 statlist(ls);
1009 new_fs.f->lastlinedefined = ls->linenumber; 1009 new_fs.f->lastlinedefined = ls->linenumber;
1010 check_match(ls, TK_END, TK_FUNCTION, line); 1010 check_match(ls, TK_END, TK_FUNCTION, line);
1011 codeclosure(ls, e); 1011 codeclosure(ls, e);
1012 close_func(ls); 1012 close_func(ls);
1013} 1013}
1014 1014
1015 1015
1016static int explist (LexState *ls, expdesc *v) { 1016static int explist (LexState *ls, expdesc *v) {
1017 /* explist -> expr { ',' expr } */ 1017 /* explist -> expr { ',' expr } */
1018 int n = 1; /* at least one expression */ 1018 int n = 1; /* at least one expression */
1019 expr(ls, v); 1019 expr(ls, v);
1020 while (testnext(ls, ',')) { 1020 while (testnext(ls, ',')) {
1021 luaK_exp2nextreg(ls->fs, v); 1021 luaK_exp2nextreg(ls->fs, v);
1022 expr(ls, v); 1022 expr(ls, v);
1023 n++; 1023 n++;
1024 } 1024 }
1025 return n; 1025 return n;
1026} 1026}
1027 1027
1028 1028
1029static void funcargs (LexState *ls, expdesc *f, int line) { 1029static void funcargs (LexState *ls, expdesc *f, int line) {
1030 FuncState *fs = ls->fs; 1030 FuncState *fs = ls->fs;
1031 expdesc args; 1031 expdesc args;
1032 int base, nparams; 1032 int base, nparams;
1033 switch (ls->t.token) { 1033 switch (ls->t.token) {
1034 case '(': { /* funcargs -> '(' [ explist ] ')' */ 1034 case '(': { /* funcargs -> '(' [ explist ] ')' */
1035 luaX_next(ls); 1035 luaX_next(ls);
1036 if (ls->t.token == ')') /* arg list is empty? */ 1036 if (ls->t.token == ')') /* arg list is empty? */
1037 args.k = VVOID; 1037 args.k = VVOID;
1038 else { 1038 else {
1039 explist(ls, &args); 1039 explist(ls, &args);
1040 if (hasmultret(args.k)) 1040 if (hasmultret(args.k))
1041 luaK_setmultret(fs, &args); 1041 luaK_setmultret(fs, &args);
1042 } 1042 }
1043 check_match(ls, ')', '(', line); 1043 check_match(ls, ')', '(', line);
1044 break; 1044 break;
1045 } 1045 }
1046 case '{': { /* funcargs -> constructor */ 1046 case '{': { /* funcargs -> constructor */
1047 constructor(ls, &args); 1047 constructor(ls, &args);
1048 break; 1048 break;
1049 } 1049 }
1050 case TK_STRING: { /* funcargs -> STRING */ 1050 case TK_STRING: { /* funcargs -> STRING */
1051 codestring(&args, ls->t.seminfo.ts); 1051 codestring(&args, ls->t.seminfo.ts);
1052 luaX_next(ls); /* must use 'seminfo' before 'next' */ 1052 luaX_next(ls); /* must use 'seminfo' before 'next' */
1053 break; 1053 break;
1054 } 1054 }
1055 default: { 1055 default: {
1056 luaX_syntaxerror(ls, "function arguments expected"); 1056 luaX_syntaxerror(ls, "function arguments expected");
1057 } 1057 }
1058 } 1058 }
1059 lua_assert(f->k == VNONRELOC); 1059 lua_assert(f->k == VNONRELOC);
1060 base = f->u.info; /* base register for call */ 1060 base = f->u.info; /* base register for call */
1061 if (hasmultret(args.k)) 1061 if (hasmultret(args.k))
1062 nparams = LUA_MULTRET; /* open call */ 1062 nparams = LUA_MULTRET; /* open call */
1063 else { 1063 else {
1064 if (args.k != VVOID) 1064 if (args.k != VVOID)
1065 luaK_exp2nextreg(fs, &args); /* close last argument */ 1065 luaK_exp2nextreg(fs, &args); /* close last argument */
1066 nparams = fs->freereg - (base+1); 1066 nparams = fs->freereg - (base+1);
1067 } 1067 }
1068 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); 1068 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
1069 luaK_fixline(fs, line); 1069 luaK_fixline(fs, line);
1070 fs->freereg = base+1; /* call remove function and arguments and leaves 1070 fs->freereg = base+1; /* call remove function and arguments and leaves
1071 (unless changed) one result */ 1071 (unless changed) one result */
1072} 1072}
1073 1073
1074 1074
1075 1075
1076 1076
1077/* 1077/*
1078** {====================================================================== 1078** {======================================================================
1079** Expression parsing 1079** Expression parsing
1080** ======================================================================= 1080** =======================================================================
1081*/ 1081*/
1082 1082
1083 1083
1084static void primaryexp (LexState *ls, expdesc *v) { 1084static void primaryexp (LexState *ls, expdesc *v) {
1085 /* primaryexp -> NAME | '(' expr ')' */ 1085 /* primaryexp -> NAME | '(' expr ')' */
1086 switch (ls->t.token) { 1086 switch (ls->t.token) {
1087 case '(': { 1087 case '(': {
1088 int line = ls->linenumber; 1088 int line = ls->linenumber;
1089 luaX_next(ls); 1089 luaX_next(ls);
1090 expr(ls, v); 1090 expr(ls, v);
1091 check_match(ls, ')', '(', line); 1091 check_match(ls, ')', '(', line);
1092 luaK_dischargevars(ls->fs, v); 1092 luaK_dischargevars(ls->fs, v);
1093 return; 1093 return;
1094 } 1094 }
1095 case TK_NAME: { 1095 case TK_NAME: {
1096 singlevar(ls, v); 1096 singlevar(ls, v);
1097 return; 1097 return;
1098 } 1098 }
1099 default: { 1099 default: {
1100 luaX_syntaxerror(ls, "unexpected symbol"); 1100 luaX_syntaxerror(ls, "unexpected symbol");
1101 } 1101 }
1102 } 1102 }
1103} 1103}
1104 1104
1105 1105
1106static void suffixedexp (LexState *ls, expdesc *v) { 1106static void suffixedexp (LexState *ls, expdesc *v) {
1107 /* suffixedexp -> 1107 /* suffixedexp ->
1108 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ 1108 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
1109 FuncState *fs = ls->fs; 1109 FuncState *fs = ls->fs;
1110 int line = ls->linenumber; 1110 int line = ls->linenumber;
1111 primaryexp(ls, v); 1111 primaryexp(ls, v);
1112 for (;;) { 1112 for (;;) {
1113 switch (ls->t.token) { 1113 switch (ls->t.token) {
1114 case '.': { /* fieldsel */ 1114 case '.': { /* fieldsel */
1115 fieldsel(ls, v); 1115 fieldsel(ls, v);
1116 break; 1116 break;
1117 } 1117 }
1118 case '[': { /* '[' exp ']' */ 1118 case '[': { /* '[' exp ']' */
1119 expdesc key; 1119 expdesc key;
1120 luaK_exp2anyregup(fs, v); 1120 luaK_exp2anyregup(fs, v);
1121 yindex(ls, &key); 1121 yindex(ls, &key);
1122 luaK_indexed(fs, v, &key); 1122 luaK_indexed(fs, v, &key);
1123 break; 1123 break;
1124 } 1124 }
1125 case ':': { /* ':' NAME funcargs */ 1125 case ':': { /* ':' NAME funcargs */
1126 expdesc key; 1126 expdesc key;
1127 luaX_next(ls); 1127 luaX_next(ls);
1128 codename(ls, &key); 1128 codename(ls, &key);
1129 luaK_self(fs, v, &key); 1129 luaK_self(fs, v, &key);
1130 funcargs(ls, v, line); 1130 funcargs(ls, v, line);
1131 break; 1131 break;
1132 } 1132 }
1133 case '(': case TK_STRING: case '{': { /* funcargs */ 1133 case '(': case TK_STRING: case '{': { /* funcargs */
1134 luaK_exp2nextreg(fs, v); 1134 luaK_exp2nextreg(fs, v);
1135 funcargs(ls, v, line); 1135 funcargs(ls, v, line);
1136 break; 1136 break;
1137 } 1137 }
1138 default: return; 1138 default: return;
1139 } 1139 }
1140 } 1140 }
1141} 1141}
1142 1142
1143 1143
1144static void simpleexp (LexState *ls, expdesc *v) { 1144static void simpleexp (LexState *ls, expdesc *v) {
1145 /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | 1145 /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
1146 constructor | FUNCTION body | suffixedexp */ 1146 constructor | FUNCTION body | suffixedexp */
1147 switch (ls->t.token) { 1147 switch (ls->t.token) {
1148#ifndef _KERNEL 1148#ifndef _KERNEL
1149 case TK_FLT: { 1149 case TK_FLT: {
1150 init_exp(v, VKFLT, 0); 1150 init_exp(v, VKFLT, 0);
1151 v->u.nval = ls->t.seminfo.r; 1151 v->u.nval = ls->t.seminfo.r;
1152 break; 1152 break;
1153 } 1153 }
1154#endif /* _KERNEL */ 1154#endif /* _KERNEL */
1155 case TK_INT: { 1155 case TK_INT: {
1156 init_exp(v, VKINT, 0); 1156 init_exp(v, VKINT, 0);
1157 v->u.ival = ls->t.seminfo.i; 1157 v->u.ival = ls->t.seminfo.i;
1158 break; 1158 break;
1159 } 1159 }
1160 case TK_STRING: { 1160 case TK_STRING: {
1161 codestring(v, ls->t.seminfo.ts); 1161 codestring(v, ls->t.seminfo.ts);
1162 break; 1162 break;
1163 } 1163 }
1164 case TK_NIL: { 1164 case TK_NIL: {
1165 init_exp(v, VNIL, 0); 1165 init_exp(v, VNIL, 0);
1166 break; 1166 break;
1167 } 1167 }
1168 case TK_TRUE: { 1168 case TK_TRUE: {
1169 init_exp(v, VTRUE, 0); 1169 init_exp(v, VTRUE, 0);
1170 break; 1170 break;
1171 } 1171 }
1172 case TK_FALSE: { 1172 case TK_FALSE: {
1173 init_exp(v, VFALSE, 0); 1173 init_exp(v, VFALSE, 0);
1174 break; 1174 break;
1175 } 1175 }
1176 case TK_DOTS: { /* vararg */ 1176 case TK_DOTS: { /* vararg */
1177 FuncState *fs = ls->fs; 1177 FuncState *fs = ls->fs;
1178 check_condition(ls, fs->f->is_vararg, 1178 check_condition(ls, fs->f->is_vararg,
1179 "cannot use '...' outside a vararg function"); 1179 "cannot use '...' outside a vararg function");
1180 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); 1180 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1));
1181 break; 1181 break;
1182 } 1182 }
1183 case '{': { /* constructor */ 1183 case '{': { /* constructor */
1184 constructor(ls, v); 1184 constructor(ls, v);
1185 return; 1185 return;
1186 } 1186 }
1187 case TK_FUNCTION: { 1187 case TK_FUNCTION: {
1188 luaX_next(ls); 1188 luaX_next(ls);
1189 body(ls, v, 0, ls->linenumber); 1189 body(ls, v, 0, ls->linenumber);
1190 return; 1190 return;
1191 } 1191 }
1192 default: { 1192 default: {
1193 suffixedexp(ls, v); 1193 suffixedexp(ls, v);
1194 return; 1194 return;
1195 } 1195 }
1196 } 1196 }
1197 luaX_next(ls); 1197 luaX_next(ls);
1198} 1198}
1199 1199
1200 1200
1201static UnOpr getunopr (int op) { 1201static UnOpr getunopr (int op) {
1202 switch (op) { 1202 switch (op) {
1203 case TK_NOT: return OPR_NOT; 1203 case TK_NOT: return OPR_NOT;
1204 case '-': return OPR_MINUS; 1204 case '-': return OPR_MINUS;
1205 case '~': return OPR_BNOT; 1205 case '~': return OPR_BNOT;
1206 case '#': return OPR_LEN; 1206 case '#': return OPR_LEN;
1207 default: return OPR_NOUNOPR; 1207 default: return OPR_NOUNOPR;
1208 } 1208 }
1209} 1209}
1210 1210
1211 1211
1212static BinOpr getbinopr (int op) { 1212static BinOpr getbinopr (int op) {
1213 switch (op) { 1213 switch (op) {
1214 case '+': return OPR_ADD; 1214 case '+': return OPR_ADD;
1215 case '-': return OPR_SUB; 1215 case '-': return OPR_SUB;
1216 case '*': return OPR_MUL; 1216 case '*': return OPR_MUL;
1217 case '%': return OPR_MOD; 1217 case '%': return OPR_MOD;
1218#ifndef _KERNEL 1218#ifndef _KERNEL
1219 case '^': return OPR_POW; 1219 case '^': return OPR_POW;
1220 case '/': return OPR_DIV; 1220 case '/': return OPR_DIV;
1221#else /* _KERNEL */ 1221#else /* _KERNEL */
1222 case '/': return OPR_IDIV; 1222 case '/': return OPR_IDIV;
1223#endif /* _KERNEL */ 1223#endif /* _KERNEL */
1224 case TK_IDIV: return OPR_IDIV; 1224 case TK_IDIV: return OPR_IDIV;
1225 case '&': return OPR_BAND; 1225 case '&': return OPR_BAND;
1226 case '|': return OPR_BOR; 1226 case '|': return OPR_BOR;
1227 case '~': return OPR_BXOR; 1227 case '~': return OPR_BXOR;
1228 case TK_SHL: return OPR_SHL; 1228 case TK_SHL: return OPR_SHL;
1229 case TK_SHR: return OPR_SHR; 1229 case TK_SHR: return OPR_SHR;
1230 case TK_CONCAT: return OPR_CONCAT; 1230 case TK_CONCAT: return OPR_CONCAT;
1231 case TK_NE: return OPR_NE; 1231 case TK_NE: return OPR_NE;
1232 case TK_EQ: return OPR_EQ; 1232 case TK_EQ: return OPR_EQ;
1233 case '<': return OPR_LT; 1233 case '<': return OPR_LT;
1234 case TK_LE: return OPR_LE; 1234 case TK_LE: return OPR_LE;
1235 case '>': return OPR_GT; 1235 case '>': return OPR_GT;
1236 case TK_GE: return OPR_GE; 1236 case TK_GE: return OPR_GE;
1237 case TK_AND: return OPR_AND; 1237 case TK_AND: return OPR_AND;
1238 case TK_OR: return OPR_OR; 1238 case TK_OR: return OPR_OR;
1239 default: return OPR_NOBINOPR; 1239 default: return OPR_NOBINOPR;
1240 } 1240 }
1241} 1241}
1242 1242
1243 1243
1244/* 1244/*
1245** Priority table for binary operators. 1245** Priority table for binary operators.
1246*/ 1246*/
1247static const struct { 1247static const struct {
1248 lu_byte left; /* left priority for each binary operator */ 1248 lu_byte left; /* left priority for each binary operator */
1249 lu_byte right; /* right priority */ 1249 lu_byte right; /* right priority */
1250} priority[] = { /* ORDER OPR */ 1250} priority[] = { /* ORDER OPR */
1251 {10, 10}, {10, 10}, /* '+' '-' */ 1251 {10, 10}, {10, 10}, /* '+' '-' */
1252 {11, 11}, {11, 11}, /* '*' '%' */ 1252 {11, 11}, {11, 11}, /* '*' '%' */
1253#ifndef _KERNEL 1253#ifndef _KERNEL
1254 {14, 13}, /* '^' (right associative) */ 1254 {14, 13}, /* '^' (right associative) */
1255 {11, 11}, {11, 11}, /* '/' '//' */ 1255 {11, 11}, {11, 11}, /* '/' '//' */
1256#else /* _KERNEL */ 1256#else /* _KERNEL */
1257 {11, 11}, /* '//' */ 1257 {11, 11}, /* '//' */
1258#endif /* _KERNEL */ 1258#endif /* _KERNEL */
1259 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ 1259 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
1260 {7, 7}, {7, 7}, /* '<<' '>>' */ 1260 {7, 7}, {7, 7}, /* '<<' '>>' */
1261 {9, 8}, /* '..' (right associative) */ 1261 {9, 8}, /* '..' (right associative) */
1262 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ 1262 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
1263 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ 1263 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
1264 {2, 2}, {1, 1} /* and, or */ 1264 {2, 2}, {1, 1} /* and, or */
1265}; 1265};
1266 1266
1267#define UNARY_PRIORITY 12 /* priority for unary operators */ 1267#define UNARY_PRIORITY 12 /* priority for unary operators */
1268 1268
1269 1269
1270/* 1270/*
1271** subexpr -> (simpleexp | unop subexpr) { binop subexpr } 1271** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1272** where 'binop' is any binary operator with a priority higher than 'limit' 1272** where 'binop' is any binary operator with a priority higher than 'limit'
1273*/ 1273*/
1274static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { 1274static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1275 BinOpr op; 1275 BinOpr op;
1276 UnOpr uop; 1276 UnOpr uop;
1277 enterlevel(ls); 1277 enterlevel(ls);
1278 uop = getunopr(ls->t.token); 1278 uop = getunopr(ls->t.token);
1279 if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */ 1279 if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */
1280 int line = ls->linenumber; 1280 int line = ls->linenumber;
1281 luaX_next(ls); /* skip operator */ 1281 luaX_next(ls); /* skip operator */
1282 subexpr(ls, v, UNARY_PRIORITY); 1282 subexpr(ls, v, UNARY_PRIORITY);
1283 luaK_prefix(ls->fs, uop, v, line); 1283 luaK_prefix(ls->fs, uop, v, line);
1284 } 1284 }
1285 else simpleexp(ls, v); 1285 else simpleexp(ls, v);
1286 /* expand while operators have priorities higher than 'limit' */ 1286 /* expand while operators have priorities higher than 'limit' */
1287 op = getbinopr(ls->t.token); 1287 op = getbinopr(ls->t.token);
1288 while (op != OPR_NOBINOPR && priority[op].left > limit) { 1288 while (op != OPR_NOBINOPR && priority[op].left > limit) {
1289 expdesc v2; 1289 expdesc v2;
1290 BinOpr nextop; 1290 BinOpr nextop;
1291 int line = ls->linenumber; 1291 int line = ls->linenumber;
1292 luaX_next(ls); /* skip operator */ 1292 luaX_next(ls); /* skip operator */
1293 luaK_infix(ls->fs, op, v); 1293 luaK_infix(ls->fs, op, v);
1294 /* read sub-expression with higher priority */ 1294 /* read sub-expression with higher priority */
1295 nextop = subexpr(ls, &v2, priority[op].right); 1295 nextop = subexpr(ls, &v2, priority[op].right);
1296 luaK_posfix(ls->fs, op, v, &v2, line); 1296 luaK_posfix(ls->fs, op, v, &v2, line);
1297 op = nextop; 1297 op = nextop;
1298 } 1298 }
1299 leavelevel(ls); 1299 leavelevel(ls);
1300 return op; /* return first untreated operator */ 1300 return op; /* return first untreated operator */
1301} 1301}
1302 1302
1303 1303
1304static void expr (LexState *ls, expdesc *v) { 1304static void expr (LexState *ls, expdesc *v) {
1305 subexpr(ls, v, 0); 1305 subexpr(ls, v, 0);
1306} 1306}
1307 1307
1308/* }==================================================================== */ 1308/* }==================================================================== */
1309 1309
1310 1310
1311 1311
1312/* 1312/*
1313** {====================================================================== 1313** {======================================================================
1314** Rules for Statements 1314** Rules for Statements
1315** ======================================================================= 1315** =======================================================================
1316*/ 1316*/
1317 1317
1318 1318
1319static void block (LexState *ls) { 1319static void block (LexState *ls) {
1320 /* block -> statlist */ 1320 /* block -> statlist */
1321 FuncState *fs = ls->fs; 1321 FuncState *fs = ls->fs;
1322 BlockCnt bl; 1322 BlockCnt bl;
1323 enterblock(fs, &bl, 0); 1323 enterblock(fs, &bl, 0);
1324 statlist(ls); 1324 statlist(ls);
1325 leaveblock(fs); 1325 leaveblock(fs);
1326} 1326}
1327 1327
1328 1328
1329/* 1329/*
1330** structure to chain all variables in the left-hand side of an 1330** structure to chain all variables in the left-hand side of an
1331** assignment 1331** assignment
1332*/ 1332*/
1333struct LHS_assign { 1333struct LHS_assign {
1334 struct LHS_assign *prev; 1334 struct LHS_assign *prev;
1335 expdesc v; /* variable (global, local, upvalue, or indexed) */ 1335 expdesc v; /* variable (global, local, upvalue, or indexed) */
1336}; 1336};
1337 1337
1338 1338
1339/* 1339/*
1340** check whether, in an assignment to an upvalue/local variable, the 1340** check whether, in an assignment to an upvalue/local variable, the
1341** upvalue/local variable is begin used in a previous assignment to a 1341** upvalue/local variable is begin used in a previous assignment to a
1342** table. If so, save original upvalue/local value in a safe place and 1342** table. If so, save original upvalue/local value in a safe place and
1343** use this safe copy in the previous assignment. 1343** use this safe copy in the previous assignment.
1344*/ 1344*/
1345static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 1345static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1346 FuncState *fs = ls->fs; 1346 FuncState *fs = ls->fs;
1347 int extra = fs->freereg; /* eventual position to save local variable */ 1347 int extra = fs->freereg; /* eventual position to save local variable */
1348 int conflict = 0; 1348 int conflict = 0;
1349 for (; lh; lh = lh->prev) { /* check all previous assignments */ 1349 for (; lh; lh = lh->prev) { /* check all previous assignments */
1350 if (vkisindexed(lh->v.k)) { /* assignment to table field? */ 1350 if (vkisindexed(lh->v.k)) { /* assignment to table field? */
1351 if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ 1351 if (lh->v.k == VINDEXUP) { /* is table an upvalue? */
1352 if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { 1352 if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) {
1353 conflict = 1; /* table is the upvalue being assigned now */ 1353 conflict = 1; /* table is the upvalue being assigned now */
1354 lh->v.k = VINDEXSTR; 1354 lh->v.k = VINDEXSTR;
1355 lh->v.u.ind.t = extra; /* assignment will use safe copy */ 1355 lh->v.u.ind.t = extra; /* assignment will use safe copy */
1356 } 1356 }
1357 } 1357 }
1358 else { /* table is a register */ 1358 else { /* table is a register */
1359 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) { 1359 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) {
1360 conflict = 1; /* table is the local being assigned now */ 1360 conflict = 1; /* table is the local being assigned now */
1361 lh->v.u.ind.t = extra; /* assignment will use safe copy */ 1361 lh->v.u.ind.t = extra; /* assignment will use safe copy */
1362 } 1362 }
1363 /* is index the local being assigned? */ 1363 /* is index the local being assigned? */
1364 if (lh->v.k == VINDEXED && v->k == VLOCAL && 1364 if (lh->v.k == VINDEXED && v->k == VLOCAL &&
1365 lh->v.u.ind.idx == v->u.var.ridx) { 1365 lh->v.u.ind.idx == v->u.var.ridx) {
1366 conflict = 1; 1366 conflict = 1;
1367 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 1367 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
1368 } 1368 }
1369 } 1369 }
1370 } 1370 }
1371 } 1371 }
1372 if (conflict) { 1372 if (conflict) {
1373 /* copy upvalue/local value to a temporary (in position 'extra') */ 1373 /* copy upvalue/local value to a temporary (in position 'extra') */
1374 if (v->k == VLOCAL) 1374 if (v->k == VLOCAL)
1375 luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0); 1375 luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0);
1376 else 1376 else
1377 luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); 1377 luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0);
1378 luaK_reserveregs(fs, 1); 1378 luaK_reserveregs(fs, 1);
1379 } 1379 }
1380} 1380}
1381 1381
1382/* 1382/*
1383** Parse and compile a multiple assignment. The first "variable" 1383** Parse and compile a multiple assignment. The first "variable"
1384** (a 'suffixedexp') was already read by the caller. 1384** (a 'suffixedexp') was already read by the caller.
1385** 1385**
1386** assignment -> suffixedexp restassign 1386** assignment -> suffixedexp restassign
1387** restassign -> ',' suffixedexp restassign | '=' explist 1387** restassign -> ',' suffixedexp restassign | '=' explist
1388*/ 1388*/
1389static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { 1389static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
1390 expdesc e; 1390 expdesc e;
1391 check_condition(ls, vkisvar(lh->v.k), "syntax error"); 1391 check_condition(ls, vkisvar(lh->v.k), "syntax error");
1392 check_readonly(ls, &lh->v); 1392 check_readonly(ls, &lh->v);
1393 if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */ 1393 if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */
1394 struct LHS_assign nv; 1394 struct LHS_assign nv;
1395 nv.prev = lh; 1395 nv.prev = lh;
1396 suffixedexp(ls, &nv.v); 1396 suffixedexp(ls, &nv.v);
1397 if (!vkisindexed(nv.v.k)) 1397 if (!vkisindexed(nv.v.k))
1398 check_conflict(ls, lh, &nv.v); 1398 check_conflict(ls, lh, &nv.v);
1399 enterlevel(ls); /* control recursion depth */ 1399 enterlevel(ls); /* control recursion depth */
1400 restassign(ls, &nv, nvars+1); 1400 restassign(ls, &nv, nvars+1);
1401 leavelevel(ls); 1401 leavelevel(ls);
1402 } 1402 }
1403 else { /* restassign -> '=' explist */ 1403 else { /* restassign -> '=' explist */
1404 int nexps; 1404 int nexps;
1405 checknext(ls, '='); 1405 checknext(ls, '=');
1406 nexps = explist(ls, &e); 1406 nexps = explist(ls, &e);
1407 if (nexps != nvars) 1407 if (nexps != nvars)
1408 adjust_assign(ls, nvars, nexps, &e); 1408 adjust_assign(ls, nvars, nexps, &e);
1409 else { 1409 else {
1410 luaK_setoneret(ls->fs, &e); /* close last expression */ 1410 luaK_setoneret(ls->fs, &e); /* close last expression */
1411 luaK_storevar(ls->fs, &lh->v, &e); 1411 luaK_storevar(ls->fs, &lh->v, &e);
1412 return; /* avoid default */ 1412 return; /* avoid default */
1413 } 1413 }
1414 } 1414 }
1415 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ 1415 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
1416 luaK_storevar(ls->fs, &lh->v, &e); 1416 luaK_storevar(ls->fs, &lh->v, &e);
1417} 1417}
1418 1418
1419 1419
1420static int cond (LexState *ls) { 1420static int cond (LexState *ls) {
1421 /* cond -> exp */ 1421 /* cond -> exp */
1422 expdesc v; 1422 expdesc v;
1423 expr(ls, &v); /* read condition */ 1423 expr(ls, &v); /* read condition */
1424 if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ 1424 if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */
1425 luaK_goiftrue(ls->fs, &v); 1425 luaK_goiftrue(ls->fs, &v);
1426 return v.f; 1426 return v.f;
1427} 1427}
1428 1428
1429 1429
1430static void gotostat (LexState *ls) { 1430static void gotostat (LexState *ls) {
1431 FuncState *fs = ls->fs; 1431 FuncState *fs = ls->fs;
1432 int line = ls->linenumber; 1432 int line = ls->linenumber;
1433 TString *name = str_checkname(ls); /* label's name */ 1433 TString *name = str_checkname(ls); /* label's name */
1434 Labeldesc *lb = findlabel(ls, name); 1434 Labeldesc *lb = findlabel(ls, name);
1435 if (lb == NULL) /* no label? */ 1435 if (lb == NULL) /* no label? */
1436 /* forward jump; will be resolved when the label is declared */ 1436 /* forward jump; will be resolved when the label is declared */
1437 newgotoentry(ls, name, line, luaK_jump(fs)); 1437 newgotoentry(ls, name, line, luaK_jump(fs));
1438 else { /* found a label */ 1438 else { /* found a label */
1439 /* backward jump; will be resolved here */ 1439 /* backward jump; will be resolved here */
1440 int lblevel = reglevel(fs, lb->nactvar); /* label level */ 1440 int lblevel = reglevel(fs, lb->nactvar); /* label level */
1441 if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ 1441 if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */
1442 luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); 1442 luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0);
1443 /* create jump and link it to the label */ 1443 /* create jump and link it to the label */
1444 luaK_patchlist(fs, luaK_jump(fs), lb->pc); 1444 luaK_patchlist(fs, luaK_jump(fs), lb->pc);
1445 } 1445 }
1446} 1446}
1447 1447
1448 1448
1449/* 1449/*
1450** Break statement. Semantically equivalent to "goto break". 1450** Break statement. Semantically equivalent to "goto break".
1451*/ 1451*/
1452static void breakstat (LexState *ls) { 1452static void breakstat (LexState *ls) {
1453 int line = ls->linenumber; 1453 int line = ls->linenumber;
1454 luaX_next(ls); /* skip break */ 1454 luaX_next(ls); /* skip break */
1455 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs)); 1455 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs));
1456} 1456}
1457 1457
1458 1458
1459/* 1459/*
1460** Check whether there is already a label with the given 'name'. 1460** Check whether there is already a label with the given 'name'.
1461*/ 1461*/
1462static void checkrepeated (LexState *ls, TString *name) { 1462static void checkrepeated (LexState *ls, TString *name) {
1463 Labeldesc *lb = findlabel(ls, name); 1463 Labeldesc *lb = findlabel(ls, name);
1464 if (l_unlikely(lb != NULL)) { /* already defined? */ 1464 if (l_unlikely(lb != NULL)) { /* already defined? */
1465 const char *msg = "label '%s' already defined on line %d"; 1465 const char *msg = "label '%s' already defined on line %d";
1466 msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); 1466 msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line);
1467 luaK_semerror(ls, msg); /* error */ 1467 luaK_semerror(ls, msg); /* error */
1468 } 1468 }
1469} 1469}
1470 1470
1471 1471
1472static void labelstat (LexState *ls, TString *name, int line) { 1472static void labelstat (LexState *ls, TString *name, int line) {
1473 /* label -> '::' NAME '::' */ 1473 /* label -> '::' NAME '::' */
1474 checknext(ls, TK_DBCOLON); /* skip double colon */ 1474 checknext(ls, TK_DBCOLON); /* skip double colon */
1475 while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) 1475 while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
1476 statement(ls); /* skip other no-op statements */ 1476 statement(ls); /* skip other no-op statements */
1477 checkrepeated(ls, name); /* check for repeated labels */ 1477 checkrepeated(ls, name); /* check for repeated labels */
1478 createlabel(ls, name, line, block_follow(ls, 0)); 1478 createlabel(ls, name, line, block_follow(ls, 0));
1479} 1479}
1480 1480
1481 1481
1482static void whilestat (LexState *ls, int line) { 1482static void whilestat (LexState *ls, int line) {
1483 /* whilestat -> WHILE cond DO block END */ 1483 /* whilestat -> WHILE cond DO block END */
1484 FuncState *fs = ls->fs; 1484 FuncState *fs = ls->fs;
1485 int whileinit; 1485 int whileinit;
1486 int condexit; 1486 int condexit;
1487 BlockCnt bl; 1487 BlockCnt bl;
1488 luaX_next(ls); /* skip WHILE */ 1488 luaX_next(ls); /* skip WHILE */
1489 whileinit = luaK_getlabel(fs); 1489 whileinit = luaK_getlabel(fs);
1490 condexit = cond(ls); 1490 condexit = cond(ls);
1491 enterblock(fs, &bl, 1); 1491 enterblock(fs, &bl, 1);
1492 checknext(ls, TK_DO); 1492 checknext(ls, TK_DO);
1493 block(ls); 1493 block(ls);
1494 luaK_jumpto(fs, whileinit); 1494 luaK_jumpto(fs, whileinit);
1495 check_match(ls, TK_END, TK_WHILE, line); 1495 check_match(ls, TK_END, TK_WHILE, line);
1496 leaveblock(fs); 1496 leaveblock(fs);
1497 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ 1497 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1498} 1498}
1499 1499
1500 1500
1501static void repeatstat (LexState *ls, int line) { 1501static void repeatstat (LexState *ls, int line) {
1502 /* repeatstat -> REPEAT block UNTIL cond */ 1502 /* repeatstat -> REPEAT block UNTIL cond */
1503 int condexit; 1503 int condexit;
1504 FuncState *fs = ls->fs; 1504 FuncState *fs = ls->fs;
1505 int repeat_init = luaK_getlabel(fs); 1505 int repeat_init = luaK_getlabel(fs);
1506 BlockCnt bl1, bl2; 1506 BlockCnt bl1, bl2;
1507 enterblock(fs, &bl1, 1); /* loop block */ 1507 enterblock(fs, &bl1, 1); /* loop block */
1508 enterblock(fs, &bl2, 0); /* scope block */ 1508 enterblock(fs, &bl2, 0); /* scope block */
1509 luaX_next(ls); /* skip REPEAT */ 1509 luaX_next(ls); /* skip REPEAT */
1510 statlist(ls); 1510 statlist(ls);
1511 check_match(ls, TK_UNTIL, TK_REPEAT, line); 1511 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1512 condexit = cond(ls); /* read condition (inside scope block) */ 1512 condexit = cond(ls); /* read condition (inside scope block) */
1513 leaveblock(fs); /* finish scope */ 1513 leaveblock(fs); /* finish scope */
1514 if (bl2.upval) { /* upvalues? */ 1514 if (bl2.upval) { /* upvalues? */
1515 int exit = luaK_jump(fs); /* normal exit must jump over fix */ 1515 int exit = luaK_jump(fs); /* normal exit must jump over fix */
1516 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ 1516 luaK_patchtohere(fs, condexit); /* repetition must close upvalues */
1517 luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0); 1517 luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0);
1518 condexit = luaK_jump(fs); /* repeat after closing upvalues */ 1518 condexit = luaK_jump(fs); /* repeat after closing upvalues */
1519 luaK_patchtohere(fs, exit); /* normal exit comes to here */ 1519 luaK_patchtohere(fs, exit); /* normal exit comes to here */
1520 } 1520 }
1521 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ 1521 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
1522 leaveblock(fs); /* finish loop */ 1522 leaveblock(fs); /* finish loop */
1523} 1523}
1524 1524
1525 1525
1526/* 1526/*
1527** Read an expression and generate code to put its results in next 1527** Read an expression and generate code to put its results in next
1528** stack slot. 1528** stack slot.
1529** 1529**
1530*/ 1530*/
1531static void exp1 (LexState *ls) { 1531static void exp1 (LexState *ls) {
1532 expdesc e; 1532 expdesc e;
1533 expr(ls, &e); 1533 expr(ls, &e);
1534 luaK_exp2nextreg(ls->fs, &e); 1534 luaK_exp2nextreg(ls->fs, &e);
1535 lua_assert(e.k == VNONRELOC); 1535 lua_assert(e.k == VNONRELOC);
1536} 1536}
1537 1537
1538 1538
1539/* 1539/*
1540** Fix for instruction at position 'pc' to jump to 'dest'. 1540** Fix for instruction at position 'pc' to jump to 'dest'.
1541** (Jump addresses are relative in Lua). 'back' true means 1541** (Jump addresses are relative in Lua). 'back' true means
1542** a back jump. 1542** a back jump.
1543*/ 1543*/
1544static void fixforjump (FuncState *fs, int pc, int dest, int back) { 1544static void fixforjump (FuncState *fs, int pc, int dest, int back) {
1545 Instruction *jmp = &fs->f->code[pc]; 1545 Instruction *jmp = &fs->f->code[pc];
1546 int offset = dest - (pc + 1); 1546 int offset = dest - (pc + 1);
1547 if (back) 1547 if (back)
1548 offset = -offset; 1548 offset = -offset;
1549 if (l_unlikely(offset > MAXARG_Bx)) 1549 if (l_unlikely(offset > MAXARG_Bx))
1550 luaX_syntaxerror(fs->ls, "control structure too long"); 1550 luaX_syntaxerror(fs->ls, "control structure too long");
1551 SETARG_Bx(*jmp, offset); 1551 SETARG_Bx(*jmp, offset);
1552} 1552}
1553 1553
1554 1554
1555/* 1555/*
1556** Generate code for a 'for' loop. 1556** Generate code for a 'for' loop.
1557*/ 1557*/
1558static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { 1558static void forbody (LexState *ls, int base, int line, int nvars, int isgen) {
1559 /* forbody -> DO block */ 1559 /* forbody -> DO block */
1560 static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; 1560 static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP};
1561 static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; 1561 static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP};
1562 BlockCnt bl; 1562 BlockCnt bl;
1563 FuncState *fs = ls->fs; 1563 FuncState *fs = ls->fs;
1564 int prep, endfor; 1564 int prep, endfor;
1565 checknext(ls, TK_DO); 1565 checknext(ls, TK_DO);
1566 prep = luaK_codeABx(fs, forprep[isgen], base, 0); 1566 prep = luaK_codeABx(fs, forprep[isgen], base, 0);
1567 enterblock(fs, &bl, 0); /* scope for declared variables */ 1567 enterblock(fs, &bl, 0); /* scope for declared variables */
1568 adjustlocalvars(ls, nvars); 1568 adjustlocalvars(ls, nvars);
1569 luaK_reserveregs(fs, nvars); 1569 luaK_reserveregs(fs, nvars);
1570 block(ls); 1570 block(ls);
1571 leaveblock(fs); /* end of scope for declared variables */ 1571 leaveblock(fs); /* end of scope for declared variables */
1572 fixforjump(fs, prep, luaK_getlabel(fs), 0); 1572 fixforjump(fs, prep, luaK_getlabel(fs), 0);
1573 if (isgen) { /* generic for? */ 1573 if (isgen) { /* generic for? */
1574 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); 1574 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1575 luaK_fixline(fs, line); 1575 luaK_fixline(fs, line);
1576 } 1576 }
1577 endfor = luaK_codeABx(fs, forloop[isgen], base, 0); 1577 endfor = luaK_codeABx(fs, forloop[isgen], base, 0);
1578 fixforjump(fs, endfor, prep + 1, 1); 1578 fixforjump(fs, endfor, prep + 1, 1);
1579 luaK_fixline(fs, line); 1579 luaK_fixline(fs, line);
1580} 1580}
1581 1581
1582 1582
1583static void fornum (LexState *ls, TString *varname, int line) { 1583static void fornum (LexState *ls, TString *varname, int line) {
1584 /* fornum -> NAME = exp,exp[,exp] forbody */ 1584 /* fornum -> NAME = exp,exp[,exp] forbody */
1585 FuncState *fs = ls->fs; 1585 FuncState *fs = ls->fs;
1586 int base = fs->freereg; 1586 int base = fs->freereg;
1587 new_localvarliteral(ls, "(for state)"); 1587 new_localvarliteral(ls, "(for state)");
1588 new_localvarliteral(ls, "(for state)"); 1588 new_localvarliteral(ls, "(for state)");
1589 new_localvarliteral(ls, "(for state)"); 1589 new_localvarliteral(ls, "(for state)");
1590 new_localvar(ls, varname); 1590 new_localvar(ls, varname);
1591 checknext(ls, '='); 1591 checknext(ls, '=');
1592 exp1(ls); /* initial value */ 1592 exp1(ls); /* initial value */
1593 checknext(ls, ','); 1593 checknext(ls, ',');
1594 exp1(ls); /* limit */ 1594 exp1(ls); /* limit */
1595 if (testnext(ls, ',')) 1595 if (testnext(ls, ','))
1596 exp1(ls); /* optional step */ 1596 exp1(ls); /* optional step */
1597 else { /* default step = 1 */ 1597 else { /* default step = 1 */
1598 luaK_int(fs, fs->freereg, 1); 1598 luaK_int(fs, fs->freereg, 1);
1599 luaK_reserveregs(fs, 1); 1599 luaK_reserveregs(fs, 1);
1600 } 1600 }
1601 adjustlocalvars(ls, 3); /* control variables */ 1601 adjustlocalvars(ls, 3); /* control variables */
1602 forbody(ls, base, line, 1, 0); 1602 forbody(ls, base, line, 1, 0);
1603} 1603}
1604 1604
1605 1605
1606static void forlist (LexState *ls, TString *indexname) { 1606static void forlist (LexState *ls, TString *indexname) {
1607 /* forlist -> NAME {,NAME} IN explist forbody */ 1607 /* forlist -> NAME {,NAME} IN explist forbody */
1608 FuncState *fs = ls->fs; 1608 FuncState *fs = ls->fs;
1609 expdesc e; 1609 expdesc e;
1610 int nvars = 5; /* gen, state, control, toclose, 'indexname' */ 1610 int nvars = 5; /* gen, state, control, toclose, 'indexname' */
1611 int line; 1611 int line;
1612 int base = fs->freereg; 1612 int base = fs->freereg;
1613 /* create control variables */ 1613 /* create control variables */
1614 new_localvarliteral(ls, "(for state)"); 1614 new_localvarliteral(ls, "(for state)");
1615 new_localvarliteral(ls, "(for state)"); 1615 new_localvarliteral(ls, "(for state)");
1616 new_localvarliteral(ls, "(for state)"); 1616 new_localvarliteral(ls, "(for state)");
1617 new_localvarliteral(ls, "(for state)"); 1617 new_localvarliteral(ls, "(for state)");
1618 /* create declared variables */ 1618 /* create declared variables */
1619 new_localvar(ls, indexname); 1619 new_localvar(ls, indexname);
1620 while (testnext(ls, ',')) { 1620 while (testnext(ls, ',')) {
1621 new_localvar(ls, str_checkname(ls)); 1621 new_localvar(ls, str_checkname(ls));
1622 nvars++; 1622 nvars++;
1623 } 1623 }
1624 checknext(ls, TK_IN); 1624 checknext(ls, TK_IN);
1625 line = ls->linenumber; 1625 line = ls->linenumber;
1626 adjust_assign(ls, 4, explist(ls, &e), &e); 1626 adjust_assign(ls, 4, explist(ls, &e), &e);
1627 adjustlocalvars(ls, 4); /* control variables */ 1627 adjustlocalvars(ls, 4); /* control variables */
1628 marktobeclosed(fs); /* last control var. must be closed */ 1628 marktobeclosed(fs); /* last control var. must be closed */
1629 luaK_checkstack(fs, 3); /* extra space to call generator */ 1629 luaK_checkstack(fs, 3); /* extra space to call generator */
1630 forbody(ls, base, line, nvars - 4, 1); 1630 forbody(ls, base, line, nvars - 4, 1);
1631} 1631}
1632 1632
1633 1633
1634static void forstat (LexState *ls, int line) { 1634static void forstat (LexState *ls, int line) {
1635 /* forstat -> FOR (fornum | forlist) END */ 1635 /* forstat -> FOR (fornum | forlist) END */
1636 FuncState *fs = ls->fs; 1636 FuncState *fs = ls->fs;
1637 TString *varname; 1637 TString *varname;
1638 BlockCnt bl; 1638 BlockCnt bl;
1639 enterblock(fs, &bl, 1); /* scope for loop and control variables */ 1639 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1640 luaX_next(ls); /* skip 'for' */ 1640 luaX_next(ls); /* skip 'for' */
1641 varname = str_checkname(ls); /* first variable name */ 1641 varname = str_checkname(ls); /* first variable name */
1642 switch (ls->t.token) { 1642 switch (ls->t.token) {
1643 case '=': fornum(ls, varname, line); break; 1643 case '=': fornum(ls, varname, line); break;
1644 case ',': case TK_IN: forlist(ls, varname); break; 1644 case ',': case TK_IN: forlist(ls, varname); break;
1645 default: luaX_syntaxerror(ls, "'=' or 'in' expected"); 1645 default: luaX_syntaxerror(ls, "'=' or 'in' expected");
1646 } 1646 }
1647 check_match(ls, TK_END, TK_FOR, line); 1647 check_match(ls, TK_END, TK_FOR, line);
1648 leaveblock(fs); /* loop scope ('break' jumps to this point) */ 1648 leaveblock(fs); /* loop scope ('break' jumps to this point) */
1649} 1649}
1650 1650
1651 1651
1652static void test_then_block (LexState *ls, int *escapelist) { 1652static void test_then_block (LexState *ls, int *escapelist) {
1653 /* test_then_block -> [IF | ELSEIF] cond THEN block */ 1653 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1654 BlockCnt bl; 1654 BlockCnt bl;
1655 FuncState *fs = ls->fs; 1655 FuncState *fs = ls->fs;
1656 expdesc v; 1656 expdesc v;
1657 int jf; /* instruction to skip 'then' code (if condition is false) */ 1657 int jf; /* instruction to skip 'then' code (if condition is false) */
1658 luaX_next(ls); /* skip IF or ELSEIF */ 1658 luaX_next(ls); /* skip IF or ELSEIF */
1659 expr(ls, &v); /* read condition */ 1659 expr(ls, &v); /* read condition */
1660 checknext(ls, TK_THEN); 1660 checknext(ls, TK_THEN);
1661 if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */ 1661 if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */
1662 int line = ls->linenumber; 1662 int line = ls->linenumber;
1663 luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */ 1663 luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */
1664 luaX_next(ls); /* skip 'break' */ 1664 luaX_next(ls); /* skip 'break' */
1665 enterblock(fs, &bl, 0); /* must enter block before 'goto' */ 1665 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1666 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t); 1666 newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t);
1667 while (testnext(ls, ';')) {} /* skip semicolons */ 1667 while (testnext(ls, ';')) {} /* skip semicolons */
1668 if (block_follow(ls, 0)) { /* jump is the entire block? */ 1668 if (block_follow(ls, 0)) { /* jump is the entire block? */
1669 leaveblock(fs); 1669 leaveblock(fs);
1670 return; /* and that is it */ 1670 return; /* and that is it */
1671 } 1671 }
1672 else /* must skip over 'then' part if condition is false */ 1672 else /* must skip over 'then' part if condition is false */
1673 jf = luaK_jump(fs); 1673 jf = luaK_jump(fs);
1674 } 1674 }
1675 else { /* regular case (not a break) */ 1675 else { /* regular case (not a break) */
1676 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ 1676 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1677 enterblock(fs, &bl, 0); 1677 enterblock(fs, &bl, 0);
1678 jf = v.f; 1678 jf = v.f;
1679 } 1679 }
1680 statlist(ls); /* 'then' part */ 1680 statlist(ls); /* 'then' part */
1681 leaveblock(fs); 1681 leaveblock(fs);
1682 if (ls->t.token == TK_ELSE || 1682 if (ls->t.token == TK_ELSE ||
1683 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ 1683 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
1684 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ 1684 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
1685 luaK_patchtohere(fs, jf); 1685 luaK_patchtohere(fs, jf);
1686} 1686}
1687 1687
1688 1688
1689static void ifstat (LexState *ls, int line) { 1689static void ifstat (LexState *ls, int line) {
1690 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ 1690 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1691 FuncState *fs = ls->fs; 1691 FuncState *fs = ls->fs;
1692 int escapelist = NO_JUMP; /* exit list for finished parts */ 1692 int escapelist = NO_JUMP; /* exit list for finished parts */