diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-06-05 15:17:01 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-06-05 15:17:01 -0300 |
commit | 762d059a13d83eb367238a6115bbb4f5f13fcb49 (patch) | |
tree | f35fdf0675b791865d0d4800522b172903b34803 /lparser.c | |
parent | 572a69b6afbd368beab8844bc876b0f9690b5253 (diff) | |
download | lua-762d059a13d83eb367238a6115bbb4f5f13fcb49.tar.gz lua-762d059a13d83eb367238a6115bbb4f5f13fcb49.tar.bz2 lua-762d059a13d83eb367238a6115bbb4f5f13fcb49.zip |
new implementation for the Virtual Machine
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 558 |
1 files changed, 328 insertions, 230 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.141 2001/04/05 16:49:14 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.142 2001/04/06 18:25:00 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,10 +35,12 @@ typedef struct Constdesc { | |||
35 | } Constdesc; | 35 | } Constdesc; |
36 | 36 | ||
37 | 37 | ||
38 | /* | ||
39 | ** nodes for break list (list of active breakable loops) | ||
40 | */ | ||
38 | typedef struct Breaklabel { | 41 | typedef struct Breaklabel { |
39 | struct Breaklabel *previous; /* chain */ | 42 | struct Breaklabel *previous; /* chain */ |
40 | int breaklist; | 43 | int breaklist; /* list of jumps out of this loop */ |
41 | int stacklevel; | ||
42 | } Breaklabel; | 44 | } Breaklabel; |
43 | 45 | ||
44 | 46 | ||
@@ -47,11 +49,10 @@ typedef struct Breaklabel { | |||
47 | /* | 49 | /* |
48 | ** prototypes for recursive non-terminal functions | 50 | ** prototypes for recursive non-terminal functions |
49 | */ | 51 | */ |
50 | static void body (LexState *ls, int needself, int line); | 52 | static void body (LexState *ls, expdesc *v, int needself, int line); |
51 | static void chunk (LexState *ls); | 53 | static void chunk (LexState *ls); |
52 | static void constructor (LexState *ls); | 54 | static void constructor (LexState *ls, expdesc *v); |
53 | static void expr (LexState *ls, expdesc *v); | 55 | static void expr (LexState *ls, expdesc *v); |
54 | static void exp1 (LexState *ls); | ||
55 | 56 | ||
56 | 57 | ||
57 | 58 | ||
@@ -119,25 +120,6 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
119 | } | 120 | } |
120 | 121 | ||
121 | 122 | ||
122 | static int string_constant (FuncState *fs, TString *s) { | ||
123 | Proto *f = fs->f; | ||
124 | int c = s->u.s.constindex; | ||
125 | if (c >= fs->nkstr || f->kstr[c] != s) { | ||
126 | luaM_growvector(fs->L, f->kstr, fs->nkstr, f->sizekstr, TString *, | ||
127 | MAXARG_U, l_s("constant table overflow")); | ||
128 | c = fs->nkstr++; | ||
129 | f->kstr[c] = s; | ||
130 | s->u.s.constindex = c; /* hint for next time */ | ||
131 | } | ||
132 | return c; | ||
133 | } | ||
134 | |||
135 | |||
136 | static void code_string (LexState *ls, TString *s) { | ||
137 | luaK_kstr(ls, string_constant(ls->fs, s)); | ||
138 | } | ||
139 | |||
140 | |||
141 | static TString *str_checkname (LexState *ls) { | 123 | static TString *str_checkname (LexState *ls) { |
142 | TString *ts; | 124 | TString *ts; |
143 | check_condition(ls, (ls->t.token == TK_NAME), l_s("<name> expected")); | 125 | check_condition(ls, (ls->t.token == TK_NAME), l_s("<name> expected")); |
@@ -147,11 +129,21 @@ static TString *str_checkname (LexState *ls) { | |||
147 | } | 129 | } |
148 | 130 | ||
149 | 131 | ||
150 | static int checkname (LexState *ls) { | 132 | static void init_exp (expdesc *e, expkind k, int i) { |
151 | return string_constant(ls->fs, str_checkname(ls)); | 133 | e->f = e->t = NO_JUMP; |
134 | e->k = k; | ||
135 | e->u.i.info = i; | ||
136 | } | ||
137 | |||
138 | |||
139 | static void codestring (LexState *ls, expdesc *e, TString *s) { | ||
140 | init_exp(e, VK, luaK_stringk(ls->fs, s)); | ||
152 | } | 141 | } |
153 | 142 | ||
154 | 143 | ||
144 | #define checkname(ls,e) codestring(ls,e,str_checkname(ls)) | ||
145 | |||
146 | |||
155 | static int luaI_registerlocalvar (LexState *ls, TString *varname) { | 147 | static int luaI_registerlocalvar (LexState *ls, TString *varname) { |
156 | FuncState *fs = ls->fs; | 148 | FuncState *fs = ls->fs; |
157 | Proto *f = fs->f; | 149 | Proto *f = fs->f; |
@@ -195,14 +187,13 @@ static int search_local (LexState *ls, TString *n, expdesc *var) { | |||
195 | int i; | 187 | int i; |
196 | for (i=fs->nactloc-1; i >= 0; i--) { | 188 | for (i=fs->nactloc-1; i >= 0; i--) { |
197 | if (n == fs->f->locvars[fs->actloc[i]].varname) { | 189 | if (n == fs->f->locvars[fs->actloc[i]].varname) { |
198 | var->k = VLOCAL; | 190 | init_exp(var, VLOCAL, i); |
199 | var->u.index = i; | ||
200 | return level; | 191 | return level; |
201 | } | 192 | } |
202 | } | 193 | } |
203 | level++; /* `var' not found; check outer level */ | 194 | level++; /* `var' not found; check outer level */ |
204 | } | 195 | } |
205 | var->k = VGLOBAL; /* not found in any level; must be global */ | 196 | init_exp(var, VGLOBAL, 0); /* not found in any level; must be global */ |
206 | return -1; | 197 | return -1; |
207 | } | 198 | } |
208 | 199 | ||
@@ -213,7 +204,7 @@ static void singlevar (LexState *ls, TString *n, expdesc *var) { | |||
213 | luaX_syntaxerror(ls, l_s("cannot access a variable in outer function"), | 204 | luaX_syntaxerror(ls, l_s("cannot access a variable in outer function"), |
214 | getstr(n)); | 205 | getstr(n)); |
215 | else if (level == -1) /* global? */ | 206 | else if (level == -1) /* global? */ |
216 | var->u.index = string_constant(ls->fs, n); | 207 | var->u.i.info = luaK_stringk(ls->fs, n); |
217 | } | 208 | } |
218 | 209 | ||
219 | 210 | ||
@@ -221,7 +212,7 @@ static int indexupvalue (LexState *ls, expdesc *v) { | |||
221 | FuncState *fs = ls->fs; | 212 | FuncState *fs = ls->fs; |
222 | int i; | 213 | int i; |
223 | for (i=0; i<fs->f->nupvalues; i++) { | 214 | for (i=0; i<fs->f->nupvalues; i++) { |
224 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) | 215 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.i.info == v->u.i.info) |
225 | return i; | 216 | return i; |
226 | } | 217 | } |
227 | /* new one */ | 218 | /* new one */ |
@@ -231,37 +222,43 @@ static int indexupvalue (LexState *ls, expdesc *v) { | |||
231 | } | 222 | } |
232 | 223 | ||
233 | 224 | ||
234 | static void pushupvalue (LexState *ls, TString *n) { | 225 | static void codeupvalue (LexState *ls, expdesc *v, TString *n) { |
235 | FuncState *fs = ls->fs; | 226 | FuncState *fs = ls->fs; |
236 | expdesc v; | 227 | int level; |
237 | int level = search_local(ls, n, &v); | 228 | level = search_local(ls, n, v); |
238 | if (level == -1) { /* global? */ | 229 | if (level == -1) { /* global? */ |
239 | if (fs->prev == NULL) | 230 | if (fs->prev == NULL) |
240 | luaX_syntaxerror(ls, l_s("cannot access an upvalue at top level"), getstr(n)); | 231 | luaX_syntaxerror(ls, l_s("cannot access an upvalue at top level"), |
241 | v.u.index = string_constant(fs->prev, n); | 232 | getstr(n)); |
233 | v->u.i.info = luaK_stringk(fs->prev, n); | ||
242 | } | 234 | } |
243 | else if (level != 1) { | 235 | else if (level != 1) { |
244 | luaX_syntaxerror(ls, | 236 | luaX_syntaxerror(ls, |
245 | l_s("upvalue must be global or local to immediately outer function"), getstr(n)); | 237 | l_s("upvalue must be global or local to immediately outer function"), |
238 | getstr(n)); | ||
246 | } | 239 | } |
247 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); | 240 | init_exp(v, VRELOCABLE, |
241 | luaK_codeABc(fs, OP_LOADUPVAL, 0, indexupvalue(ls, v))); | ||
248 | } | 242 | } |
249 | 243 | ||
250 | 244 | ||
251 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | 245 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { |
252 | FuncState *fs = ls->fs; | 246 | FuncState *fs = ls->fs; |
253 | int diff = nexps - nvars; | 247 | int extra = nvars - nexps; |
254 | if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ | 248 | if (e->k == VCALL) { |
255 | diff--; /* do not count function call itself */ | 249 | extra++; /* includes call itself */ |
256 | if (diff <= 0) { /* more variables than values? */ | 250 | if (extra <= 0) extra = 0; |
257 | luaK_setcallreturns(fs, -diff); /* function call provide extra values */ | 251 | else luaK_reserveregs(fs, extra-1); |
258 | diff = 0; /* no more difference */ | 252 | luaK_setcallreturns(fs, e, extra); /* call provides the difference */ |
253 | } | ||
254 | else { | ||
255 | if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ | ||
256 | if (extra > 0) { | ||
257 | int reg = fs->freereg; | ||
258 | luaK_reserveregs(fs, extra); | ||
259 | luaK_nil(fs, reg, extra); | ||
259 | } | 260 | } |
260 | else /* more values than variables */ | ||
261 | luaK_setcallreturns(fs, 0); /* call should provide no value */ | ||
262 | } | 261 | } |
263 | /* push or pop eventual difference between list lengths */ | ||
264 | luaK_adjuststack(fs, diff); | ||
265 | } | 262 | } |
266 | 263 | ||
267 | 264 | ||
@@ -275,12 +272,11 @@ static void code_params (LexState *ls, int nparams, short dots) { | |||
275 | new_localvarstr(ls, l_s("arg"), 0); | 272 | new_localvarstr(ls, l_s("arg"), 0); |
276 | adjustlocalvars(ls, 1); | 273 | adjustlocalvars(ls, 1); |
277 | } | 274 | } |
278 | luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */ | 275 | luaK_reserveregs(fs, fs->nactloc); /* reserve register for parameters */ |
279 | } | 276 | } |
280 | 277 | ||
281 | 278 | ||
282 | static void enterbreak (FuncState *fs, Breaklabel *bl) { | 279 | static void enterbreak (FuncState *fs, Breaklabel *bl) { |
283 | bl->stacklevel = fs->stacklevel; | ||
284 | bl->breaklist = NO_JUMP; | 280 | bl->breaklist = NO_JUMP; |
285 | bl->previous = fs->bl; | 281 | bl->previous = fs->bl; |
286 | fs->bl = bl; | 282 | fs->bl = bl; |
@@ -289,21 +285,24 @@ static void enterbreak (FuncState *fs, Breaklabel *bl) { | |||
289 | 285 | ||
290 | static void leavebreak (FuncState *fs, Breaklabel *bl) { | 286 | static void leavebreak (FuncState *fs, Breaklabel *bl) { |
291 | fs->bl = bl->previous; | 287 | fs->bl = bl->previous; |
292 | lua_assert(bl->stacklevel == fs->stacklevel); | ||
293 | luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); | 288 | luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); |
294 | } | 289 | } |
295 | 290 | ||
296 | 291 | ||
297 | static void pushclosure (LexState *ls, FuncState *func) { | 292 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { |
298 | FuncState *fs = ls->fs; | 293 | FuncState *fs = ls->fs; |
299 | Proto *f = fs->f; | 294 | Proto *f = fs->f; |
300 | int i; | 295 | int i; |
296 | int reg = fs->freereg; | ||
301 | for (i=0; i<func->f->nupvalues; i++) | 297 | for (i=0; i<func->f->nupvalues; i++) |
302 | luaK_tostack(ls, &func->upvalues[i], 1); | 298 | luaK_exp2nextreg(fs, &func->upvalues[i]); |
303 | luaM_growvector(ls->L, f->kproto, fs->nkproto, f->sizekproto, Proto *, | 299 | luaM_growvector(ls->L, f->kproto, fs->nkproto, f->sizekproto, Proto *, |
304 | MAXARG_A, l_s("constant table overflow")); | 300 | MAXARG_Bc, l_s("constant table overflow")); |
305 | f->kproto[fs->nkproto++] = func->f; | 301 | f->kproto[fs->nkproto++] = func->f; |
306 | luaK_code2(fs, OP_CLOSURE, fs->nkproto-1, func->f->nupvalues); | 302 | fs->freereg = reg; /* CLOSURE will consume those values */ |
303 | init_exp(v, VNONRELOC, reg); | ||
304 | luaK_reserveregs(fs, 1); | ||
305 | luaK_codeABc(fs, OP_CLOSURE, v->u.i.info, fs->nkproto-1); | ||
307 | } | 306 | } |
308 | 307 | ||
309 | 308 | ||
@@ -317,10 +316,9 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
317 | fs->pc = 0; | 316 | fs->pc = 0; |
318 | fs->lasttarget = 0; | 317 | fs->lasttarget = 0; |
319 | fs->jlt = NO_JUMP; | 318 | fs->jlt = NO_JUMP; |
320 | fs->stacklevel = 0; | 319 | fs->freereg = 0; |
321 | fs->nkstr = 0; | 320 | fs->nk = 0; |
322 | fs->nkproto = 0; | 321 | fs->nkproto = 0; |
323 | fs->nknum = 0; | ||
324 | fs->nlineinfo = 0; | 322 | fs->nlineinfo = 0; |
325 | fs->nlocvars = 0; | 323 | fs->nlocvars = 0; |
326 | fs->nactloc = 0; | 324 | fs->nactloc = 0; |
@@ -328,7 +326,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
328 | fs->bl = NULL; | 326 | fs->bl = NULL; |
329 | f->code = NULL; | 327 | f->code = NULL; |
330 | f->source = ls->source; | 328 | f->source = ls->source; |
331 | f->maxstacksize = 0; | 329 | f->maxstacksize = 1; /* register 0 is always valid */ |
332 | f->numparams = 0; /* default for main chunk */ | 330 | f->numparams = 0; /* default for main chunk */ |
333 | f->is_vararg = 0; /* default for main chunk */ | 331 | f->is_vararg = 0; /* default for main chunk */ |
334 | } | 332 | } |
@@ -338,15 +336,13 @@ static void close_func (LexState *ls) { | |||
338 | lua_State *L = ls->L; | 336 | lua_State *L = ls->L; |
339 | FuncState *fs = ls->fs; | 337 | FuncState *fs = ls->fs; |
340 | Proto *f = fs->f; | 338 | Proto *f = fs->f; |
341 | luaK_code1(fs, OP_RETURN, ls->fs->nactloc); /* final return */ | 339 | luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */ |
342 | luaK_getlabel(fs); /* close eventual list of pending jumps */ | 340 | luaK_getlabel(fs); /* close eventual list of pending jumps */ |
343 | removelocalvars(ls, fs->nactloc); | 341 | removelocalvars(ls, fs->nactloc); |
344 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | 342 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
345 | f->sizecode = fs->pc; | 343 | f->sizecode = fs->pc; |
346 | luaM_reallocvector(L, f->kstr, f->sizekstr, fs->nkstr, TString *); | 344 | luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject); |
347 | f->sizekstr = fs->nkstr; | 345 | f->sizek = fs->nk; |
348 | luaM_reallocvector(L, f->knum, f->sizeknum, fs->nknum, lua_Number); | ||
349 | f->sizeknum = fs->nknum; | ||
350 | luaM_reallocvector(L, f->kproto, f->sizekproto, fs->nkproto, Proto *); | 346 | luaM_reallocvector(L, f->kproto, f->sizekproto, fs->nkproto, Proto *); |
351 | f->sizekproto = fs->nkproto; | 347 | f->sizekproto = fs->nkproto; |
352 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 348 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
@@ -354,9 +350,9 @@ static void close_func (LexState *ls) { | |||
354 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); | 350 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); |
355 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ | 351 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ |
356 | f->sizelineinfo = fs->nlineinfo; | 352 | f->sizelineinfo = fs->nlineinfo; |
357 | lua_assert(luaG_checkcode(L, f)); | 353 | lua_assert(luaG_checkcode(f)); |
358 | ls->fs = fs->prev; | ||
359 | lua_assert(fs->bl == NULL); | 354 | lua_assert(fs->bl == NULL); |
355 | ls->fs = fs->prev; | ||
360 | } | 356 | } |
361 | 357 | ||
362 | 358 | ||
@@ -367,7 +363,8 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
367 | open_func(&lexstate, &funcstate); | 363 | open_func(&lexstate, &funcstate); |
368 | next(&lexstate); /* read first token */ | 364 | next(&lexstate); /* read first token */ |
369 | chunk(&lexstate); | 365 | chunk(&lexstate); |
370 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), l_s("<eof> expected")); | 366 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), |
367 | l_s("<eof> expected")); | ||
371 | close_func(&lexstate); | 368 | close_func(&lexstate); |
372 | lua_assert(funcstate.prev == NULL); | 369 | lua_assert(funcstate.prev == NULL); |
373 | lua_assert(funcstate.f->nupvalues == 0); | 370 | lua_assert(funcstate.f->nupvalues == 0); |
@@ -381,48 +378,64 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
381 | /*============================================================*/ | 378 | /*============================================================*/ |
382 | 379 | ||
383 | 380 | ||
384 | static int explist1 (LexState *ls) { | 381 | static void luaY_field (LexState *ls, expdesc *v) { |
382 | /* field -> ['.' | ':'] NAME */ | ||
383 | FuncState *fs = ls->fs; | ||
384 | expdesc key; | ||
385 | luaK_exp2anyreg(fs, v); | ||
386 | next(ls); /* skip the dot or colon */ | ||
387 | checkname(ls, &key); | ||
388 | luaK_indexed(fs, v, &key); | ||
389 | } | ||
390 | |||
391 | |||
392 | static void luaY_index (LexState *ls, expdesc *v) { | ||
393 | /* index -> '[' expr ']' */ | ||
394 | next(ls); /* skip the '[' */ | ||
395 | expr(ls, v); | ||
396 | luaK_exp2val(ls->fs, v); | ||
397 | check(ls, l_c(']')); | ||
398 | } | ||
399 | |||
400 | |||
401 | static int explist1 (LexState *ls, expdesc *v) { | ||
385 | /* explist1 -> expr { `,' expr } */ | 402 | /* explist1 -> expr { `,' expr } */ |
386 | int n = 1; /* at least one expression */ | 403 | int n = 1; /* at least one expression */ |
387 | expdesc v; | 404 | expr(ls, v); |
388 | expr(ls, &v); | ||
389 | while (ls->t.token == l_c(',')) { | 405 | while (ls->t.token == l_c(',')) { |
390 | next(ls); /* skip comma */ | 406 | next(ls); /* skip comma */ |
391 | luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ | 407 | luaK_exp2nextreg(ls->fs, v); |
392 | expr(ls, &v); | 408 | expr(ls, v); |
393 | n++; | 409 | n++; |
394 | } | 410 | } |
395 | luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */ | ||
396 | return n; | 411 | return n; |
397 | } | 412 | } |
398 | 413 | ||
399 | 414 | ||
400 | static void funcargs (LexState *ls, int slf) { | 415 | static void funcargs (LexState *ls, expdesc *f) { |
401 | FuncState *fs = ls->fs; | 416 | FuncState *fs = ls->fs; |
402 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | 417 | expdesc args; |
418 | int base, top; | ||
403 | switch (ls->t.token) { | 419 | switch (ls->t.token) { |
404 | case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */ | 420 | case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */ |
405 | int line = ls->linenumber; | 421 | int line = ls->linenumber; |
406 | int nargs = 0; | ||
407 | next(ls); | 422 | next(ls); |
408 | if (ls->t.token != l_c(')')) /* arg list not empty? */ | 423 | if (ls->t.token == l_c(')')) /* arg list is empty? */ |
409 | nargs = explist1(ls); | 424 | args.k = VVOID; |
425 | else { | ||
426 | explist1(ls, &args); | ||
427 | luaK_setcallreturns(fs, &args, NO_REG); | ||
428 | } | ||
410 | check_match(ls, l_c(')'), l_c('('), line); | 429 | check_match(ls, l_c(')'), l_c('('), line); |
411 | #ifdef LUA_COMPAT_ARGRET | ||
412 | if (nargs > 0) /* arg list is not empty? */ | ||
413 | luaK_setcallreturns(fs, 1); /* last call returns only 1 value */ | ||
414 | #else | ||
415 | UNUSED(nargs); /* to avoid warnings */ | ||
416 | #endif | ||
417 | break; | 430 | break; |
418 | } | 431 | } |
419 | case l_c('{'): { /* funcargs -> constructor */ | 432 | case l_c('{'): { /* funcargs -> constructor */ |
420 | constructor(ls); | 433 | constructor(ls, &args); |
421 | break; | 434 | break; |
422 | } | 435 | } |
423 | case TK_STRING: { /* funcargs -> STRING */ | 436 | case TK_STRING: { /* funcargs -> STRING */ |
424 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | 437 | codestring(ls, &args, ls->t.seminfo.ts); |
425 | next(ls); | 438 | next(ls); /* must use `seminfo' before `next' */ |
426 | break; | 439 | break; |
427 | } | 440 | } |
428 | default: { | 441 | default: { |
@@ -430,11 +443,22 @@ static void funcargs (LexState *ls, int slf) { | |||
430 | break; | 443 | break; |
431 | } | 444 | } |
432 | } | 445 | } |
433 | fs->stacklevel = slevel; /* call will remove function and arguments */ | 446 | lua_assert(f->k == VNONRELOC); |
434 | luaK_code2(fs, OP_CALL, slevel, MULT_RET); | 447 | base = f->u.i.info; /* base register for call */ |
448 | if (args.k == VCALL) | ||
449 | top = NO_REG; /* open call */ | ||
450 | else { | ||
451 | if (args.k != VVOID) | ||
452 | luaK_exp2nextreg(fs, &args); /* close last argument */ | ||
453 | top = fs->freereg; | ||
454 | } | ||
455 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, top, 1)); | ||
456 | fs->freereg = base+1; /* call remove function and arguments and leaves | ||
457 | (unless changed) one result */ | ||
435 | } | 458 | } |
436 | 459 | ||
437 | 460 | ||
461 | |||
438 | /* | 462 | /* |
439 | ** {====================================================================== | 463 | ** {====================================================================== |
440 | ** Rules for Constructors | 464 | ** Rules for Constructors |
@@ -442,69 +466,82 @@ static void funcargs (LexState *ls, int slf) { | |||
442 | */ | 466 | */ |
443 | 467 | ||
444 | 468 | ||
445 | static void recfield (LexState *ls) { | 469 | static void recfield (LexState *ls, expdesc *t) { |
446 | /* recfield -> (NAME | `['exp1`]') = exp1 */ | 470 | /* recfield -> (NAME | `['exp1`]') = exp1 */ |
471 | FuncState *fs = ls->fs; | ||
472 | int reg = ls->fs->freereg; | ||
473 | expdesc key, val; | ||
447 | switch (ls->t.token) { | 474 | switch (ls->t.token) { |
448 | case TK_NAME: { | 475 | case TK_NAME: { |
449 | luaK_kstr(ls, checkname(ls)); | 476 | checkname(ls, &key); |
450 | break; | 477 | break; |
451 | } | 478 | } |
452 | case l_c('['): { | 479 | case l_c('['): { |
453 | next(ls); | 480 | luaY_index(ls, &key); |
454 | exp1(ls); | ||
455 | check(ls, l_c(']')); | ||
456 | break; | 481 | break; |
457 | } | 482 | } |
458 | default: luaK_error(ls, l_s("<name> or `[' expected")); | 483 | default: luaK_error(ls, l_s("<name> or `[' expected")); |
459 | } | 484 | } |
460 | check(ls, l_c('=')); | 485 | check(ls, l_c('=')); |
461 | exp1(ls); | 486 | luaK_exp2RK(fs, &key); |
487 | expr(ls, &val); | ||
488 | luaK_exp2anyreg(fs, &val); | ||
489 | luaK_codeABC(fs, OP_SETTABLE, val.u.i.info, t->u.i.info, | ||
490 | luaK_exp2RK(fs, &key)); | ||
491 | fs->freereg = reg; /* free registers */ | ||
462 | } | 492 | } |
463 | 493 | ||
464 | 494 | ||
465 | static int recfields (LexState *ls) { | 495 | static int recfields (LexState *ls, expdesc *t) { |
466 | /* recfields -> recfield { `,' recfield } [`,'] */ | 496 | /* recfields -> recfield { `,' recfield } [`,'] */ |
467 | FuncState *fs = ls->fs; | ||
468 | int t = fs->stacklevel-1; /* level of table on the stack */ | ||
469 | int n = 1; /* at least one element */ | 497 | int n = 1; /* at least one element */ |
470 | recfield(ls); | 498 | luaK_exp2nextreg(ls->fs, t); |
471 | while (ls->t.token == l_c(',') && | 499 | recfield(ls, t); |
472 | (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { | 500 | while (ls->t.token == l_c(',')) { |
473 | if (n%RFIELDS_PER_FLUSH == 0) | 501 | next(ls); |
474 | luaK_code1(fs, OP_SETMAP, t); | 502 | if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) break; |
475 | recfield(ls); | 503 | recfield(ls, t); |
476 | n++; | 504 | n++; |
477 | } | 505 | } |
478 | luaK_code1(fs, OP_SETMAP, t); | ||
479 | return n; | 506 | return n; |
480 | } | 507 | } |
481 | 508 | ||
482 | 509 | ||
483 | static int listfields (LexState *ls) { | 510 | static int listfields (LexState *ls, expdesc *t) { |
484 | /* listfields -> exp1 { `,' exp1 } [`,'] */ | 511 | /* listfields -> exp1 { `,' exp1 } [`,'] */ |
485 | expdesc v; | 512 | expdesc v; |
486 | FuncState *fs = ls->fs; | 513 | FuncState *fs = ls->fs; |
487 | int t = fs->stacklevel-1; /* level of table on the stack */ | ||
488 | int n = 1; /* at least one element */ | 514 | int n = 1; /* at least one element */ |
515 | int reg; | ||
516 | luaK_exp2nextreg(ls->fs, t); | ||
517 | reg = fs->freereg; | ||
489 | expr(ls, &v); | 518 | expr(ls, &v); |
490 | while (ls->t.token == l_c(',') && | 519 | while (ls->t.token == l_c(',') && |
491 | (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { | 520 | (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { |
492 | luaK_tostack(ls, &v, 1); /* only one value from intermediate expressions */ | 521 | luaK_exp2nextreg(fs, &v); |
493 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | 522 | luaX_checklimit(ls, n, MAXARG_Bc, |
494 | l_s("`item groups' in a list initializer")); | 523 | l_s("`item groups' in a list initializer")); |
495 | if (n%LFIELDS_PER_FLUSH == 0) | 524 | if (n%LFIELDS_PER_FLUSH == 0) { |
496 | luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); | 525 | luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); |
526 | fs->freereg = reg; /* free registers */ | ||
527 | } | ||
497 | expr(ls, &v); | 528 | expr(ls, &v); |
498 | n++; | 529 | n++; |
499 | } | 530 | } |
500 | luaK_tostack(ls, &v, 0); /* allow multiple values for last expression */ | 531 | if (v.k == VCALL) { |
501 | luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); | 532 | luaK_setcallreturns(fs, &v, NO_REG); |
533 | luaK_codeABc(fs, OP_SETLISTO, t->u.i.info, n-1); | ||
534 | } | ||
535 | else { | ||
536 | luaK_exp2nextreg(fs, &v); | ||
537 | luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); | ||
538 | } | ||
539 | fs->freereg = reg; /* free registers */ | ||
502 | return n; | 540 | return n; |
503 | } | 541 | } |
504 | 542 | ||
505 | 543 | ||
506 | 544 | static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { | |
507 | static void constructor_part (LexState *ls, Constdesc *cd) { | ||
508 | switch (ls->t.token) { | 545 | switch (ls->t.token) { |
509 | case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ | 546 | case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ |
510 | cd->n = 0; | 547 | cd->n = 0; |
@@ -518,13 +555,13 @@ static void constructor_part (LexState *ls, Constdesc *cd) { | |||
518 | /* else go through to recfields */ | 555 | /* else go through to recfields */ |
519 | } | 556 | } |
520 | case l_c('['): { /* constructor_part -> recfields */ | 557 | case l_c('['): { /* constructor_part -> recfields */ |
521 | cd->n = recfields(ls); | 558 | cd->n = recfields(ls, t); |
522 | cd->k = 1; /* record */ | 559 | cd->k = 1; /* record */ |
523 | break; | 560 | break; |
524 | } | 561 | } |
525 | default: { /* constructor_part -> listfields */ | 562 | default: { /* constructor_part -> listfields */ |
526 | case_default: | 563 | case_default: |
527 | cd->n = listfields(ls); | 564 | cd->n = listfields(ls, t); |
528 | cd->k = 0; /* list */ | 565 | cd->k = 0; /* list */ |
529 | break; | 566 | break; |
530 | } | 567 | } |
@@ -532,25 +569,27 @@ static void constructor_part (LexState *ls, Constdesc *cd) { | |||
532 | } | 569 | } |
533 | 570 | ||
534 | 571 | ||
535 | static void constructor (LexState *ls) { | 572 | static void constructor (LexState *ls, expdesc *t) { |
536 | /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ | 573 | /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ |
537 | FuncState *fs = ls->fs; | 574 | FuncState *fs = ls->fs; |
538 | int line = ls->linenumber; | 575 | int line = ls->linenumber; |
539 | int pc = luaK_code1(fs, OP_CREATETABLE, 0); | 576 | int n; |
540 | int nelems; | 577 | int pc; |
541 | Constdesc cd; | 578 | Constdesc cd; |
579 | pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0); | ||
580 | init_exp(t, VRELOCABLE, pc); | ||
542 | check(ls, l_c('{')); | 581 | check(ls, l_c('{')); |
543 | constructor_part(ls, &cd); | 582 | constructor_part(ls, t, &cd); |
544 | nelems = cd.n; | 583 | n = cd.n; |
545 | if (optional(ls, l_c(';'))) { | 584 | if (optional(ls, l_c(';'))) { |
546 | Constdesc other_cd; | 585 | Constdesc other_cd; |
547 | constructor_part(ls, &other_cd); | 586 | constructor_part(ls, t, &other_cd); |
548 | check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); | 587 | check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); |
549 | nelems += other_cd.n; | 588 | n += other_cd.n; |
550 | } | 589 | } |
551 | check_match(ls, l_c('}'), l_c('{'), line); | 590 | check_match(ls, l_c('}'), l_c('{'), line); |
552 | luaX_checklimit(ls, nelems, MAXARG_U, l_s("elements in a table constructor")); | 591 | luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table constructor")); |
553 | SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ | 592 | SETARG_Bc(fs->f->code[pc], n); /* set initial table size */ |
554 | } | 593 | } |
555 | 594 | ||
556 | /* }====================================================================== */ | 595 | /* }====================================================================== */ |
@@ -565,31 +604,30 @@ static void constructor (LexState *ls) { | |||
565 | */ | 604 | */ |
566 | 605 | ||
567 | static void primaryexp (LexState *ls, expdesc *v) { | 606 | static void primaryexp (LexState *ls, expdesc *v) { |
568 | FuncState *fs = ls->fs; | ||
569 | switch (ls->t.token) { | 607 | switch (ls->t.token) { |
570 | case TK_NUMBER: { | 608 | case TK_NUMBER: { |
571 | lua_Number r = ls->t.seminfo.r; | 609 | init_exp(v, VNUMBER, 0); |
572 | next(ls); | 610 | v->u.n = ls->t.seminfo.r; |
573 | luaK_number(fs, r); | 611 | next(ls); /* must use `seminfo' before `next' */ |
574 | break; | 612 | break; |
575 | } | 613 | } |
576 | case TK_STRING: { | 614 | case TK_STRING: { |
577 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | 615 | codestring(ls, v, ls->t.seminfo.ts); |
578 | next(ls); | 616 | next(ls); /* must use `seminfo' before `next' */ |
579 | break; | 617 | break; |
580 | } | 618 | } |
581 | case TK_NIL: { | 619 | case TK_NIL: { |
582 | luaK_adjuststack(fs, -1); | 620 | init_exp(v, VNIL, 0); |
583 | next(ls); | 621 | next(ls); |
584 | break; | 622 | break; |
585 | } | 623 | } |
586 | case l_c('{'): { /* constructor */ | 624 | case l_c('{'): { /* constructor */ |
587 | constructor(ls); | 625 | constructor(ls, v); |
588 | break; | 626 | break; |
589 | } | 627 | } |
590 | case TK_FUNCTION: { | 628 | case TK_FUNCTION: { |
591 | next(ls); | 629 | next(ls); |
592 | body(ls, 0, ls->linenumber); | 630 | body(ls, v, 0, ls->linenumber); |
593 | break; | 631 | break; |
594 | } | 632 | } |
595 | case l_c('('): { | 633 | case l_c('('): { |
@@ -604,7 +642,7 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
604 | } | 642 | } |
605 | case l_c('%'): { | 643 | case l_c('%'): { |
606 | next(ls); /* skip `%' */ | 644 | next(ls); /* skip `%' */ |
607 | pushupvalue(ls, str_checkname(ls)); | 645 | codeupvalue(ls, v, str_checkname(ls)); |
608 | break; | 646 | break; |
609 | } | 647 | } |
610 | default: { | 648 | default: { |
@@ -612,46 +650,38 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
612 | return; | 650 | return; |
613 | } | 651 | } |
614 | } | 652 | } |
615 | v->k = VEXP; | ||
616 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
617 | } | 653 | } |
618 | 654 | ||
619 | 655 | ||
620 | static void simpleexp (LexState *ls, expdesc *v) { | 656 | static void simpleexp (LexState *ls, expdesc *v) { |
621 | /* simpleexp -> | 657 | /* simpleexp -> |
622 | primaryexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | 658 | primaryexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ |
659 | FuncState *fs = ls->fs; | ||
623 | primaryexp(ls, v); | 660 | primaryexp(ls, v); |
624 | for (;;) { | 661 | for (;;) { |
625 | switch (ls->t.token) { | 662 | switch (ls->t.token) { |
626 | case l_c('.'): { /* `.' NAME */ | 663 | case l_c('.'): { /* field */ |
627 | next(ls); | 664 | luaY_field(ls, v); |
628 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
629 | luaK_kstr(ls, checkname(ls)); | ||
630 | v->k = VINDEXED; | ||
631 | break; | 665 | break; |
632 | } | 666 | } |
633 | case l_c('['): { /* `[' exp1 `]' */ | 667 | case l_c('['): { /* `[' exp1 `]' */ |
634 | next(ls); | 668 | expdesc key; |
635 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 669 | luaK_exp2anyreg(fs, v); |
636 | v->k = VINDEXED; | 670 | luaY_index(ls, &key); |
637 | exp1(ls); | 671 | luaK_indexed(fs, v, &key); |
638 | check(ls, l_c(']')); | ||
639 | break; | 672 | break; |
640 | } | 673 | } |
641 | case l_c(':'): { /* `:' NAME funcargs */ | 674 | case l_c(':'): { /* `:' NAME funcargs */ |
675 | expdesc key; | ||
642 | next(ls); | 676 | next(ls); |
643 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 677 | checkname(ls, &key); |
644 | luaK_code1(ls->fs, OP_PUSHSELF, checkname(ls)); | 678 | luaK_self(fs, v, &key); |
645 | funcargs(ls, 1); | 679 | funcargs(ls, v); |
646 | v->k = VEXP; | ||
647 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
648 | break; | 680 | break; |
649 | } | 681 | } |
650 | case l_c('('): case TK_STRING: case l_c('{'): { /* funcargs */ | 682 | case l_c('('): case TK_STRING: case l_c('{'): { /* funcargs */ |
651 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 683 | luaK_exp2nextreg(fs, v); |
652 | funcargs(ls, 0); | 684 | funcargs(ls, v); |
653 | v->k = VEXP; | ||
654 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
655 | break; | 685 | break; |
656 | } | 686 | } |
657 | default: return; /* should be follow... */ | 687 | default: return; /* should be follow... */ |
@@ -714,7 +744,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |||
714 | if (uop != OPR_NOUNOPR) { | 744 | if (uop != OPR_NOUNOPR) { |
715 | next(ls); | 745 | next(ls); |
716 | subexpr(ls, v, UNARY_PRIORITY); | 746 | subexpr(ls, v, UNARY_PRIORITY); |
717 | luaK_prefix(ls, uop, v); | 747 | luaK_prefix(ls->fs, uop, v); |
718 | } | 748 | } |
719 | else simpleexp(ls, v); | 749 | else simpleexp(ls, v); |
720 | /* expand while operators have priorities higher than `limit' */ | 750 | /* expand while operators have priorities higher than `limit' */ |
@@ -723,10 +753,10 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |||
723 | expdesc v2; | 753 | expdesc v2; |
724 | BinOpr nextop; | 754 | BinOpr nextop; |
725 | next(ls); | 755 | next(ls); |
726 | luaK_infix(ls, op, v); | 756 | luaK_infix(ls->fs, op, v); |
727 | /* read sub-expression with higher priority */ | 757 | /* read sub-expression with higher priority */ |
728 | nextop = subexpr(ls, &v2, (int)priority[op].right); | 758 | nextop = subexpr(ls, &v2, (int)priority[op].right); |
729 | luaK_posfix(ls, op, v, &v2); | 759 | luaK_posfix(ls->fs, op, v, &v2); |
730 | op = nextop; | 760 | op = nextop; |
731 | } | 761 | } |
732 | return op; /* return first untreated operator */ | 762 | return op; /* return first untreated operator */ |
@@ -737,13 +767,6 @@ static void expr (LexState *ls, expdesc *v) { | |||
737 | subexpr(ls, v, -1); | 767 | subexpr(ls, v, -1); |
738 | } | 768 | } |
739 | 769 | ||
740 | |||
741 | static void exp1 (LexState *ls) { | ||
742 | expdesc v; | ||
743 | expr(ls, &v); | ||
744 | luaK_tostack(ls, &v, 1); | ||
745 | } | ||
746 | |||
747 | /* }==================================================================== */ | 770 | /* }==================================================================== */ |
748 | 771 | ||
749 | 772 | ||
@@ -769,41 +792,87 @@ static void block (LexState *ls) { | |||
769 | FuncState *fs = ls->fs; | 792 | FuncState *fs = ls->fs; |
770 | int nactloc = fs->nactloc; | 793 | int nactloc = fs->nactloc; |
771 | chunk(ls); | 794 | chunk(ls); |
772 | luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */ | ||
773 | removelocalvars(ls, fs->nactloc - nactloc); | 795 | removelocalvars(ls, fs->nactloc - nactloc); |
796 | fs->freereg = nactloc; /* free registers used by locals */ | ||
774 | } | 797 | } |
775 | 798 | ||
776 | 799 | ||
777 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 800 | /* |
778 | int left = 0; /* number of values left in the stack after assignment */ | 801 | ** structure to chain all variables in the left-hand side of an |
779 | luaX_checklimit(ls, nvars, MAXVARSLH, l_s("variables in a multiple assignment")); | 802 | ** assignment |
803 | */ | ||
804 | struct LHS_assign { | ||
805 | struct LHS_assign *prev; | ||
806 | expdesc v; /* variable (global, local, or indexed) */ | ||
807 | }; | ||
808 | |||
809 | |||
810 | /* | ||
811 | ** check whether, in an assignment to a local variable, the local variable | ||
812 | ** is needed in a previous assignment (to a table). If so, save original | ||
813 | ** local value in a safe place and use this safe copy in the previous | ||
814 | ** assignment. | ||
815 | */ | ||
816 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | ||
817 | FuncState *fs = ls->fs; | ||
818 | int extra = fs->freereg; /* eventual position to save local variable */ | ||
819 | int conflict = 0; | ||
820 | for (; lh; lh = lh->prev) { | ||
821 | if (lh->v.k == VINDEXED) { | ||
822 | if (lh->v.u.i.info == v->u.i.info) { /* conflict? */ | ||
823 | conflict = 1; | ||
824 | lh->v.u.i.info = extra; /* previous assignment will use safe copy */ | ||
825 | } | ||
826 | if (lh->v.u.i.aux == v->u.i.info) { /* conflict? */ | ||
827 | conflict = 1; | ||
828 | lh->v.u.i.aux = extra; /* previous assignment will use safe copy */ | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | if (conflict) { | ||
833 | luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.i.info, 0); /* make copy */ | ||
834 | luaK_reserveregs(fs, 1); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | |||
839 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | ||
840 | expdesc e; | ||
841 | check_condition(ls, lh->v.k == VLOCAL || lh->v.k == VGLOBAL || | ||
842 | lh->v.k == VINDEXED, | ||
843 | l_s("syntax error")); | ||
780 | if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */ | 844 | if (ls->t.token == l_c(',')) { /* assignment -> `,' simpleexp assignment */ |
781 | expdesc nv; | 845 | struct LHS_assign nv; |
846 | nv.prev = lh; | ||
782 | next(ls); | 847 | next(ls); |
783 | simpleexp(ls, &nv); | 848 | simpleexp(ls, &nv.v); |
784 | check_condition(ls, (nv.k != VEXP), l_s("syntax error")); | 849 | if (nv.v.k == VLOCAL) |
785 | left = assignment(ls, &nv, nvars+1); | 850 | check_conflict(ls, lh, &nv.v); |
851 | assignment(ls, &nv, nvars+1); | ||
786 | } | 852 | } |
787 | else { /* assignment -> `=' explist1 */ | 853 | else { /* assignment -> `=' explist1 */ |
788 | int nexps; | 854 | int nexps; |
789 | check(ls, l_c('=')); | 855 | check(ls, l_c('=')); |
790 | nexps = explist1(ls); | 856 | nexps = explist1(ls, &e); |
791 | adjust_mult_assign(ls, nvars, nexps); | 857 | if (nexps != nvars) { |
792 | } | 858 | adjust_assign(ls, nvars, nexps, &e); |
793 | if (v->k != VINDEXED) | 859 | if (nexps > nvars) |
794 | luaK_storevar(ls, v); | 860 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ |
795 | else { /* there may be garbage between table-index and value */ | 861 | } |
796 | luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1); | 862 | else { |
797 | left += 2; | 863 | luaK_storevar(ls->fs, &lh->v, &e); |
864 | return; /* avoid default */ | ||
865 | } | ||
798 | } | 866 | } |
799 | return left; | 867 | init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ |
868 | luaK_storevar(ls->fs, &lh->v, &e); | ||
800 | } | 869 | } |
801 | 870 | ||
802 | 871 | ||
803 | static void cond (LexState *ls, expdesc *v) { | 872 | static void cond (LexState *ls, expdesc *v) { |
804 | /* cond -> exp */ | 873 | /* cond -> exp */ |
805 | expr(ls, v); /* read condition */ | 874 | expr(ls, v); /* read condition */ |
806 | luaK_goiftrue(ls->fs, v, 0); | 875 | luaK_goiftrue(ls->fs, v); |
807 | } | 876 | } |
808 | 877 | ||
809 | 878 | ||
@@ -819,7 +888,7 @@ static void whilestat (LexState *ls, int line) { | |||
819 | check(ls, TK_DO); | 888 | check(ls, TK_DO); |
820 | block(ls); | 889 | block(ls); |
821 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 890 | luaK_patchlist(fs, luaK_jump(fs), while_init); |
822 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 891 | luaK_patchlist(fs, v.f, luaK_getlabel(fs)); |
823 | check_match(ls, TK_END, TK_WHILE, line); | 892 | check_match(ls, TK_END, TK_WHILE, line); |
824 | leavebreak(fs, &bl); | 893 | leavebreak(fs, &bl); |
825 | } | 894 | } |
@@ -836,20 +905,28 @@ static void repeatstat (LexState *ls, int line) { | |||
836 | block(ls); | 905 | block(ls); |
837 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 906 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
838 | cond(ls, &v); | 907 | cond(ls, &v); |
839 | luaK_patchlist(fs, v.u.l.f, repeat_init); | 908 | luaK_patchlist(fs, v.f, repeat_init); |
840 | leavebreak(fs, &bl); | 909 | leavebreak(fs, &bl); |
841 | } | 910 | } |
842 | 911 | ||
843 | 912 | ||
913 | static void exp1 (LexState *ls) { | ||
914 | expdesc e; | ||
915 | expr(ls, &e); | ||
916 | luaK_exp2nextreg(ls->fs, &e); | ||
917 | } | ||
918 | |||
919 | |||
844 | static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { | 920 | static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { |
845 | /* forbody -> DO block END */ | 921 | /* forbody -> DO block END */ |
846 | FuncState *fs = ls->fs; | 922 | FuncState *fs = ls->fs; |
847 | int prep = luaK_code1(fs, prepfor, NO_JUMP); | 923 | int basereg = fs->freereg - nvar; |
924 | int prep = luaK_codeAsBc(fs, prepfor, basereg, NO_JUMP); | ||
848 | int blockinit = luaK_getlabel(fs); | 925 | int blockinit = luaK_getlabel(fs); |
849 | check(ls, TK_DO); | 926 | check(ls, TK_DO); |
850 | adjustlocalvars(ls, nvar); /* scope for control variables */ | 927 | adjustlocalvars(ls, nvar); /* scope for control variables */ |
851 | block(ls); | 928 | block(ls); |
852 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); | 929 | luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit); |
853 | luaK_fixfor(fs, prep, luaK_getlabel(fs)); | 930 | luaK_fixfor(fs, prep, luaK_getlabel(fs)); |
854 | removelocalvars(ls, nvar); | 931 | removelocalvars(ls, nvar); |
855 | } | 932 | } |
@@ -864,8 +941,10 @@ static void fornum (LexState *ls, TString *varname) { | |||
864 | exp1(ls); /* limit */ | 941 | exp1(ls); /* limit */ |
865 | if (optional(ls, l_c(','))) | 942 | if (optional(ls, l_c(','))) |
866 | exp1(ls); /* optional step */ | 943 | exp1(ls); /* optional step */ |
867 | else | 944 | else { |
868 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | 945 | luaK_codeAsBc(fs, OP_LOADINT, fs->freereg, 1); /* default step */ |
946 | luaK_reserveregs(fs, 1); | ||
947 | } | ||
869 | new_localvar(ls, varname, 0); | 948 | new_localvar(ls, varname, 0); |
870 | new_localvarstr(ls, l_s("(limit)"), 1); | 949 | new_localvarstr(ls, l_s("(limit)"), 1); |
871 | new_localvarstr(ls, l_s("(step)"), 2); | 950 | new_localvarstr(ls, l_s("(step)"), 2); |
@@ -889,7 +968,8 @@ static void forlist (LexState *ls, TString *indexname) { | |||
889 | new_localvarstr(ls, l_s("(index)"), 1); | 968 | new_localvarstr(ls, l_s("(index)"), 1); |
890 | new_localvar(ls, indexname, 2); | 969 | new_localvar(ls, indexname, 2); |
891 | new_localvar(ls, valname, 3); | 970 | new_localvar(ls, valname, 3); |
892 | forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP); | 971 | luaK_reserveregs(ls->fs, 3); /* registers for control, index and val */ |
972 | forbody(ls, 4, OP_TFORPREP, OP_TFORLOOP); | ||
893 | } | 973 | } |
894 | 974 | ||
895 | 975 | ||
@@ -928,17 +1008,17 @@ static void ifstat (LexState *ls, int line) { | |||
928 | test_then_block(ls, &v); /* IF cond THEN block */ | 1008 | test_then_block(ls, &v); /* IF cond THEN block */ |
929 | while (ls->t.token == TK_ELSEIF) { | 1009 | while (ls->t.token == TK_ELSEIF) { |
930 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1010 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
931 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 1011 | luaK_patchlist(fs, v.f, luaK_getlabel(fs)); |
932 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ | 1012 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ |
933 | } | 1013 | } |
934 | if (ls->t.token == TK_ELSE) { | 1014 | if (ls->t.token == TK_ELSE) { |
935 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1015 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
936 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 1016 | luaK_patchlist(fs, v.f, luaK_getlabel(fs)); |
937 | next(ls); /* skip ELSE */ | 1017 | next(ls); /* skip ELSE */ |
938 | block(ls); /* `else' part */ | 1018 | block(ls); /* `else' part */ |
939 | } | 1019 | } |
940 | else | 1020 | else |
941 | luaK_concat(fs, &escapelist, v.u.l.f); | 1021 | luaK_concat(fs, &escapelist, v.f); |
942 | luaK_patchlist(fs, escapelist, luaK_getlabel(fs)); | 1022 | luaK_patchlist(fs, escapelist, luaK_getlabel(fs)); |
943 | check_match(ls, TK_END, TK_IF, line); | 1023 | check_match(ls, TK_END, TK_IF, line); |
944 | } | 1024 | } |
@@ -948,35 +1028,32 @@ static void localstat (LexState *ls) { | |||
948 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | 1028 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ |
949 | int nvars = 0; | 1029 | int nvars = 0; |
950 | int nexps; | 1030 | int nexps; |
1031 | expdesc e; | ||
951 | do { | 1032 | do { |
952 | next(ls); /* skip LOCAL or `,' */ | 1033 | next(ls); /* skip LOCAL or `,' */ |
953 | new_localvar(ls, str_checkname(ls), nvars++); | 1034 | new_localvar(ls, str_checkname(ls), nvars++); |
954 | } while (ls->t.token == l_c(',')); | 1035 | } while (ls->t.token == l_c(',')); |
955 | if (optional(ls, l_c('='))) | 1036 | if (optional(ls, l_c('='))) |
956 | nexps = explist1(ls); | 1037 | nexps = explist1(ls, &e); |
957 | else | 1038 | else { |
1039 | e.k = VVOID; | ||
958 | nexps = 0; | 1040 | nexps = 0; |
959 | adjust_mult_assign(ls, nvars, nexps); | 1041 | } |
1042 | adjust_assign(ls, nvars, nexps, &e); | ||
960 | adjustlocalvars(ls, nvars); | 1043 | adjustlocalvars(ls, nvars); |
961 | } | 1044 | } |
962 | 1045 | ||
963 | 1046 | ||
964 | static int funcname (LexState *ls, expdesc *v) { | 1047 | static int funcname (LexState *ls, expdesc *v) { |
965 | /* funcname -> NAME {`.' NAME} [`:' NAME] */ | 1048 | /* funcname -> NAME {field} [`:' NAME] */ |
966 | int needself = 0; | 1049 | int needself = 0; |
967 | singlevar(ls, str_checkname(ls), v); | 1050 | singlevar(ls, str_checkname(ls), v); |
968 | while (ls->t.token == l_c('.')) { | 1051 | while (ls->t.token == l_c('.')) { |
969 | next(ls); | 1052 | luaY_field(ls, v); |
970 | luaK_tostack(ls, v, 1); | ||
971 | luaK_kstr(ls, checkname(ls)); | ||
972 | v->k = VINDEXED; | ||
973 | } | 1053 | } |
974 | if (ls->t.token == l_c(':')) { | 1054 | if (ls->t.token == l_c(':')) { |
975 | needself = 1; | 1055 | needself = 1; |
976 | next(ls); | 1056 | luaY_field(ls, v); |
977 | luaK_tostack(ls, v, 1); | ||
978 | luaK_kstr(ls, checkname(ls)); | ||
979 | v->k = VINDEXED; | ||
980 | } | 1057 | } |
981 | return needself; | 1058 | return needself; |
982 | } | 1059 | } |
@@ -985,26 +1062,25 @@ static int funcname (LexState *ls, expdesc *v) { | |||
985 | static void funcstat (LexState *ls, int line) { | 1062 | static void funcstat (LexState *ls, int line) { |
986 | /* funcstat -> FUNCTION funcname body */ | 1063 | /* funcstat -> FUNCTION funcname body */ |
987 | int needself; | 1064 | int needself; |
988 | expdesc v; | 1065 | expdesc v, b; |
989 | next(ls); /* skip FUNCTION */ | 1066 | next(ls); /* skip FUNCTION */ |
990 | needself = funcname(ls, &v); | 1067 | needself = funcname(ls, &v); |
991 | body(ls, needself, line); | 1068 | body(ls, &b, needself, line); |
992 | luaK_storevar(ls, &v); | 1069 | luaK_storevar(ls->fs, &v, &b); |
993 | } | 1070 | } |
994 | 1071 | ||
995 | 1072 | ||
996 | static void exprstat (LexState *ls) { | 1073 | static void exprstat (LexState *ls) { |
997 | /* stat -> func | assignment */ | 1074 | /* stat -> func | assignment */ |
998 | FuncState *fs = ls->fs; | 1075 | FuncState *fs = ls->fs; |
999 | expdesc v; | 1076 | struct LHS_assign v; |
1000 | simpleexp(ls, &v); | 1077 | simpleexp(ls, &v.v); |
1001 | if (v.k == VEXP) { /* stat -> func */ | 1078 | if (v.v.k == VCALL) { /* stat -> func */ |
1002 | check_condition(ls, luaK_lastisopen(fs), l_s("syntax error")); /* an upvalue? */ | 1079 | luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ |
1003 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ | ||
1004 | } | 1080 | } |
1005 | else { /* stat -> assignment */ | 1081 | else { /* stat -> assignment */ |
1006 | int left = assignment(ls, &v, 1); | 1082 | v.prev = NULL; |
1007 | luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ | 1083 | assignment(ls, &v, 1); |
1008 | } | 1084 | } |
1009 | } | 1085 | } |
1010 | 1086 | ||
@@ -1012,26 +1088,45 @@ static void exprstat (LexState *ls) { | |||
1012 | static void retstat (LexState *ls) { | 1088 | static void retstat (LexState *ls) { |
1013 | /* stat -> RETURN explist */ | 1089 | /* stat -> RETURN explist */ |
1014 | FuncState *fs = ls->fs; | 1090 | FuncState *fs = ls->fs; |
1091 | expdesc e; | ||
1092 | int first, last1; /* registers with returned values */ | ||
1015 | next(ls); /* skip RETURN */ | 1093 | next(ls); /* skip RETURN */ |
1016 | if (!block_follow(ls->t.token) && ls->t.token != l_c(';')) | 1094 | if (block_follow(ls->t.token) || ls->t.token == l_c(';')) |
1017 | explist1(ls); /* optional return values */ | 1095 | first = last1 = 0; /* return no values */ |
1018 | luaK_code1(fs, OP_RETURN, ls->fs->nactloc); | 1096 | else { |
1019 | fs->stacklevel = fs->nactloc; /* removes all temp values */ | 1097 | int n = explist1(ls, &e); /* optional return values */ |
1098 | if (e.k == VCALL) { | ||
1099 | luaK_setcallreturns(fs, &e, NO_REG); | ||
1100 | first = fs->nactloc; | ||
1101 | last1 = NO_REG; /* return all values */ | ||
1102 | } | ||
1103 | else { | ||
1104 | if (n == 1) { /* only one value? */ | ||
1105 | luaK_exp2anyreg(fs, &e); | ||
1106 | first = e.u.i.info; | ||
1107 | last1 = first+1; /* return only this value */ | ||
1108 | } | ||
1109 | else { | ||
1110 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ | ||
1111 | first = fs->nactloc; | ||
1112 | last1 = fs->freereg; /* return all `active' values */ | ||
1113 | } | ||
1114 | } | ||
1115 | } | ||
1116 | luaK_codeABC(fs, OP_RETURN, first, last1, 0); | ||
1117 | fs->freereg = fs->nactloc; /* removes all temp values */ | ||
1020 | } | 1118 | } |
1021 | 1119 | ||
1022 | 1120 | ||
1023 | static void breakstat (LexState *ls) { | 1121 | static void breakstat (LexState *ls) { |
1024 | /* stat -> BREAK [NAME] */ | 1122 | /* stat -> BREAK [NAME] */ |
1025 | FuncState *fs = ls->fs; | 1123 | FuncState *fs = ls->fs; |
1026 | int currentlevel = fs->stacklevel; | ||
1027 | Breaklabel *bl = fs->bl; | 1124 | Breaklabel *bl = fs->bl; |
1028 | if (!bl) | 1125 | if (!bl) |
1029 | luaK_error(ls, l_s("no loop to break")); | 1126 | luaK_error(ls, l_s("no loop to break")); |
1030 | next(ls); /* skip BREAK */ | 1127 | next(ls); /* skip BREAK */ |
1031 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | ||
1032 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1128 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
1033 | /* correct stack for compiler and symbolic execution */ | 1129 | /* correct stack for compiler and symbolic execution */ |
1034 | luaK_adjuststack(fs, bl->stacklevel - currentlevel); | ||
1035 | } | 1130 | } |
1036 | 1131 | ||
1037 | 1132 | ||
@@ -1105,7 +1200,7 @@ static void parlist (LexState *ls) { | |||
1105 | } | 1200 | } |
1106 | 1201 | ||
1107 | 1202 | ||
1108 | static void body (LexState *ls, int needself, int line) { | 1203 | static void body (LexState *ls, expdesc *e, int needself, int line) { |
1109 | /* body -> `(' parlist `)' chunk END */ | 1204 | /* body -> `(' parlist `)' chunk END */ |
1110 | FuncState new_fs; | 1205 | FuncState new_fs; |
1111 | open_func(ls, &new_fs); | 1206 | open_func(ls, &new_fs); |
@@ -1120,7 +1215,7 @@ static void body (LexState *ls, int needself, int line) { | |||
1120 | chunk(ls); | 1215 | chunk(ls); |
1121 | check_match(ls, TK_END, TK_FUNCTION, line); | 1216 | check_match(ls, TK_END, TK_FUNCTION, line); |
1122 | close_func(ls); | 1217 | close_func(ls); |
1123 | pushclosure(ls, &new_fs); | 1218 | pushclosure(ls, &new_fs, e); |
1124 | } | 1219 | } |
1125 | 1220 | ||
1126 | 1221 | ||
@@ -1133,7 +1228,10 @@ static void chunk (LexState *ls) { | |||
1133 | while (!islast && !block_follow(ls->t.token)) { | 1228 | while (!islast && !block_follow(ls->t.token)) { |
1134 | islast = statement(ls); | 1229 | islast = statement(ls); |
1135 | optional(ls, l_c(';')); | 1230 | optional(ls, l_c(';')); |
1136 | lua_assert(ls->fs->stacklevel == ls->fs->nactloc); | 1231 | if (ls->fs->freereg < ls->fs->nactloc) |
1232 | printf(">>>>>>> %d %d\n", ls->fs->freereg, ls->fs->nactloc); | ||
1233 | lua_assert(ls->fs->freereg >= ls->fs->nactloc); | ||
1234 | ls->fs->freereg = ls->fs->nactloc; /* free registers */ | ||
1137 | } | 1235 | } |
1138 | } | 1236 | } |
1139 | 1237 | ||