diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_parse.c | 2198 |
1 files changed, 2198 insertions, 0 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c new file mode 100644 index 00000000..663525ab --- /dev/null +++ b/src/lj_parse.c | |||
@@ -0,0 +1,2198 @@ | |||
1 | /* | ||
2 | ** Lua parser (source code -> bytecode). | ||
3 | ** Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h | ||
4 | ** | ||
5 | ** Major portions taken verbatim or adapted from the Lua interpreter. | ||
6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h | ||
7 | */ | ||
8 | |||
9 | #define lj_parse_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lj_obj.h" | ||
13 | #include "lj_gc.h" | ||
14 | #include "lj_err.h" | ||
15 | #include "lj_str.h" | ||
16 | #include "lj_tab.h" | ||
17 | #include "lj_func.h" | ||
18 | #include "lj_state.h" | ||
19 | #include "lj_bc.h" | ||
20 | #include "lj_lex.h" | ||
21 | #include "lj_parse.h" | ||
22 | #include "lj_vm.h" | ||
23 | #include "lj_vmevent.h" | ||
24 | |||
25 | /* -- Parser structures and definitions ----------------------------------- */ | ||
26 | |||
27 | /* Expression kinds. */ | ||
28 | typedef enum { | ||
29 | /* Constant expressions must be first and in this order: */ | ||
30 | VKNIL, | ||
31 | VKFALSE, | ||
32 | VKTRUE, | ||
33 | VKSTR, /* sval = string value */ | ||
34 | VKNUM, /* nval = numerical value */ | ||
35 | VKLAST = VKNUM, | ||
36 | /* Non-constant expressions follow: */ | ||
37 | VLOCAL, /* info = local register */ | ||
38 | VUPVAL, /* info = upvalue index */ | ||
39 | VGLOBAL, /* sval = string value */ | ||
40 | VINDEXED, /* info = table register, aux = index reg/byte/string const */ | ||
41 | VJMP, /* info = instruction PC */ | ||
42 | VRELOCABLE, /* info = instruction PC */ | ||
43 | VNONRELOC, /* info = result register */ | ||
44 | VCALL, /* info = instruction PC, aux = base */ | ||
45 | VVOID | ||
46 | } ExpKind; | ||
47 | |||
48 | /* Expression descriptor. */ | ||
49 | typedef struct ExpDesc { | ||
50 | union { | ||
51 | struct { uint32_t info, aux; } s; | ||
52 | TValue nval; | ||
53 | GCstr *sval; | ||
54 | } u; | ||
55 | ExpKind k; | ||
56 | BCPos t; /* true condition exit list */ | ||
57 | BCPos f; /* false condition exit list */ | ||
58 | } ExpDesc; | ||
59 | |||
60 | /* Tests for expression types */ | ||
61 | #define isK(e) ((uint32_t)((e)->k) <= VKLAST) | ||
62 | #define isnumK(e) ((e)->k == VKNUM) | ||
63 | #define isstrK(e) ((e)->k == VKSTR) | ||
64 | #define expnumV(e) check_exp(isnumK((e)), numV(&(e)->u.nval)) | ||
65 | |||
66 | #define hasjumps(e) ((e)->t != (e)->f) | ||
67 | #define isKexp(e) (isK(e) && !hasjumps(e)) | ||
68 | #define isnumKexp(e) (isnumK(e) && !hasjumps(e)) | ||
69 | |||
70 | #define priKk(k) check_exp((k) <= VKTRUE, (k) - VKNIL) | ||
71 | #define priK(e) priKk((e)->k) | ||
72 | |||
73 | /* Per-function linked list of blocks. */ | ||
74 | typedef struct FuncBlock { | ||
75 | struct FuncBlock *previous; /* chain */ | ||
76 | BCPos breaklist; /* list of jumps out of this loop */ | ||
77 | uint8_t nactvar; /* # active locals outside the breakable structure */ | ||
78 | uint8_t upval; /* true if some variable in the block is an upvalue */ | ||
79 | uint8_t isbreakable; /* true if `block' is a loop */ | ||
80 | } FuncBlock; | ||
81 | |||
82 | typedef struct UpValDesc { | ||
83 | uint8_t k; | ||
84 | uint8_t info; | ||
85 | } UpValDesc; | ||
86 | |||
87 | /* Per-function state. */ | ||
88 | typedef struct FuncState { | ||
89 | GCproto *pt; /* current function header */ | ||
90 | GCtab *kt; /* table to find (and reuse) elements in `k' */ | ||
91 | struct FuncState *prev; /* enclosing function */ | ||
92 | struct LexState *ls; /* lexical state */ | ||
93 | struct lua_State *L; /* copy of the Lua state */ | ||
94 | struct FuncBlock *bl; /* chain of current blocks */ | ||
95 | BCPos pc; /* next bytecode position */ | ||
96 | BCPos lasttarget; /* PC of last jump target */ | ||
97 | BCPos jpc; /* list of pending jumps to PC */ | ||
98 | BCReg freereg; /* first free register */ | ||
99 | BCReg nkn, nkgc; /* number of lua_Number/GCobj constants */ | ||
100 | uint16_t nlocvars; /* number of elements in `locvars' */ | ||
101 | uint8_t nactvar; /* number of active local variables */ | ||
102 | uint8_t nuv; /* number of upvalues */ | ||
103 | UpValDesc upvalues[LJ_MAX_UPVAL]; /* upvalues */ | ||
104 | uint16_t actvar[LJ_MAX_LOCVAR]; /* declared-variable stack */ | ||
105 | } FuncState; | ||
106 | |||
107 | /* Binary and unary operators. ORDER OPR */ | ||
108 | typedef enum BinOpr { | ||
109 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */ | ||
110 | OPR_CONCAT, | ||
111 | OPR_NE, OPR_EQ, | ||
112 | OPR_LT, OPR_GE, OPR_LE, OPR_GT, | ||
113 | OPR_AND, OPR_OR, | ||
114 | OPR_NOBINOPR | ||
115 | } BinOpr; | ||
116 | |||
117 | LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT); | ||
118 | LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT); | ||
119 | LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT); | ||
120 | LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD); | ||
121 | LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD); | ||
122 | LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD); | ||
123 | LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); | ||
124 | |||
125 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | ||
126 | |||
127 | /* -- Error handling ------------------------------------------------------ */ | ||
128 | |||
129 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) | ||
130 | { | ||
131 | lj_lex_error(ls, ls->token, em); | ||
132 | } | ||
133 | |||
134 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token) | ||
135 | { | ||
136 | lj_lex_error(ls, ls->token, LJ_ERR_XTOKEN, lj_lex_token2str(ls, token)); | ||
137 | } | ||
138 | |||
139 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | ||
140 | { | ||
141 | if (fs->pt->linedefined == 0) | ||
142 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what); | ||
143 | else | ||
144 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->pt->linedefined, limit, what); | ||
145 | } | ||
146 | |||
147 | #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m) | ||
148 | #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m) | ||
149 | #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); } | ||
150 | |||
151 | /* -- Code emitter: branches ---------------------------------------------- */ | ||
152 | |||
153 | static BCPos getjump(FuncState *fs, BCPos pc) | ||
154 | { | ||
155 | ptrdiff_t delta = bc_j(fs->pt->bc[pc]); | ||
156 | if ((BCPos)delta == NO_JMP) | ||
157 | return NO_JMP; | ||
158 | else | ||
159 | return (BCPos)(((ptrdiff_t)pc+1)+delta); | ||
160 | } | ||
161 | |||
162 | static int need_value(FuncState *fs, BCPos list) | ||
163 | { | ||
164 | for (; list != NO_JMP; list = getjump(fs, list)) { | ||
165 | BCOp op = bc_op(fs->pt->bc[list >= 1 ? list-1 : list]); | ||
166 | if (!(op == BC_ISTC || op == BC_ISFC)) return 1; | ||
167 | } | ||
168 | return 0; /* Not found. */ | ||
169 | } | ||
170 | |||
171 | static int patchtestreg(FuncState *fs, BCPos pc, BCReg reg) | ||
172 | { | ||
173 | BCIns *i = &fs->pt->bc[pc >= 1 ? pc-1 : pc]; | ||
174 | BCOp op = bc_op(*i); | ||
175 | if (!(op == BC_ISTC || op == BC_ISFC)) | ||
176 | return 0; /* cannot patch other instructions */ | ||
177 | if (reg != NO_REG && reg != bc_d(*i)) { | ||
178 | setbc_a(i, reg); | ||
179 | } else { /* no register to put value or register already has the value */ | ||
180 | setbc_op(i, op+(BC_IST-BC_ISTC)); | ||
181 | setbc_a(i, 0); | ||
182 | } | ||
183 | return 1; | ||
184 | } | ||
185 | |||
186 | static void removevalues(FuncState *fs, BCPos list) | ||
187 | { | ||
188 | for (; list != NO_JMP; list = getjump(fs, list)) | ||
189 | patchtestreg(fs, list, NO_REG); | ||
190 | } | ||
191 | |||
192 | static void fixjump(FuncState *fs, BCPos pc, BCPos dest) | ||
193 | { | ||
194 | BCIns *jmp = &fs->pt->bc[pc]; | ||
195 | BCPos offset = dest-(pc+1)+BCBIAS_J; | ||
196 | lua_assert(dest != NO_JMP); | ||
197 | if (offset > BCMAX_D) | ||
198 | err_syntax(fs->ls, LJ_ERR_XJUMP); | ||
199 | setbc_d(jmp, offset); | ||
200 | } | ||
201 | |||
202 | static void concatjumps(FuncState *fs, BCPos *l1, BCPos l2) | ||
203 | { | ||
204 | if (l2 == NO_JMP) return; | ||
205 | else if (*l1 == NO_JMP) { | ||
206 | *l1 = l2; | ||
207 | } else { | ||
208 | BCPos list = *l1; | ||
209 | BCPos next; | ||
210 | while ((next = getjump(fs, list)) != NO_JMP) /* find last element */ | ||
211 | list = next; | ||
212 | fixjump(fs, list, l2); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static void patchlistaux(FuncState *fs, BCPos list, BCPos vtarget, | ||
217 | BCReg reg, BCPos dtarget) | ||
218 | { | ||
219 | while (list != NO_JMP) { | ||
220 | BCPos next = getjump(fs, list); | ||
221 | if (patchtestreg(fs, list, reg)) | ||
222 | fixjump(fs, list, vtarget); | ||
223 | else | ||
224 | fixjump(fs, list, dtarget); /* jump to default target */ | ||
225 | list = next; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static void patchtohere(FuncState *fs, BCPos list) | ||
230 | { | ||
231 | fs->lasttarget = fs->pc; | ||
232 | concatjumps(fs, &fs->jpc, list); | ||
233 | } | ||
234 | |||
235 | static void patchlist(FuncState *fs, BCPos list, BCPos target) | ||
236 | { | ||
237 | if (target == fs->pc) { | ||
238 | patchtohere(fs, list); | ||
239 | } else { | ||
240 | lua_assert(target < fs->pc); | ||
241 | patchlistaux(fs, list, target, NO_REG, target); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* -- Code emitter: instructions ------------------------------------------ */ | ||
246 | |||
247 | static BCPos emitINS(FuncState *fs, BCIns i) | ||
248 | { | ||
249 | GCproto *pt; | ||
250 | patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | ||
251 | fs->jpc = NO_JMP; | ||
252 | pt = fs->pt; | ||
253 | if (LJ_UNLIKELY(fs->pc >= pt->sizebc)) { | ||
254 | checklimit(fs, fs->pc, LJ_MAX_BCINS, "bytecode instructions"); | ||
255 | lj_mem_growvec(fs->L, pt->bc, pt->sizebc, LJ_MAX_BCINS, BCIns); | ||
256 | lj_mem_growvec(fs->L, pt->lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine); | ||
257 | } | ||
258 | pt->bc[fs->pc] = i; | ||
259 | pt->lineinfo[fs->pc] = fs->ls->lastline; | ||
260 | return fs->pc++; | ||
261 | } | ||
262 | |||
263 | #define emitABC(fs, o, a, b, c) emitINS(fs, BCINS_ABC(o, a, b, c)) | ||
264 | #define emitAD(fs, o, a, d) emitINS(fs, BCINS_AD(o, a, d)) | ||
265 | #define emitAJ(fs, o, a, j) emitINS(fs, BCINS_AJ(o, a, j)) | ||
266 | |||
267 | #define bcptr(fs, e) (&(fs)->pt->bc[(e)->u.s.info]) | ||
268 | |||
269 | static BCPos emit_jump(FuncState *fs) | ||
270 | { | ||
271 | BCPos jpc = fs->jpc; /* save list of jumps to here */ | ||
272 | BCPos j = fs->pc - 1; | ||
273 | fs->jpc = NO_JMP; | ||
274 | if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(fs->pt->bc[j]) == BC_UCLO) | ||
275 | setbc_j(&fs->pt->bc[j], NO_JMP); | ||
276 | else | ||
277 | j = emitAJ(fs, BC_JMP, fs->freereg, NO_JMP); | ||
278 | concatjumps(fs, &j, jpc); /* keep them on hold */ | ||
279 | return j; | ||
280 | } | ||
281 | |||
282 | /* -- Code emitter: constants --------------------------------------------- */ | ||
283 | |||
284 | static BCReg numK(FuncState *fs, ExpDesc *e) | ||
285 | { | ||
286 | lua_State *L = fs->L; | ||
287 | TValue *val; | ||
288 | lua_assert(isnumK(e)); | ||
289 | val = lj_tab_set(L, fs->kt, &e->u.nval); | ||
290 | if (tvisnum(val)) | ||
291 | return val->u32.lo; | ||
292 | val->u64 = fs->nkn; | ||
293 | return fs->nkn++; | ||
294 | } | ||
295 | |||
296 | static BCReg gcK(FuncState *fs, GCobj *gc, int itype) | ||
297 | { | ||
298 | lua_State *L = fs->L; | ||
299 | TValue o, *val; | ||
300 | setgcV(L, &o, &gc->gch, itype); | ||
301 | val = lj_tab_set(L, fs->kt, &o); | ||
302 | if (tvisnum(val)) | ||
303 | return val->u32.lo; | ||
304 | val->u64 = fs->nkgc; | ||
305 | return fs->nkgc++; | ||
306 | } | ||
307 | |||
308 | static BCReg strK(FuncState *fs, ExpDesc *e) | ||
309 | { | ||
310 | lua_assert(isstrK(e) || e->k == VGLOBAL); | ||
311 | return gcK(fs, obj2gco(e->u.sval), LJ_TSTR); | ||
312 | } | ||
313 | |||
314 | GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len) | ||
315 | { | ||
316 | lua_State *L = ls->L; | ||
317 | GCstr *s = lj_str_new(L, str, len); | ||
318 | TValue *tv = lj_tab_setstr(L, ls->fs->kt, s); | ||
319 | if (tvisnil(tv)) setboolV(tv, 1); /* Anchor string to avoid GC. */ | ||
320 | return s; | ||
321 | } | ||
322 | |||
323 | static void keep_token(LexState *ls) | ||
324 | { | ||
325 | if (ls->token == TK_name || ls->token == TK_string) { | ||
326 | TValue *tv = lj_tab_setstr(ls->L, ls->fs->kt, strV(&ls->tokenval)); | ||
327 | if (tvisnil(tv)) setboolV(tv, 1); /* Anchor string to avoid GC. */ | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static void nilK(FuncState *fs, BCReg from, BCReg n) | ||
332 | { | ||
333 | BCIns *pr; | ||
334 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ | ||
335 | BCReg pfrom, pto; | ||
336 | pr = &fs->pt->bc[fs->pc-1]; | ||
337 | pfrom = bc_a(*pr); | ||
338 | switch (bc_op(*pr)) { | ||
339 | case BC_KPRI: | ||
340 | if (bc_d(*pr) != ~LJ_TNIL) break; | ||
341 | if (from == pfrom) { | ||
342 | if (n == 1) return; | ||
343 | } else if (from == pfrom+1) { | ||
344 | from = pfrom; | ||
345 | n++; | ||
346 | } else { | ||
347 | break; | ||
348 | } | ||
349 | fs->pc--; | ||
350 | break; | ||
351 | case BC_KNIL: | ||
352 | pto = bc_d(*pr); | ||
353 | if (pfrom <= from && from <= pto+1) { /* can connect both? */ | ||
354 | if (from+n-1 > pto) | ||
355 | setbc_d(pr, from+n-1); | ||
356 | return; | ||
357 | } | ||
358 | break; | ||
359 | default: | ||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | emitINS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, priKk(VKNIL)) | ||
364 | : BCINS_AD(BC_KNIL, from, from+n-1)); | ||
365 | } | ||
366 | |||
367 | /* -- Code emitter: registers --------------------------------------------- */ | ||
368 | |||
369 | static void checkframe(FuncState *fs, BCReg n) | ||
370 | { | ||
371 | BCReg sz = fs->freereg + n; | ||
372 | if (sz > fs->pt->framesize) { | ||
373 | if (sz >= LJ_MAX_SLOTS) | ||
374 | err_syntax(fs->ls, LJ_ERR_XSLOTS); | ||
375 | fs->pt->framesize = cast_byte(sz); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static void reserveregs(FuncState *fs, BCReg n) | ||
380 | { | ||
381 | checkframe(fs, n); | ||
382 | fs->freereg += n; | ||
383 | } | ||
384 | |||
385 | static void freereg(FuncState *fs, BCReg reg) | ||
386 | { | ||
387 | if (reg >= fs->nactvar) { | ||
388 | fs->freereg--; | ||
389 | lua_assert(reg == fs->freereg); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | static void freeexp(FuncState *fs, ExpDesc *e) | ||
394 | { | ||
395 | if (e->k == VNONRELOC) | ||
396 | freereg(fs, e->u.s.info); | ||
397 | } | ||
398 | |||
399 | /* -- Code emitter: expressions ------------------------------------------- */ | ||
400 | |||
401 | static void dischargevars(FuncState *fs, ExpDesc *e) | ||
402 | { | ||
403 | BCIns ins; | ||
404 | switch (e->k) { | ||
405 | case VUPVAL: | ||
406 | ins = BCINS_AD(BC_UGET, 0, e->u.s.info); | ||
407 | break; | ||
408 | case VGLOBAL: | ||
409 | ins = BCINS_AD(BC_GGET, 0, strK(fs, e)); | ||
410 | break; | ||
411 | case VINDEXED: { | ||
412 | /* TGET[VSB] key = reg, string const or byte const */ | ||
413 | BCReg rc = e->u.s.aux; | ||
414 | if ((int32_t)rc < 0) { | ||
415 | ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc); | ||
416 | } else if (rc > BCMAX_C) { | ||
417 | ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1)); | ||
418 | } else { | ||
419 | freereg(fs, rc); | ||
420 | ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); | ||
421 | } | ||
422 | freereg(fs, e->u.s.info); | ||
423 | break; | ||
424 | } | ||
425 | case VCALL: | ||
426 | e->u.s.info = e->u.s.aux; | ||
427 | /* fallthrough */ | ||
428 | case VLOCAL: | ||
429 | e->k = VNONRELOC; | ||
430 | /* fallthrough */ | ||
431 | default: | ||
432 | return; | ||
433 | } | ||
434 | e->u.s.info = emitINS(fs, ins); | ||
435 | e->k = VRELOCABLE; | ||
436 | } | ||
437 | |||
438 | static void discharge2reg(FuncState *fs, ExpDesc *e, BCReg reg) | ||
439 | { | ||
440 | BCIns ins; | ||
441 | dischargevars(fs, e); | ||
442 | switch (e->k) { | ||
443 | case VKNIL: case VKFALSE: case VKTRUE: | ||
444 | ins = BCINS_AD(BC_KPRI, reg, priK(e)); | ||
445 | break; | ||
446 | case VKSTR: | ||
447 | ins = BCINS_AD(BC_KSTR, reg, strK(fs, e)); | ||
448 | break; | ||
449 | case VKNUM: { | ||
450 | lua_Number n = expnumV(e); | ||
451 | int32_t k = lj_num2int(n); | ||
452 | if (checki16(k) && n == cast_num(k)) | ||
453 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | ||
454 | else | ||
455 | ins = BCINS_AD(BC_KNUM, reg, numK(fs, e)); | ||
456 | break; | ||
457 | } | ||
458 | case VRELOCABLE: | ||
459 | setbc_a(bcptr(fs, e), reg); | ||
460 | goto noins; | ||
461 | case VNONRELOC: | ||
462 | if (reg == e->u.s.info) | ||
463 | goto noins; | ||
464 | ins = BCINS_AD(BC_MOV, reg, e->u.s.info); | ||
465 | break; | ||
466 | default: | ||
467 | lua_assert(e->k == VVOID || e->k == VJMP); | ||
468 | return; /* nothing to do... */ | ||
469 | } | ||
470 | emitINS(fs, ins); | ||
471 | noins: | ||
472 | e->u.s.info = reg; | ||
473 | e->k = VNONRELOC; | ||
474 | } | ||
475 | |||
476 | static void exp2reg(FuncState *fs, ExpDesc *e, BCReg reg) | ||
477 | { | ||
478 | discharge2reg(fs, e, reg); | ||
479 | if (e->k == VJMP) | ||
480 | concatjumps(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ | ||
481 | if (hasjumps(e)) { | ||
482 | BCPos final; /* position after whole expression */ | ||
483 | BCPos p_f = NO_JMP; /* position of an eventual LOAD false */ | ||
484 | BCPos p_t = NO_JMP; /* position of an eventual LOAD true */ | ||
485 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | ||
486 | BCPos fj = (e->k == VJMP) ? NO_JMP : emit_jump(fs); | ||
487 | p_f = emitAD(fs, BC_KPRI, reg, priKk(VKFALSE)); | ||
488 | emitAJ(fs, BC_JMP, fs->freereg, 1); | ||
489 | p_t = emitAD(fs, BC_KPRI, reg, priKk(VKTRUE)); | ||
490 | patchtohere(fs, fj); | ||
491 | } | ||
492 | final = fs->pc; | ||
493 | fs->lasttarget = final; | ||
494 | patchlistaux(fs, e->f, final, reg, p_f); | ||
495 | patchlistaux(fs, e->t, final, reg, p_t); | ||
496 | } | ||
497 | e->f = e->t = NO_JMP; | ||
498 | e->u.s.info = reg; | ||
499 | e->k = VNONRELOC; | ||
500 | } | ||
501 | |||
502 | static void exp2nextreg(FuncState *fs, ExpDesc *e) | ||
503 | { | ||
504 | dischargevars(fs, e); | ||
505 | freeexp(fs, e); | ||
506 | reserveregs(fs, 1); | ||
507 | exp2reg(fs, e, fs->freereg - 1); | ||
508 | } | ||
509 | |||
510 | static BCReg exp2anyreg(FuncState *fs, ExpDesc *e) | ||
511 | { | ||
512 | dischargevars(fs, e); | ||
513 | if (e->k == VNONRELOC) { | ||
514 | if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ | ||
515 | if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ | ||
516 | exp2reg(fs, e, e->u.s.info); /* put value on it */ | ||
517 | return e->u.s.info; | ||
518 | } | ||
519 | } | ||
520 | exp2nextreg(fs, e); /* default */ | ||
521 | return e->u.s.info; | ||
522 | } | ||
523 | |||
524 | static void exp2val(FuncState *fs, ExpDesc *e) | ||
525 | { | ||
526 | if (hasjumps(e)) | ||
527 | exp2anyreg(fs, e); | ||
528 | else | ||
529 | dischargevars(fs, e); | ||
530 | } | ||
531 | |||
532 | static void storevar(FuncState *fs, ExpDesc *var, ExpDesc *e) | ||
533 | { | ||
534 | BCIns ins; | ||
535 | switch (var->k) { | ||
536 | case VLOCAL: | ||
537 | freeexp(fs, e); | ||
538 | exp2reg(fs, e, var->u.s.info); | ||
539 | return; | ||
540 | case VUPVAL: | ||
541 | exp2val(fs, e); | ||
542 | switch (e->k) { | ||
543 | case VKNIL: case VKFALSE: case VKTRUE: | ||
544 | ins = BCINS_AD(BC_USETP, var->u.s.info, priK(e)); | ||
545 | break; | ||
546 | case VKSTR: | ||
547 | ins = BCINS_AD(BC_USETS, var->u.s.info, strK(fs, e)); | ||
548 | break; | ||
549 | case VKNUM: | ||
550 | ins = BCINS_AD(BC_USETN, var->u.s.info, numK(fs, e)); | ||
551 | break; | ||
552 | default: | ||
553 | ins = BCINS_AD(BC_USETV, var->u.s.info, exp2anyreg(fs, e)); | ||
554 | break; | ||
555 | } | ||
556 | break; | ||
557 | case VGLOBAL: { | ||
558 | BCReg ra = exp2anyreg(fs, e); | ||
559 | ins = BCINS_AD(BC_GSET, ra, strK(fs, var)); | ||
560 | break; | ||
561 | } | ||
562 | case VINDEXED: { | ||
563 | /* TSET[VSB] key = reg, string const or byte const */ | ||
564 | BCReg ra = exp2anyreg(fs, e); | ||
565 | BCReg rc = var->u.s.aux; | ||
566 | if ((int32_t)rc < 0) { | ||
567 | ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc); | ||
568 | } else if (rc > BCMAX_C) { | ||
569 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); | ||
570 | } else { | ||
571 | /* Free late alloced key reg to avoid assert on free of value reg. */ | ||
572 | /* This can only happen when called from constructor(). */ | ||
573 | lua_assert(e->k != VNONRELOC || ra < fs->nactvar || | ||
574 | rc < ra || (freereg(fs, rc),1)); | ||
575 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); | ||
576 | } | ||
577 | break; | ||
578 | } | ||
579 | default: | ||
580 | lua_assert(0); /* invalid var kind to store */ | ||
581 | return; | ||
582 | } | ||
583 | emitINS(fs, ins); | ||
584 | freeexp(fs, e); | ||
585 | } | ||
586 | |||
587 | static void indexexp(FuncState *fs, ExpDesc *t, ExpDesc *e) | ||
588 | { | ||
589 | /* already called: exp2val(fs, e) */ | ||
590 | t->k = VINDEXED; | ||
591 | if (isnumK(e)) { | ||
592 | lua_Number n = expnumV(e); | ||
593 | int32_t k = lj_num2int(n); | ||
594 | if (checku8(k) && n == cast_num(k)) { | ||
595 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | ||
596 | return; | ||
597 | } | ||
598 | } else if (isstrK(e)) { | ||
599 | BCReg idx = strK(fs, e); | ||
600 | if (idx <= BCMAX_C) { | ||
601 | t->u.s.aux = ~idx; /* -256..-1: const string key */ | ||
602 | return; | ||
603 | } | ||
604 | } | ||
605 | t->u.s.aux = exp2anyreg(fs, e); /* 0..255: register */ | ||
606 | } | ||
607 | |||
608 | static void methodexp(FuncState *fs, ExpDesc *e, ExpDesc *key) | ||
609 | { | ||
610 | BCReg idx, func, tab = exp2anyreg(fs, e); | ||
611 | freeexp(fs, e); | ||
612 | func = fs->freereg; | ||
613 | emitAD(fs, BC_MOV, func+1, tab); | ||
614 | lua_assert(isstrK(key)); | ||
615 | idx = strK(fs, key); | ||
616 | if (idx <= BCMAX_C) { | ||
617 | reserveregs(fs, 2); | ||
618 | emitABC(fs, BC_TGETS, func, tab, idx); | ||
619 | } else { | ||
620 | reserveregs(fs, 3); | ||
621 | emitAD(fs, BC_KSTR, func+2, idx); | ||
622 | emitABC(fs, BC_TGETV, func, tab, func+2); | ||
623 | fs->freereg--; | ||
624 | } | ||
625 | e->u.s.info = func; | ||
626 | e->k = VNONRELOC; | ||
627 | } | ||
628 | |||
629 | /* -- Code emitter: conditionals ------------------------------------------ */ | ||
630 | |||
631 | static void invertjump(FuncState *fs, ExpDesc *e) | ||
632 | { | ||
633 | BCIns *i = bcptr(fs, e) - 1; | ||
634 | setbc_op(i, bc_op(*i)^1); | ||
635 | } | ||
636 | |||
637 | static BCPos jumponcond(FuncState *fs, ExpDesc *e, int cond) | ||
638 | { | ||
639 | if (e->k == VRELOCABLE) { | ||
640 | BCIns *i = bcptr(fs, e); | ||
641 | if (bc_op(*i) == BC_NOT) { | ||
642 | *i = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*i)); | ||
643 | return emit_jump(fs); | ||
644 | } | ||
645 | /* else go through */ | ||
646 | } | ||
647 | if (e->k != VNONRELOC) { | ||
648 | reserveregs(fs, 1); | ||
649 | discharge2reg(fs, e, fs->freereg-1); | ||
650 | } | ||
651 | freeexp(fs, e); | ||
652 | emitAD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info); | ||
653 | return emit_jump(fs); | ||
654 | } | ||
655 | |||
656 | static void goiftrue(FuncState *fs, ExpDesc *e) | ||
657 | { | ||
658 | BCPos pc; /* PC of last jump. */ | ||
659 | dischargevars(fs, e); | ||
660 | switch (e->k) { | ||
661 | case VKSTR: case VKNUM: case VKTRUE: | ||
662 | pc = NO_JMP; /* always true; do nothing */ | ||
663 | break; | ||
664 | case VJMP: | ||
665 | invertjump(fs, e); | ||
666 | pc = e->u.s.info; | ||
667 | break; | ||
668 | case VKFALSE: | ||
669 | if (!hasjumps(e)) { | ||
670 | pc = emit_jump(fs); /* always jump */ | ||
671 | break; | ||
672 | } | ||
673 | /* fallthrough */ | ||
674 | default: | ||
675 | pc = jumponcond(fs, e, 0); | ||
676 | break; | ||
677 | } | ||
678 | concatjumps(fs, &e->f, pc); /* insert last jump in `f' list */ | ||
679 | patchtohere(fs, e->t); | ||
680 | e->t = NO_JMP; | ||
681 | } | ||
682 | |||
683 | static void goiffalse(FuncState *fs, ExpDesc *e) | ||
684 | { | ||
685 | BCPos pc; /* PC of last jump. */ | ||
686 | dischargevars(fs, e); | ||
687 | switch (e->k) { | ||
688 | case VKNIL: case VKFALSE: | ||
689 | pc = NO_JMP; /* always false; do nothing */ | ||
690 | break; | ||
691 | case VJMP: | ||
692 | pc = e->u.s.info; | ||
693 | break; | ||
694 | case VKTRUE: | ||
695 | if (!hasjumps(e)) { | ||
696 | pc = emit_jump(fs); /* always jump */ | ||
697 | break; | ||
698 | } | ||
699 | /* fallthrough */ | ||
700 | default: | ||
701 | pc = jumponcond(fs, e, 1); | ||
702 | break; | ||
703 | } | ||
704 | concatjumps(fs, &e->t, pc); /* insert last jump in `t' list */ | ||
705 | patchtohere(fs, e->f); | ||
706 | e->f = NO_JMP; | ||
707 | } | ||
708 | |||
709 | /* -- Code emitter: operators --------------------------------------------- */ | ||
710 | |||
711 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | ||
712 | { | ||
713 | TValue o; | ||
714 | if (!isnumKexp(e1) || !isnumKexp(e2)) return 0; | ||
715 | setnumV(&o, lj_vm_foldarith(expnumV(e1), expnumV(e2), (int)opr-OPR_ADD)); | ||
716 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | ||
717 | setnumV(&e1->u.nval, numV(&o)); | ||
718 | return 1; | ||
719 | } | ||
720 | |||
721 | static void codearith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | ||
722 | { | ||
723 | BCReg rb, rc, t; | ||
724 | uint32_t op; | ||
725 | if (foldarith(opr, e1, e2)) | ||
726 | return; | ||
727 | if (opr == OPR_POW) { | ||
728 | op = BC_POW; | ||
729 | rc = exp2anyreg(fs, e2); | ||
730 | rb = exp2anyreg(fs, e1); | ||
731 | } else { | ||
732 | op = opr-OPR_ADD+BC_ADDVV; | ||
733 | /* must discharge 2nd operand first since VINDEXED might free regs */ | ||
734 | exp2val(fs, e2); | ||
735 | if (isnumK(e2) && (rc = numK(fs, e2)) <= BCMAX_C) | ||
736 | op -= BC_ADDVV-BC_ADDVN; | ||
737 | else | ||
738 | rc = exp2anyreg(fs, e2); | ||
739 | /* emit_prebinop discharges 1st operand, but may need to use KNUM/KSHORT */ | ||
740 | lua_assert(isnumK(e1) || e1->k == VNONRELOC); | ||
741 | exp2val(fs, e1); | ||
742 | /* avoid two consts to satisfy bytecode constraints */ | ||
743 | if (isnumK(e1) && !isnumK(e2) && (t = numK(fs, e1)) <= BCMAX_B) { | ||
744 | rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV; | ||
745 | } else { | ||
746 | rb = exp2anyreg(fs, e1); | ||
747 | } | ||
748 | } | ||
749 | /* using freeexp might cause asserts if the order is wrong */ | ||
750 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | ||
751 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | ||
752 | e1->u.s.info = emitABC(fs, op, 0, rb, rc); | ||
753 | e1->k = VRELOCABLE; | ||
754 | } | ||
755 | |||
756 | static void codecomp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) | ||
757 | { | ||
758 | ExpDesc *eret = e1; | ||
759 | BCIns ins; | ||
760 | exp2val(fs, e1); | ||
761 | if (opr == OPR_EQ || opr == OPR_NE) { | ||
762 | BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV; | ||
763 | BCReg ra; | ||
764 | if (isK(e1)) { e1 = e2; e2 = eret; } /* need constant in 2nd arg */ | ||
765 | ra = exp2anyreg(fs, e1); /* first arg must be in a reg */ | ||
766 | exp2val(fs, e2); | ||
767 | switch (e2->k) { | ||
768 | case VKNIL: case VKFALSE: case VKTRUE: | ||
769 | ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, priK(e2)); | ||
770 | break; | ||
771 | case VKSTR: | ||
772 | ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, strK(fs, e2)); | ||
773 | break; | ||
774 | case VKNUM: | ||
775 | ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, numK(fs, e2)); | ||
776 | break; | ||
777 | default: | ||
778 | ins = BCINS_AD(op, ra, exp2anyreg(fs, e2)); | ||
779 | break; | ||
780 | } | ||
781 | } else { | ||
782 | uint32_t op = opr-OPR_LT+BC_ISLT; | ||
783 | BCReg ra; | ||
784 | if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */ | ||
785 | e1 = e2; e2 = eret; /* swap operands */ | ||
786 | op = ((op-BC_ISLT)^3)+BC_ISLT; | ||
787 | } | ||
788 | ra = exp2anyreg(fs, e1); | ||
789 | ins = BCINS_AD(op, ra, exp2anyreg(fs, e2)); | ||
790 | } | ||
791 | /* using freeexp might cause asserts if the order is wrong */ | ||
792 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; | ||
793 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; | ||
794 | emitINS(fs, ins); | ||
795 | eret->u.s.info = emit_jump(fs); | ||
796 | eret->k = VJMP; | ||
797 | } | ||
798 | |||
799 | static void emit_unop(FuncState *fs, UnOpr uop, ExpDesc *e) | ||
800 | { | ||
801 | BCOp op = BC_LEN; | ||
802 | switch (uop) { | ||
803 | case OPR_MINUS: | ||
804 | if (isnumKexp(e) && expnumV(e) != 0) { /* Avoid const-folding to -0. */ | ||
805 | setnumV(&e->u.nval, -expnumV(e)); | ||
806 | return; | ||
807 | } | ||
808 | op = BC_UNM; | ||
809 | /* fallthrough */ | ||
810 | case OPR_LEN: | ||
811 | exp2anyreg(fs, e); | ||
812 | break; | ||
813 | case OPR_NOT: | ||
814 | /* interchange true and false lists */ | ||
815 | { BCPos temp = e->f; e->f = e->t; e->t = temp; } | ||
816 | removevalues(fs, e->f); | ||
817 | removevalues(fs, e->t); | ||
818 | dischargevars(fs, e); | ||
819 | switch (e->k) { | ||
820 | case VKNIL: case VKFALSE: | ||
821 | e->k = VKTRUE; | ||
822 | return; | ||
823 | case VKSTR: case VKNUM: case VKTRUE: | ||
824 | e->k = VKFALSE; | ||
825 | return; | ||
826 | case VJMP: | ||
827 | invertjump(fs, e); | ||
828 | return; | ||
829 | case VRELOCABLE: | ||
830 | reserveregs(fs, 1); | ||
831 | setbc_a(bcptr(fs, e), fs->freereg-1); | ||
832 | e->u.s.info = fs->freereg-1; | ||
833 | e->k = VNONRELOC; | ||
834 | break; | ||
835 | case VNONRELOC: | ||
836 | break; | ||
837 | default: lua_assert(0); return; | ||
838 | } | ||
839 | op = BC_NOT; | ||
840 | break; | ||
841 | default: lua_assert(0); return; | ||
842 | } | ||
843 | freeexp(fs, e); | ||
844 | e->u.s.info = emitAD(fs, op, 0, e->u.s.info); | ||
845 | e->k = VRELOCABLE; | ||
846 | } | ||
847 | |||
848 | static void prepare_binop(FuncState *fs, BinOpr op, ExpDesc *e) | ||
849 | { | ||
850 | switch (op) { | ||
851 | case OPR_AND: | ||
852 | goiftrue(fs, e); | ||
853 | break; | ||
854 | case OPR_OR: | ||
855 | goiffalse(fs, e); | ||
856 | break; | ||
857 | case OPR_CONCAT: | ||
858 | exp2nextreg(fs, e); /* operand must be on the `stack' */ | ||
859 | break; | ||
860 | case OPR_EQ: case OPR_NE: | ||
861 | if (!isKexp(e)) exp2anyreg(fs, e); | ||
862 | break; | ||
863 | default: | ||
864 | if (!isnumKexp(e)) exp2anyreg(fs, e); | ||
865 | break; | ||
866 | } | ||
867 | } | ||
868 | |||
869 | static void emit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) | ||
870 | { | ||
871 | switch (op) { | ||
872 | case OPR_AND: | ||
873 | lua_assert(e1->t == NO_JMP); /* list must be closed */ | ||
874 | dischargevars(fs, e2); | ||
875 | concatjumps(fs, &e2->f, e1->f); | ||
876 | *e1 = *e2; | ||
877 | break; | ||
878 | case OPR_OR: | ||
879 | lua_assert(e1->f == NO_JMP); /* list must be closed */ | ||
880 | dischargevars(fs, e2); | ||
881 | concatjumps(fs, &e2->t, e1->t); | ||
882 | *e1 = *e2; | ||
883 | break; | ||
884 | case OPR_CONCAT: | ||
885 | exp2val(fs, e2); | ||
886 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { | ||
887 | lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1); | ||
888 | freeexp(fs, e1); | ||
889 | setbc_b(bcptr(fs, e2), e1->u.s.info); | ||
890 | e1->u.s.info = e2->u.s.info; | ||
891 | } else { | ||
892 | exp2nextreg(fs, e2); | ||
893 | freeexp(fs, e2); | ||
894 | freeexp(fs, e1); | ||
895 | e1->u.s.info = emitABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info); | ||
896 | } | ||
897 | e1->k = VRELOCABLE; | ||
898 | break; | ||
899 | case OPR_ADD: case OPR_SUB: case OPR_MUL: | ||
900 | case OPR_DIV: case OPR_MOD: case OPR_POW: | ||
901 | codearith(fs, op, e1, e2); | ||
902 | break; | ||
903 | case OPR_EQ: case OPR_NE: | ||
904 | case OPR_LT: case OPR_LE: case OPR_GT: case OPR_GE: | ||
905 | codecomp(fs, op, e1, e2); | ||
906 | break; | ||
907 | default: lua_assert(0); break; | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* -- Lexer support ------------------------------------------------------- */ | ||
912 | |||
913 | static int testnext(LexState *ls, LexToken tok) | ||
914 | { | ||
915 | if (ls->token == tok) { | ||
916 | lj_lex_next(ls); | ||
917 | return 1; | ||
918 | } | ||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static void checknext(LexState *ls, LexToken tok) | ||
923 | { | ||
924 | if (ls->token != tok) | ||
925 | err_token(ls, tok); | ||
926 | lj_lex_next(ls); | ||
927 | } | ||
928 | |||
929 | static void checkmatch(LexState *ls, LexToken what, LexToken who, BCLine line) | ||
930 | { | ||
931 | if (!testnext(ls, what)) { | ||
932 | if (line == ls->linenumber) { | ||
933 | err_token(ls, what); | ||
934 | } else { | ||
935 | const char *swhat = lj_lex_token2str(ls, what); | ||
936 | const char *swho = lj_lex_token2str(ls, who); | ||
937 | lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line); | ||
938 | } | ||
939 | } | ||
940 | } | ||
941 | |||
942 | static GCstr *str_checkname(LexState *ls) | ||
943 | { | ||
944 | GCstr *s; | ||
945 | if (ls->token != TK_name) | ||
946 | err_token(ls, TK_name); | ||
947 | s = strV(&ls->tokenval); | ||
948 | lj_lex_next(ls); | ||
949 | return s; | ||
950 | } | ||
951 | |||
952 | static void init_exp(ExpDesc *e, ExpKind k, uint32_t info) | ||
953 | { | ||
954 | e->k = k; | ||
955 | e->u.s.info = info; | ||
956 | e->f = e->t = NO_JMP; | ||
957 | } | ||
958 | |||
959 | static void checkname(LexState *ls, ExpDesc *e) | ||
960 | { | ||
961 | init_exp(e, VKSTR, 0); | ||
962 | e->u.sval = str_checkname(ls); | ||
963 | } | ||
964 | |||
965 | /* -- Variable handling --------------------------------------------------- */ | ||
966 | |||
967 | #define getlocvar(fs, i) ((fs)->pt->varinfo[(fs)->actvar[(i)]]) | ||
968 | |||
969 | static BCReg registerlocalvar(LexState *ls, GCstr *name) | ||
970 | { | ||
971 | FuncState *fs = ls->fs; | ||
972 | GCproto *pt = fs->pt; | ||
973 | if (LJ_UNLIKELY(fs->nlocvars >= pt->sizevarinfo)) { | ||
974 | MSize oldsize = pt->sizevarinfo; | ||
975 | checklimit(fs, fs->nlocvars, 32767, "local variables"); | ||
976 | lj_mem_growvec(fs->L, pt->varinfo, pt->sizevarinfo, 32767, VarInfo); | ||
977 | while (oldsize < pt->sizevarinfo) pt->varinfo[oldsize++].name = NULL; | ||
978 | } | ||
979 | pt->varinfo[fs->nlocvars].name = name; | ||
980 | lj_gc_objbarrier(ls->L, pt, name); | ||
981 | return fs->nlocvars++; | ||
982 | } | ||
983 | |||
984 | static void new_localvar(LexState *ls, GCstr *name, BCReg n) | ||
985 | { | ||
986 | FuncState *fs = ls->fs; | ||
987 | checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables"); | ||
988 | fs->actvar[fs->nactvar+n] = cast(uint16_t, registerlocalvar(ls, name)); | ||
989 | } | ||
990 | |||
991 | #define new_localvarliteral(ls,v,n) \ | ||
992 | new_localvar(ls, lj_parse_keepstr(ls, "" v, sizeof(v)-1), n) | ||
993 | |||
994 | static void adjustlocalvars(LexState *ls, BCReg nvars) | ||
995 | { | ||
996 | FuncState *fs = ls->fs; | ||
997 | fs->nactvar = cast_byte(fs->nactvar + nvars); | ||
998 | for (; nvars; nvars--) | ||
999 | getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; | ||
1000 | } | ||
1001 | |||
1002 | static void removevars(LexState *ls, BCReg tolevel) | ||
1003 | { | ||
1004 | FuncState *fs = ls->fs; | ||
1005 | while (fs->nactvar > tolevel) | ||
1006 | getlocvar(fs, --fs->nactvar).endpc = fs->pc; | ||
1007 | } | ||
1008 | |||
1009 | static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) | ||
1010 | { | ||
1011 | uint32_t i; | ||
1012 | GCproto *pt = fs->pt; | ||
1013 | for (i = 0; i < fs->nuv; i++) { | ||
1014 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { | ||
1015 | lua_assert(pt->uvname[i] == name); | ||
1016 | return i; | ||
1017 | } | ||
1018 | } | ||
1019 | /* Not found, create a new upvalue for this name. */ | ||
1020 | if (LJ_UNLIKELY(fs->nuv >= pt->sizeuvname)) { | ||
1021 | MSize oldsize = pt->sizeuvname; | ||
1022 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); | ||
1023 | lj_mem_growvec(fs->L, pt->uvname, pt->sizeuvname, LJ_MAX_UPVAL, GCstr *); | ||
1024 | while (oldsize < pt->sizeuvname) pt->uvname[oldsize++] = NULL; | ||
1025 | } | ||
1026 | pt->uvname[fs->nuv] = name; | ||
1027 | lj_gc_objbarrier(fs->L, pt, name); | ||
1028 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | ||
1029 | fs->upvalues[fs->nuv].k = cast_byte(v->k); | ||
1030 | fs->upvalues[fs->nuv].info = cast_byte(v->u.s.info); | ||
1031 | return fs->nuv++; | ||
1032 | } | ||
1033 | |||
1034 | static BCReg searchvar(FuncState *fs, GCstr *n) | ||
1035 | { | ||
1036 | int i; | ||
1037 | for (i = fs->nactvar-1; i >= 0; i--) { | ||
1038 | if (n == getlocvar(fs, i).name) | ||
1039 | return (BCReg)i; | ||
1040 | } | ||
1041 | return (BCReg)-1; /* Not found. */ | ||
1042 | } | ||
1043 | |||
1044 | static void markupval(FuncState *fs, BCReg level) | ||
1045 | { | ||
1046 | FuncBlock *bl = fs->bl; | ||
1047 | while (bl && bl->nactvar > level) bl = bl->previous; | ||
1048 | if (bl) bl->upval = 1; | ||
1049 | } | ||
1050 | |||
1051 | static int singlevaraux(FuncState *fs, GCstr *name, ExpDesc *e, int first) | ||
1052 | { | ||
1053 | if (fs == NULL) { /* no more levels? */ | ||
1054 | init_exp(e, VGLOBAL, 0); /* default is global variable */ | ||
1055 | e->u.sval = name; | ||
1056 | return 1; | ||
1057 | } else { | ||
1058 | BCReg reg = searchvar(fs, name); /* look up at current level */ | ||
1059 | if ((int32_t)reg >= 0) { | ||
1060 | init_exp(e, VLOCAL, reg); | ||
1061 | if (!first) | ||
1062 | markupval(fs, reg); /* local will be used as an upval */ | ||
1063 | return 0; | ||
1064 | } else { /* not found at current level; try upper one */ | ||
1065 | if (singlevaraux(fs->prev, name, e, 0)) /* global? */ | ||
1066 | return 1; | ||
1067 | e->u.s.info = indexupvalue(fs, name, e); /* else was local or upvalue */ | ||
1068 | e->k = VUPVAL; /* upvalue in this level */ | ||
1069 | return 0; | ||
1070 | } | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | #define singlevar(ls, e) singlevaraux((ls)->fs, str_checkname(ls), (e), 1) | ||
1075 | |||
1076 | static void adjust_assign(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) | ||
1077 | { | ||
1078 | FuncState *fs = ls->fs; | ||
1079 | int32_t extra = (int32_t)nvars - (int32_t)nexps; | ||
1080 | if (e->k == VCALL) { | ||
1081 | extra++; /* includes call itself */ | ||
1082 | if (extra < 0) extra = 0; | ||
1083 | setbc_b(bcptr(fs, e), extra+1); | ||
1084 | if (extra > 1) reserveregs(fs, (BCReg)extra-1); | ||
1085 | } else { | ||
1086 | if (e->k != VVOID) exp2nextreg(fs, e); /* close last expression */ | ||
1087 | if (extra > 0) { | ||
1088 | BCReg reg = fs->freereg; | ||
1089 | reserveregs(fs, (BCReg)extra); | ||
1090 | nilK(fs, reg, (BCReg)extra); | ||
1091 | } | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /* -- Function handling --------------------------------------------------- */ | ||
1096 | |||
1097 | /* Forward declaration. */ | ||
1098 | static void chunk(LexState *ls); | ||
1099 | |||
1100 | static void open_func(LexState *ls, FuncState *fs) | ||
1101 | { | ||
1102 | lua_State *L = ls->L; | ||
1103 | GCproto *pt = lj_func_newproto(L); | ||
1104 | fs->pt = pt; | ||
1105 | fs->prev = ls->fs; /* linked list of funcstates */ | ||
1106 | fs->ls = ls; | ||
1107 | fs->L = L; | ||
1108 | ls->fs = fs; | ||
1109 | fs->pc = 0; | ||
1110 | fs->lasttarget = 0; | ||
1111 | fs->jpc = NO_JMP; | ||
1112 | fs->freereg = 0; | ||
1113 | fs->nkgc = 0; | ||
1114 | fs->nkn = 0; | ||
1115 | fs->nlocvars = 0; | ||
1116 | fs->nactvar = 0; | ||
1117 | fs->nuv = 0; | ||
1118 | fs->bl = NULL; | ||
1119 | pt->chunkname = ls->chunkname; | ||
1120 | pt->framesize = 2; /* registers 0/1 are always valid */ | ||
1121 | fs->kt = lj_tab_new(L, 0, 0); | ||
1122 | /* anchor table of constants and prototype (to avoid being collected) */ | ||
1123 | settabV(L, L->top, fs->kt); | ||
1124 | incr_top(L); | ||
1125 | setprotoV(L, L->top, pt); | ||
1126 | incr_top(L); | ||
1127 | } | ||
1128 | |||
1129 | static void collectk(FuncState *fs, GCproto *pt) | ||
1130 | { | ||
1131 | GCtab *kt; | ||
1132 | TValue *array; | ||
1133 | Node *node; | ||
1134 | BCReg nkgc; | ||
1135 | MSize i, hmask, sizek; | ||
1136 | GCRef *kstart; | ||
1137 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); | ||
1138 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); | ||
1139 | nkgc = round_nkgc(fs->nkgc); | ||
1140 | sizek = (MSize)(nkgc*sizeof(MRef) + fs->nkn*sizeof(lua_Number)); | ||
1141 | kstart = lj_mem_newt(fs->L, sizek, GCRef); | ||
1142 | if (nkgc) setgcrefnull(kstart[0]); /* May be uninitialized otherwise. */ | ||
1143 | pt->k.gc = kstart + nkgc; | ||
1144 | pt->sizekn = fs->nkn; | ||
1145 | pt->sizekgc = fs->nkgc; | ||
1146 | kt = fs->kt; | ||
1147 | array = tvref(kt->array); | ||
1148 | for (i = 0; i < kt->asize; i++) | ||
1149 | if (tvisnum(&array[i])) | ||
1150 | pt->k.n[array[i].u32.lo] = cast_num(i); | ||
1151 | node = noderef(kt->node); | ||
1152 | hmask = kt->hmask; | ||
1153 | for (i = 0; i <= hmask; i++) { | ||
1154 | Node *n = &node[i]; | ||
1155 | if (tvisnum(&n->val)) { | ||
1156 | ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo; | ||
1157 | if (tvisnum(&n->key)) { | ||
1158 | pt->k.n[kidx] = numV(&n->key); | ||
1159 | } else { | ||
1160 | GCobj *o = gcV(&n->key); | ||
1161 | setgcref(pt->k.gc[~kidx], o); | ||
1162 | lj_gc_objbarrier(fs->L, pt, o); | ||
1163 | } | ||
1164 | } | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | static void collectuv(FuncState *fs, GCproto *pt) | ||
1169 | { | ||
1170 | uint32_t i; | ||
1171 | pt->uv = lj_mem_newvec(fs->L, fs->nuv, int16_t); | ||
1172 | pt->sizeuv = fs->nuv; | ||
1173 | for (i = 0; i < pt->sizeuv; i++) { | ||
1174 | uint32_t v = fs->upvalues[i].info; | ||
1175 | if (fs->upvalues[i].k == VUPVAL) v = ~v; | ||
1176 | pt->uv[i] = (int16_t)v; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | static void finalret(FuncState *fs, GCproto *pt) | ||
1181 | { | ||
1182 | BCPos lastpc = fs->pc; | ||
1183 | if (lastpc > fs->lasttarget) { | ||
1184 | switch (bc_op(pt->bc[lastpc-1])) { | ||
1185 | case BC_CALLMT: case BC_CALLT: | ||
1186 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | ||
1187 | goto suppress_return; /* already got a return */ | ||
1188 | default: break; | ||
1189 | } | ||
1190 | } | ||
1191 | if (fs->pt->flags & PROTO_HAS_FNEW) | ||
1192 | emitAJ(fs, BC_UCLO, 0, 0); | ||
1193 | emitAD(fs, BC_RET0, 0, 1); /* final return */ | ||
1194 | suppress_return: | ||
1195 | /* may need to fixup returns encoded before first function was created */ | ||
1196 | if (fs->pt->flags & PROTO_FIXUP_RETURN) { | ||
1197 | BCPos pc; | ||
1198 | for (pc = 0; pc < lastpc; pc++) { | ||
1199 | BCIns i = pt->bc[pc]; | ||
1200 | BCPos offset; | ||
1201 | switch (bc_op(i)) { | ||
1202 | case BC_CALLMT: case BC_CALLT: | ||
1203 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | ||
1204 | offset = emitINS(fs, i)-(pc+1)+BCBIAS_J; /* copy return ins */ | ||
1205 | if (offset > BCMAX_D) | ||
1206 | err_syntax(fs->ls, LJ_ERR_XFIXUP); | ||
1207 | pt->bc[pc] = BCINS_AD(BC_UCLO, 0, offset); /* replace w/ UCLO+branch */ | ||
1208 | break; | ||
1209 | case BC_UCLO: return; /* we're done */ | ||
1210 | default: break; | ||
1211 | } | ||
1212 | } | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | static void close_func(LexState *ls) | ||
1217 | { | ||
1218 | lua_State *L = ls->L; | ||
1219 | FuncState *fs = ls->fs; | ||
1220 | GCproto *pt = fs->pt; | ||
1221 | removevars(ls, 0); | ||
1222 | finalret(fs, pt); | ||
1223 | lj_mem_reallocvec(L, pt->bc, pt->sizebc, fs->pc, BCIns); | ||
1224 | pt->sizebc = fs->pc; | ||
1225 | collectk(fs, pt); | ||
1226 | collectuv(fs, pt); | ||
1227 | lj_mem_reallocvec(L, pt->lineinfo, pt->sizelineinfo, fs->pc, BCLine); | ||
1228 | pt->sizelineinfo = fs->pc; | ||
1229 | lj_mem_reallocvec(L, pt->varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); | ||
1230 | pt->sizevarinfo = fs->nlocvars; | ||
1231 | lj_mem_reallocvec(L, pt->uvname, pt->sizeuvname, fs->nuv, GCstr *); | ||
1232 | pt->sizeuvname = fs->nuv; | ||
1233 | lua_assert(fs->bl == NULL); | ||
1234 | lj_vmevent_send(L, BC, | ||
1235 | setprotoV(L, L->top++, pt); | ||
1236 | ); | ||
1237 | ls->fs = fs->prev; | ||
1238 | L->top -= 2; /* Remove table and prototype from the stack. */ | ||
1239 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | ||
1240 | keep_token(ls); /* Re-anchor last token. */ | ||
1241 | } | ||
1242 | |||
1243 | GCproto *lj_parse(LexState *ls) | ||
1244 | { | ||
1245 | struct FuncState fs; | ||
1246 | ls->level = 0; | ||
1247 | open_func(ls, &fs); | ||
1248 | fs.pt->flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ | ||
1249 | lj_lex_next(ls); /* Read-ahead first token. */ | ||
1250 | chunk(ls); | ||
1251 | if (ls->token != TK_eof) | ||
1252 | err_token(ls, TK_eof); | ||
1253 | fs.pt->lastlinedefined = ls->linenumber; | ||
1254 | close_func(ls); | ||
1255 | lua_assert(fs.prev == NULL); | ||
1256 | lua_assert(fs.pt->sizeuv == 0); | ||
1257 | lua_assert(ls->fs == NULL); | ||
1258 | return fs.pt; | ||
1259 | } | ||
1260 | |||
1261 | /* -- Expressions --------------------------------------------------------- */ | ||
1262 | |||
1263 | /* forward declaration */ | ||
1264 | static void expr(LexState *ls, ExpDesc *v); | ||
1265 | |||
1266 | static void field(LexState *ls, ExpDesc *v) | ||
1267 | { | ||
1268 | /* field -> ['.' | ':'] NAME */ | ||
1269 | FuncState *fs = ls->fs; | ||
1270 | ExpDesc key; | ||
1271 | exp2anyreg(fs, v); | ||
1272 | lj_lex_next(ls); /* skip the dot or colon */ | ||
1273 | checkname(ls, &key); | ||
1274 | indexexp(fs, v, &key); | ||
1275 | } | ||
1276 | |||
1277 | static void yindex(LexState *ls, ExpDesc *v) | ||
1278 | { | ||
1279 | /* index -> '[' expr ']' */ | ||
1280 | lj_lex_next(ls); /* skip the '[' */ | ||
1281 | expr(ls, v); | ||
1282 | exp2val(ls->fs, v); | ||
1283 | checknext(ls, ']'); | ||
1284 | } | ||
1285 | |||
1286 | static void kexp2tv(TValue *v, ExpDesc *e) | ||
1287 | { | ||
1288 | switch (e->k) { | ||
1289 | case VKNIL: case VKFALSE: case VKTRUE: v->it = ~(int32_t)e->k; break; | ||
1290 | case VKSTR: | ||
1291 | setgcref(v->gcr, obj2gco(e->u.sval)); v->it = LJ_TSTR; break; | ||
1292 | case VKNUM: setnumV(v, expnumV(e)); break; | ||
1293 | default: lua_assert(0); break; | ||
1294 | } | ||
1295 | } | ||
1296 | |||
1297 | static void constructor(LexState *ls, ExpDesc *e) | ||
1298 | { | ||
1299 | FuncState *fs = ls->fs; | ||
1300 | BCLine line = ls->linenumber; | ||
1301 | GCtab *t = NULL; | ||
1302 | int vcall = 0, needarr = 0; | ||
1303 | int32_t narr = 1; /* first array index */ | ||
1304 | uint32_t nhash = 0; /* number of hash entries */ | ||
1305 | BCReg freg = fs->freereg; | ||
1306 | BCPos pc = emitAD(fs, BC_TNEW, freg, 0); | ||
1307 | init_exp(e, VNONRELOC, freg); | ||
1308 | reserveregs(fs, 1); | ||
1309 | freg++; | ||
1310 | checknext(ls, '{'); | ||
1311 | while (ls->token != '}') { | ||
1312 | ExpDesc key, val; | ||
1313 | vcall = 0; | ||
1314 | if (ls->token == '[') { | ||
1315 | yindex(ls, &key); /* already calls exp2val */ | ||
1316 | if (!isK(&key)) indexexp(fs, e, &key); | ||
1317 | if (isnumK(&key) && expnumV(&key) == 0) needarr = 1; else nhash++; | ||
1318 | checknext(ls, '='); | ||
1319 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { | ||
1320 | checkname(ls, &key); | ||
1321 | checknext(ls, '='); | ||
1322 | nhash++; | ||
1323 | } else { | ||
1324 | init_exp(&key, VKNUM, 0); | ||
1325 | setintV(&key.u.nval, narr); | ||
1326 | narr++; | ||
1327 | needarr = vcall = 1; | ||
1328 | } | ||
1329 | expr(ls, &val); | ||
1330 | if (isKexp(&val) && isK(&key) && key.k != VKNIL) { | ||
1331 | TValue k; | ||
1332 | if (!t) { /* create template table on demand */ | ||
1333 | BCReg kidx; | ||
1334 | t = lj_tab_new(fs->L, 0, 0); | ||
1335 | kidx = gcK(fs, obj2gco(t), LJ_TTAB); | ||
1336 | fs->pt->bc[pc] = BCINS_AD(BC_TDUP, freg-1, kidx); | ||
1337 | } | ||
1338 | vcall = 0; | ||
1339 | kexp2tv(&k, &key); | ||
1340 | kexp2tv(lj_tab_set(fs->L, t, &k), &val); | ||
1341 | if (val.k == VKSTR) | ||
1342 | lj_gc_objbarriert(fs->L, t, val.u.sval); | ||
1343 | } else { | ||
1344 | if (isK(&key)) indexexp(fs, e, &key); | ||
1345 | if (val.k != VCALL) vcall = 0; | ||
1346 | storevar(fs, e, &val); | ||
1347 | } | ||
1348 | fs->freereg = freg; | ||
1349 | if (!testnext(ls, ',') && !testnext(ls, ';')) break; | ||
1350 | } | ||
1351 | checkmatch(ls, '}', '{', line); | ||
1352 | if (vcall) { | ||
1353 | BCIns *i = &fs->pt->bc[fs->pc-1]; | ||
1354 | ExpDesc en; | ||
1355 | lua_assert(bc_a(*i)==freg && bc_op(*i) == (narr>256?BC_TSETV:BC_TSETB)); | ||
1356 | init_exp(&en, VKNUM, 0); | ||
1357 | setintV(&en.u.nval, narr-1); | ||
1358 | if (narr > 256) { fs->pc--; i--; } | ||
1359 | *i = BCINS_AD(BC_TSETM, freg, numK(fs, &en)); | ||
1360 | setbc_b(i-1, 0); | ||
1361 | } | ||
1362 | if (pc == fs->pc-1) { /* make expr relocable if possible */ | ||
1363 | e->u.s.info = pc; | ||
1364 | fs->freereg--; | ||
1365 | e->k = VRELOCABLE; | ||
1366 | } else { | ||
1367 | e->k = VNONRELOC; /* indexexp may have changed it */ | ||
1368 | } | ||
1369 | if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */ | ||
1370 | if (!needarr) narr = 0; | ||
1371 | else if (narr < 3) narr = 3; | ||
1372 | else if (narr > 0x7ff) narr = 0x7ff; | ||
1373 | setbc_d(&fs->pt->bc[pc], (uint32_t)narr | (hsize2hbits(nhash) << 11)); | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1377 | static void parlist(LexState *ls) | ||
1378 | { | ||
1379 | /* parlist -> [ param { `,' param } ] */ | ||
1380 | FuncState *fs = ls->fs; | ||
1381 | GCproto *pt = fs->pt; | ||
1382 | BCReg nparams = 0; | ||
1383 | if (ls->token != ')') { /* is `parlist' not empty? */ | ||
1384 | do { | ||
1385 | switch (ls->token) { | ||
1386 | case TK_name: /* param -> NAME */ | ||
1387 | new_localvar(ls, str_checkname(ls), nparams++); | ||
1388 | break; | ||
1389 | case TK_dots: /* param -> `...' */ | ||
1390 | lj_lex_next(ls); | ||
1391 | pt->flags |= PROTO_IS_VARARG; | ||
1392 | break; | ||
1393 | default: | ||
1394 | err_syntax(ls, LJ_ERR_XPARAM); | ||
1395 | break; | ||
1396 | } | ||
1397 | } while (!(pt->flags & PROTO_IS_VARARG) && testnext(ls, ',')); | ||
1398 | } | ||
1399 | adjustlocalvars(ls, nparams); | ||
1400 | pt->numparams = cast_byte(fs->nactvar); | ||
1401 | reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | ||
1402 | } | ||
1403 | |||
1404 | static void body(LexState *ls, ExpDesc *e, int needself, BCLine line) | ||
1405 | { | ||
1406 | /* body -> `(' parlist `)' chunk END */ | ||
1407 | FuncState *fs, new_fs; | ||
1408 | BCReg kidx; | ||
1409 | open_func(ls, &new_fs); | ||
1410 | new_fs.pt->linedefined = line; | ||
1411 | checknext(ls, '('); | ||
1412 | if (needself) { | ||
1413 | new_localvarliteral(ls, "self", 0); | ||
1414 | adjustlocalvars(ls, 1); | ||
1415 | } | ||
1416 | parlist(ls); | ||
1417 | checknext(ls, ')'); | ||
1418 | chunk(ls); | ||
1419 | new_fs.pt->lastlinedefined = ls->linenumber; | ||
1420 | checkmatch(ls, TK_end, TK_function, line); | ||
1421 | close_func(ls); | ||
1422 | fs = ls->fs; | ||
1423 | kidx = gcK(fs, obj2gco(new_fs.pt), LJ_TPROTO); | ||
1424 | init_exp(e, VRELOCABLE, emitAD(fs, BC_FNEW, 0, kidx)); | ||
1425 | if (!(fs->pt->flags & PROTO_HAS_FNEW)) { | ||
1426 | if (fs->pt->flags & PROTO_HAS_RETURN) | ||
1427 | fs->pt->flags |= PROTO_FIXUP_RETURN; | ||
1428 | fs->pt->flags |= PROTO_HAS_FNEW; | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | static BCReg explist1(LexState *ls, ExpDesc *v) | ||
1433 | { | ||
1434 | /* explist1 -> expr { `,' expr } */ | ||
1435 | BCReg n = 1; /* at least one expression */ | ||
1436 | expr(ls, v); | ||
1437 | while (testnext(ls, ',')) { | ||
1438 | exp2nextreg(ls->fs, v); | ||
1439 | expr(ls, v); | ||
1440 | n++; | ||
1441 | } | ||
1442 | return n; | ||
1443 | } | ||
1444 | |||
1445 | static void funcargs(LexState *ls, ExpDesc *e) | ||
1446 | { | ||
1447 | FuncState *fs = ls->fs; | ||
1448 | ExpDesc args; | ||
1449 | BCIns ins; | ||
1450 | BCReg base; | ||
1451 | BCLine line = ls->linenumber; | ||
1452 | switch (ls->token) { | ||
1453 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | ||
1454 | if (line != ls->lastline) | ||
1455 | err_syntax(ls, LJ_ERR_XAMBIG); | ||
1456 | lj_lex_next(ls); | ||
1457 | if (ls->token == ')') { /* arg list is empty? */ | ||
1458 | args.k = VVOID; | ||
1459 | } else { | ||
1460 | explist1(ls, &args); | ||
1461 | if (args.k == VCALL) | ||
1462 | setbc_b(bcptr(fs, &args), 0); | ||
1463 | } | ||
1464 | checkmatch(ls, ')', '(', line); | ||
1465 | break; | ||
1466 | } | ||
1467 | case '{': { /* funcargs -> constructor */ | ||
1468 | constructor(ls, &args); | ||
1469 | break; | ||
1470 | } | ||
1471 | case TK_string: { /* funcargs -> STRING */ | ||
1472 | init_exp(&args, VKSTR, 0); | ||
1473 | args.u.sval = strV(&ls->tokenval); | ||
1474 | lj_lex_next(ls); /* must use `seminfo' before `next' */ | ||
1475 | break; | ||
1476 | } | ||
1477 | default: { | ||
1478 | err_syntax(ls, LJ_ERR_XFUNARG); | ||
1479 | return; | ||
1480 | } | ||
1481 | } | ||
1482 | lua_assert(e->k == VNONRELOC); | ||
1483 | base = e->u.s.info; /* base register for call */ | ||
1484 | if (args.k == VCALL) { | ||
1485 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | ||
1486 | } else { | ||
1487 | if (args.k != VVOID) | ||
1488 | exp2nextreg(fs, &args); /* close last argument */ | ||
1489 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | ||
1490 | } | ||
1491 | init_exp(e, VCALL, emitINS(fs, ins)); | ||
1492 | e->u.s.aux = base; | ||
1493 | fs->pt->lineinfo[fs->pc - 1] = line; | ||
1494 | fs->freereg = base+1; /* call removes function and arguments and leaves | ||
1495 | (unless changed) one result */ | ||
1496 | } | ||
1497 | |||
1498 | static void prefixexp(LexState *ls, ExpDesc *v) | ||
1499 | { | ||
1500 | /* prefixexp -> NAME | '(' expr ')' */ | ||
1501 | switch (ls->token) { | ||
1502 | case '(': { | ||
1503 | BCLine line = ls->linenumber; | ||
1504 | lj_lex_next(ls); | ||
1505 | expr(ls, v); | ||
1506 | checkmatch(ls, ')', '(', line); | ||
1507 | dischargevars(ls->fs, v); | ||
1508 | return; | ||
1509 | } | ||
1510 | case TK_name: { | ||
1511 | singlevar(ls, v); | ||
1512 | return; | ||
1513 | } | ||
1514 | default: { | ||
1515 | err_syntax(ls, LJ_ERR_XSYMBOL); | ||
1516 | return; | ||
1517 | } | ||
1518 | } | ||
1519 | } | ||
1520 | |||
1521 | static void primaryexp(LexState *ls, ExpDesc *v) | ||
1522 | { | ||
1523 | /* primaryexp -> | ||
1524 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | ||
1525 | FuncState *fs = ls->fs; | ||
1526 | prefixexp(ls, v); | ||
1527 | for (;;) { | ||
1528 | switch (ls->token) { | ||
1529 | case '.': /* field */ | ||
1530 | field(ls, v); | ||
1531 | break; | ||
1532 | case '[': { /* `[' exp1 `]' */ | ||
1533 | ExpDesc key; | ||
1534 | exp2anyreg(fs, v); | ||
1535 | yindex(ls, &key); | ||
1536 | indexexp(fs, v, &key); | ||
1537 | break; | ||
1538 | } | ||
1539 | case ':': { /* `:' NAME funcargs */ | ||
1540 | ExpDesc key; | ||
1541 | lj_lex_next(ls); | ||
1542 | checkname(ls, &key); | ||
1543 | methodexp(fs, v, &key); | ||
1544 | funcargs(ls, v); | ||
1545 | break; | ||
1546 | } | ||
1547 | case '(': case TK_string: case '{': /* funcargs */ | ||
1548 | exp2nextreg(fs, v); | ||
1549 | funcargs(ls, v); | ||
1550 | break; | ||
1551 | default: return; | ||
1552 | } | ||
1553 | } | ||
1554 | } | ||
1555 | |||
1556 | static void simpleexp(LexState *ls, ExpDesc *v) | ||
1557 | { | ||
1558 | /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | | ||
1559 | constructor | FUNCTION body | primaryexp */ | ||
1560 | switch (ls->token) { | ||
1561 | case TK_number: | ||
1562 | init_exp(v, VKNUM, 0); | ||
1563 | setnumV(&v->u.nval, numV(&ls->tokenval)); | ||
1564 | break; | ||
1565 | case TK_string: | ||
1566 | init_exp(v, VKSTR, 0); | ||
1567 | v->u.sval = strV(&ls->tokenval); | ||
1568 | break; | ||
1569 | case TK_nil: | ||
1570 | init_exp(v, VKNIL, 0); | ||
1571 | break; | ||
1572 | case TK_true: | ||
1573 | init_exp(v, VKTRUE, 0); | ||
1574 | break; | ||
1575 | case TK_false: | ||
1576 | init_exp(v, VKFALSE, 0); | ||
1577 | break; | ||
1578 | case TK_dots: { /* vararg */ | ||
1579 | FuncState *fs = ls->fs; | ||
1580 | BCReg base; | ||
1581 | checkcond(ls, fs->pt->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); | ||
1582 | reserveregs(fs, 1); | ||
1583 | base = fs->freereg-1; | ||
1584 | init_exp(v, VCALL, emitABC(fs, BC_VARG, base, 2, 1)); | ||
1585 | v->u.s.aux = base; | ||
1586 | break; | ||
1587 | } | ||
1588 | case '{': /* constructor */ | ||
1589 | constructor(ls, v); | ||
1590 | return; | ||
1591 | case TK_function: | ||
1592 | lj_lex_next(ls); | ||
1593 | body(ls, v, 0, ls->linenumber); | ||
1594 | return; | ||
1595 | default: | ||
1596 | primaryexp(ls, v); | ||
1597 | return; | ||
1598 | } | ||
1599 | lj_lex_next(ls); | ||
1600 | } | ||
1601 | |||
1602 | static void enterlevel(LexState *ls) | ||
1603 | { | ||
1604 | if (++ls->level >= LJ_MAX_XLEVEL) | ||
1605 | lj_lex_error(ls, 0, LJ_ERR_XLEVELS); | ||
1606 | } | ||
1607 | |||
1608 | #define leavelevel(ls) ((ls)->level--) | ||
1609 | |||
1610 | static UnOpr getunopr(LexToken tok) | ||
1611 | { | ||
1612 | switch (tok) { | ||
1613 | case TK_not: return OPR_NOT; | ||
1614 | case '-': return OPR_MINUS; | ||
1615 | case '#': return OPR_LEN; | ||
1616 | default: return OPR_NOUNOPR; | ||
1617 | } | ||
1618 | } | ||
1619 | |||
1620 | static BinOpr getbinopr(LexToken tok) | ||
1621 | { | ||
1622 | switch (tok) { | ||
1623 | case '+': return OPR_ADD; | ||
1624 | case '-': return OPR_SUB; | ||
1625 | case '*': return OPR_MUL; | ||
1626 | case '/': return OPR_DIV; | ||
1627 | case '%': return OPR_MOD; | ||
1628 | case '^': return OPR_POW; | ||
1629 | case TK_concat: return OPR_CONCAT; | ||
1630 | case TK_ne: return OPR_NE; | ||
1631 | case TK_eq: return OPR_EQ; | ||
1632 | case '<': return OPR_LT; | ||
1633 | case TK_le: return OPR_LE; | ||
1634 | case '>': return OPR_GT; | ||
1635 | case TK_ge: return OPR_GE; | ||
1636 | case TK_and: return OPR_AND; | ||
1637 | case TK_or: return OPR_OR; | ||
1638 | default: return OPR_NOBINOPR; | ||
1639 | } | ||
1640 | } | ||
1641 | |||
1642 | static const struct { | ||
1643 | uint8_t left; /* left priority for each binary operator */ | ||
1644 | uint8_t right; /* right priority */ | ||
1645 | } priority[] = { /* ORDER OPR */ | ||
1646 | {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ | ||
1647 | {10,9}, {5,4}, /* POW CONCAT (right associative) */ | ||
1648 | {3,3}, {3,3}, /* EQ NE */ | ||
1649 | {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */ | ||
1650 | {2,2}, {1,1} /* AND OR */ | ||
1651 | }; | ||
1652 | |||
1653 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | ||
1654 | |||
1655 | /* | ||
1656 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
1657 | ** where `binop' is any binary operator with a priority higher than `limit' | ||
1658 | */ | ||
1659 | static BinOpr subexpr(LexState *ls, ExpDesc *v, uint32_t limit) | ||
1660 | { | ||
1661 | BinOpr op; | ||
1662 | UnOpr uop; | ||
1663 | enterlevel(ls); | ||
1664 | uop = getunopr(ls->token); | ||
1665 | if (uop != OPR_NOUNOPR) { | ||
1666 | lj_lex_next(ls); | ||
1667 | subexpr(ls, v, UNARY_PRIORITY); | ||
1668 | emit_unop(ls->fs, uop, v); | ||
1669 | } else { | ||
1670 | simpleexp(ls, v); | ||
1671 | } | ||
1672 | /* expand while operators have priorities higher than `limit' */ | ||
1673 | op = getbinopr(ls->token); | ||
1674 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | ||
1675 | ExpDesc v2; | ||
1676 | BinOpr nextop; | ||
1677 | lj_lex_next(ls); | ||
1678 | prepare_binop(ls->fs, op, v); | ||
1679 | /* read sub-expression with higher priority */ | ||
1680 | nextop = subexpr(ls, &v2, priority[op].right); | ||
1681 | emit_binop(ls->fs, op, v, &v2); | ||
1682 | op = nextop; | ||
1683 | } | ||
1684 | leavelevel(ls); | ||
1685 | return op; /* return first untreated operator */ | ||
1686 | } | ||
1687 | |||
1688 | static void expr(LexState *ls, ExpDesc *v) | ||
1689 | { | ||
1690 | subexpr(ls, v, 0); | ||
1691 | } | ||
1692 | |||
1693 | static BCPos condexpr(LexState *ls) | ||
1694 | { | ||
1695 | /* cond -> exp */ | ||
1696 | ExpDesc v; | ||
1697 | expr(ls, &v); /* read condition */ | ||
1698 | if (v.k == VKNIL) v.k = VKFALSE; /* `falses' are all equal here */ | ||
1699 | goiftrue(ls->fs, &v); | ||
1700 | return v.f; | ||
1701 | } | ||
1702 | |||
1703 | /* -- Scope handling ------------------------------------------------------ */ | ||
1704 | |||
1705 | static void enterblock(FuncState *fs, FuncBlock *bl, int isbreakable) | ||
1706 | { | ||
1707 | bl->breaklist = NO_JMP; | ||
1708 | bl->isbreakable = (uint8_t)isbreakable; | ||
1709 | bl->nactvar = fs->nactvar; | ||
1710 | bl->upval = 0; | ||
1711 | bl->previous = fs->bl; | ||
1712 | fs->bl = bl; | ||
1713 | lua_assert(fs->freereg == fs->nactvar); | ||
1714 | } | ||
1715 | |||
1716 | static void leaveblock(FuncState *fs) | ||
1717 | { | ||
1718 | FuncBlock *bl = fs->bl; | ||
1719 | fs->bl = bl->previous; | ||
1720 | removevars(fs->ls, bl->nactvar); | ||
1721 | fs->freereg = fs->nactvar; /* free registers */ | ||
1722 | lua_assert(bl->nactvar == fs->nactvar); | ||
1723 | /* a block either controls scope or breaks (never both) */ | ||
1724 | lua_assert(!bl->isbreakable || !bl->upval); | ||
1725 | if (bl->upval) | ||
1726 | emitAJ(fs, BC_UCLO, bl->nactvar, 0); | ||
1727 | else /* avoid in upval case, it clears lasttarget and kills UCLO+JMP join */ | ||
1728 | patchtohere(fs, bl->breaklist); | ||
1729 | } | ||
1730 | |||
1731 | static void block(LexState *ls) | ||
1732 | { | ||
1733 | /* block -> chunk */ | ||
1734 | FuncState *fs = ls->fs; | ||
1735 | FuncBlock bl; | ||
1736 | enterblock(fs, &bl, 0); | ||
1737 | chunk(ls); | ||
1738 | lua_assert(bl.breaklist == NO_JMP); | ||
1739 | leaveblock(fs); | ||
1740 | } | ||
1741 | |||
1742 | /* -- Statements ---------------------------------------------------------- */ | ||
1743 | |||
1744 | /* | ||
1745 | ** structure to chain all variables in the left-hand side of an | ||
1746 | ** assignment | ||
1747 | */ | ||
1748 | struct LHS_assign { | ||
1749 | ExpDesc v; /* variable (global, local, upvalue, or indexed) */ | ||
1750 | struct LHS_assign *prev; | ||
1751 | }; | ||
1752 | |||
1753 | /* | ||
1754 | ** check whether, in an assignment to a local variable, the local variable | ||
1755 | ** is needed in a previous assignment (to a table). If so, save original | ||
1756 | ** local value in a safe place and use this safe copy in the previous | ||
1757 | ** assignment. | ||
1758 | */ | ||
1759 | static void check_conflict(LexState *ls, struct LHS_assign *lh, | ||
1760 | const ExpDesc *v) | ||
1761 | { | ||
1762 | FuncState *fs = ls->fs; | ||
1763 | BCReg reg = fs->freereg; /* eventual position to save local variable */ | ||
1764 | int conflict = 0; | ||
1765 | for (; lh; lh = lh->prev) { | ||
1766 | if (lh->v.k == VINDEXED) { | ||
1767 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | ||
1768 | conflict = 1; | ||
1769 | lh->v.u.s.info = reg; /* previous assignment will use safe copy */ | ||
1770 | } | ||
1771 | if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | ||
1772 | conflict = 1; | ||
1773 | lh->v.u.s.aux = reg; /* previous assignment will use safe copy */ | ||
1774 | } | ||
1775 | } | ||
1776 | } | ||
1777 | if (conflict) { | ||
1778 | emitAD(fs, BC_MOV, reg, v->u.s.info); /* make copy */ | ||
1779 | reserveregs(fs, 1); | ||
1780 | } | ||
1781 | } | ||
1782 | |||
1783 | static void assignment(LexState *ls, struct LHS_assign *lh, BCReg nvars) | ||
1784 | { | ||
1785 | ExpDesc e; | ||
1786 | checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); | ||
1787 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | ||
1788 | struct LHS_assign nv; | ||
1789 | nv.prev = lh; | ||
1790 | primaryexp(ls, &nv.v); | ||
1791 | if (nv.v.k == VLOCAL) | ||
1792 | check_conflict(ls, lh, &nv.v); | ||
1793 | checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names"); | ||
1794 | assignment(ls, &nv, nvars+1); | ||
1795 | } else { /* assignment -> `=' explist1 */ | ||
1796 | BCReg nexps; | ||
1797 | checknext(ls, '='); | ||
1798 | nexps = explist1(ls, &e); | ||
1799 | if (nexps == nvars) { | ||
1800 | if (e.k == VCALL) { | ||
1801 | if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { | ||
1802 | ls->fs->freereg--; | ||
1803 | e.k = VRELOCABLE; | ||
1804 | } else { | ||
1805 | e.u.s.info = e.u.s.aux; | ||
1806 | e.k = VNONRELOC; | ||
1807 | } | ||
1808 | } | ||
1809 | storevar(ls->fs, &lh->v, &e); | ||
1810 | return; | ||
1811 | } | ||
1812 | adjust_assign(ls, nvars, nexps, &e); | ||
1813 | if (nexps > nvars) | ||
1814 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ | ||
1815 | } | ||
1816 | init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ | ||
1817 | storevar(ls->fs, &lh->v, &e); | ||
1818 | } | ||
1819 | |||
1820 | static void breakstat(LexState *ls) | ||
1821 | { | ||
1822 | FuncState *fs = ls->fs; | ||
1823 | FuncBlock *bl = fs->bl; | ||
1824 | int upval = 0; | ||
1825 | while (bl && !bl->isbreakable) { | ||
1826 | upval |= bl->upval; | ||
1827 | bl = bl->previous; | ||
1828 | } | ||
1829 | if (!bl) | ||
1830 | err_syntax(ls, LJ_ERR_XBREAK); | ||
1831 | if (upval) | ||
1832 | emitAJ(fs, BC_UCLO, bl->nactvar, 0); | ||
1833 | concatjumps(fs, &bl->breaklist, emit_jump(fs)); | ||
1834 | } | ||
1835 | |||
1836 | static void whilestat(LexState *ls, BCLine line) | ||
1837 | { | ||
1838 | /* whilestat -> WHILE cond DO block END */ | ||
1839 | FuncState *fs = ls->fs; | ||
1840 | BCPos start, loop, condexit; | ||
1841 | FuncBlock bl; | ||
1842 | lj_lex_next(ls); /* skip WHILE */ | ||
1843 | start = fs->lasttarget = fs->pc; | ||
1844 | condexit = condexpr(ls); | ||
1845 | enterblock(fs, &bl, 1); | ||
1846 | checknext(ls, TK_do); | ||
1847 | loop = emitAD(fs, BC_LOOP, fs->nactvar, 0); | ||
1848 | block(ls); | ||
1849 | patchlist(fs, emit_jump(fs), start); | ||
1850 | checkmatch(ls, TK_end, TK_while, line); | ||
1851 | leaveblock(fs); | ||
1852 | patchtohere(fs, condexit); /* false conditions finish the loop */ | ||
1853 | fixjump(fs, loop, fs->pc); | ||
1854 | } | ||
1855 | |||
1856 | static void repeatstat(LexState *ls, BCLine line) | ||
1857 | { | ||
1858 | /* repeatstat -> REPEAT block UNTIL cond */ | ||
1859 | FuncState *fs = ls->fs; | ||
1860 | BCPos loop = fs->lasttarget = fs->pc; | ||
1861 | BCPos condexit; | ||
1862 | FuncBlock bl1, bl2; | ||
1863 | enterblock(fs, &bl1, 1); /* loop block */ | ||
1864 | enterblock(fs, &bl2, 0); /* scope block */ | ||
1865 | lj_lex_next(ls); /* skip REPEAT */ | ||
1866 | emitAD(fs, BC_LOOP, fs->nactvar, 0); | ||
1867 | chunk(ls); | ||
1868 | checkmatch(ls, TK_until, TK_repeat, line); | ||
1869 | condexit = condexpr(ls); /* read condition (inside scope block) */ | ||
1870 | if (!bl2.upval) { /* no upvalues? */ | ||
1871 | leaveblock(fs); /* finish scope */ | ||
1872 | } else { /* complete semantics when there are upvalues */ | ||
1873 | breakstat(ls); /* if condition then break */ | ||
1874 | patchtohere(fs, condexit); /* else... */ | ||
1875 | leaveblock(fs); /* finish scope... */ | ||
1876 | condexit = emit_jump(fs); /* and repeat */ | ||
1877 | } | ||
1878 | patchlist(fs, condexit, loop); /* close the loop */ | ||
1879 | fixjump(fs, loop, fs->pc); | ||
1880 | leaveblock(fs); /* finish loop */ | ||
1881 | } | ||
1882 | |||
1883 | static void exp1(LexState *ls) | ||
1884 | { | ||
1885 | ExpDesc e; | ||
1886 | expr(ls, &e); | ||
1887 | exp2nextreg(ls->fs, &e); | ||
1888 | } | ||
1889 | |||
1890 | static void forbody(LexState *ls, BCReg base, BCLine line, BCReg nvars, | ||
1891 | int isnum) | ||
1892 | { | ||
1893 | /* forbody -> DO block */ | ||
1894 | FuncBlock bl; | ||
1895 | FuncState *fs = ls->fs; | ||
1896 | BCPos loop, loopend; | ||
1897 | adjustlocalvars(ls, 3); /* control variables */ | ||
1898 | checknext(ls, TK_do); | ||
1899 | loop = isnum ? emitAJ(fs, BC_FORI, base, NO_JMP) : | ||
1900 | emitAJ(fs, BC_JMP, fs->freereg, NO_JMP); | ||
1901 | enterblock(fs, &bl, 0); /* scope for declared variables */ | ||
1902 | adjustlocalvars(ls, nvars); | ||
1903 | reserveregs(fs, nvars); | ||
1904 | block(ls); | ||
1905 | leaveblock(fs); /* end of scope for declared variables */ | ||
1906 | if (isnum) { | ||
1907 | loopend = emitAJ(fs, BC_FORL, base, NO_JMP); | ||
1908 | fixjump(fs, loop, fs->pc); | ||
1909 | } else { | ||
1910 | fixjump(fs, loop, fs->pc); | ||
1911 | emitABC(fs, BC_ITERC, base+3, nvars+1, 2+1); | ||
1912 | loopend = emitAJ(fs, BC_ITERL, base+3, NO_JMP); | ||
1913 | fs->pt->lineinfo[loopend-1] = line; | ||
1914 | } | ||
1915 | fs->pt->lineinfo[loopend] = line; /* pretend last op starts the loop */ | ||
1916 | fixjump(fs, loopend, loop+1); | ||
1917 | } | ||
1918 | |||
1919 | static void fornum(LexState *ls, GCstr *varname, BCLine line) | ||
1920 | { | ||
1921 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | ||
1922 | FuncState *fs = ls->fs; | ||
1923 | BCReg base = fs->freereg; | ||
1924 | new_localvarliteral(ls, "(for index)", FORL_IDX); | ||
1925 | new_localvarliteral(ls, "(for limit)", FORL_STOP); | ||
1926 | new_localvarliteral(ls, "(for step)", FORL_STEP); | ||
1927 | new_localvar(ls, varname, FORL_EXT); | ||
1928 | checknext(ls, '='); | ||
1929 | exp1(ls); /* initial value */ | ||
1930 | checknext(ls, ','); | ||
1931 | exp1(ls); /* limit */ | ||
1932 | if (testnext(ls, ',')) { | ||
1933 | exp1(ls); /* optional step */ | ||
1934 | } else { /* default step = 1 */ | ||
1935 | emitAD(fs, BC_KSHORT, fs->freereg, 1); | ||
1936 | reserveregs(fs, 1); | ||
1937 | } | ||
1938 | forbody(ls, base, line, 1, 1); | ||
1939 | } | ||
1940 | |||
1941 | static void forlist(LexState *ls, GCstr *indexname) | ||
1942 | { | ||
1943 | /* forlist -> NAME {,NAME} IN explist1 forbody */ | ||
1944 | FuncState *fs = ls->fs; | ||
1945 | ExpDesc e; | ||
1946 | BCReg nvars = 0; | ||
1947 | BCLine line; | ||
1948 | BCReg base = fs->freereg; | ||
1949 | /* create control variables */ | ||
1950 | new_localvarliteral(ls, "(for generator)", nvars++); | ||
1951 | new_localvarliteral(ls, "(for state)", nvars++); | ||
1952 | new_localvarliteral(ls, "(for control)", nvars++); | ||
1953 | /* create declared variables */ | ||
1954 | new_localvar(ls, indexname, nvars++); | ||
1955 | while (testnext(ls, ',')) | ||
1956 | new_localvar(ls, str_checkname(ls), nvars++); | ||
1957 | checknext(ls, TK_in); | ||
1958 | line = ls->linenumber; | ||
1959 | adjust_assign(ls, 3, explist1(ls, &e), &e); | ||
1960 | checkframe(fs, 3); /* extra space to call generator */ | ||
1961 | forbody(ls, base, line, nvars - 3, 0); | ||
1962 | } | ||
1963 | |||
1964 | static void forstat(LexState *ls, BCLine line) | ||
1965 | { | ||
1966 | /* forstat -> FOR (fornum | forlist) END */ | ||
1967 | FuncState *fs = ls->fs; | ||
1968 | GCstr *varname; | ||
1969 | FuncBlock bl; | ||
1970 | enterblock(fs, &bl, 1); /* scope for loop and control variables */ | ||
1971 | lj_lex_next(ls); /* skip `for' */ | ||
1972 | varname = str_checkname(ls); /* first variable name */ | ||
1973 | switch (ls->token) { | ||
1974 | case '=': fornum(ls, varname, line); break; | ||
1975 | case ',': case TK_in: forlist(ls, varname); break; | ||
1976 | default: err_syntax(ls, LJ_ERR_XFOR); | ||
1977 | } | ||
1978 | checkmatch(ls, TK_end, TK_for, line); | ||
1979 | leaveblock(fs); /* loop scope (`break' jumps to this point) */ | ||
1980 | } | ||
1981 | |||
1982 | static BCPos test_then_block(LexState *ls) | ||
1983 | { | ||
1984 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | ||
1985 | BCPos condexit; | ||
1986 | lj_lex_next(ls); /* skip IF or ELSEIF */ | ||
1987 | condexit = condexpr(ls); | ||
1988 | checknext(ls, TK_then); | ||
1989 | block(ls); /* `then' part */ | ||
1990 | return condexit; | ||
1991 | } | ||
1992 | |||
1993 | static void ifstat(LexState *ls, BCLine line) | ||
1994 | { | ||
1995 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ | ||
1996 | FuncState *fs = ls->fs; | ||
1997 | BCPos flist; | ||
1998 | BCPos escapelist = NO_JMP; | ||
1999 | flist = test_then_block(ls); /* IF cond THEN block */ | ||
2000 | while (ls->token == TK_elseif) { | ||
2001 | concatjumps(fs, &escapelist, emit_jump(fs)); | ||
2002 | patchtohere(fs, flist); | ||
2003 | flist = test_then_block(ls); /* ELSEIF cond THEN block */ | ||
2004 | } | ||
2005 | if (ls->token == TK_else) { | ||
2006 | concatjumps(fs, &escapelist, emit_jump(fs)); | ||
2007 | patchtohere(fs, flist); | ||
2008 | lj_lex_next(ls); /* skip ELSE (after patch, for correct line info) */ | ||
2009 | block(ls); /* `else' part */ | ||
2010 | } else { | ||
2011 | concatjumps(fs, &escapelist, flist); | ||
2012 | } | ||
2013 | patchtohere(fs, escapelist); | ||
2014 | checkmatch(ls, TK_end, TK_if, line); | ||
2015 | } | ||
2016 | |||
2017 | static void localfunc(LexState *ls) | ||
2018 | { | ||
2019 | ExpDesc v, b; | ||
2020 | FuncState *fs = ls->fs; | ||
2021 | new_localvar(ls, str_checkname(ls), 0); | ||
2022 | init_exp(&v, VLOCAL, fs->freereg); | ||
2023 | reserveregs(fs, 1); | ||
2024 | adjustlocalvars(ls, 1); | ||
2025 | body(ls, &b, 0, ls->linenumber); | ||
2026 | storevar(fs, &v, &b); | ||
2027 | /* debug information will only see the variable after this point! */ | ||
2028 | getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; | ||
2029 | } | ||
2030 | |||
2031 | static void localstat(LexState *ls) | ||
2032 | { | ||
2033 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | ||
2034 | BCReg nvars = 0; | ||
2035 | BCReg nexps; | ||
2036 | ExpDesc e; | ||
2037 | do { | ||
2038 | new_localvar(ls, str_checkname(ls), nvars++); | ||
2039 | } while (testnext(ls, ',')); | ||
2040 | if (testnext(ls, '=')) { | ||
2041 | nexps = explist1(ls, &e); | ||
2042 | } else { | ||
2043 | e.k = VVOID; | ||
2044 | nexps = 0; | ||
2045 | } | ||
2046 | adjust_assign(ls, nvars, nexps, &e); | ||
2047 | adjustlocalvars(ls, nvars); | ||
2048 | } | ||
2049 | |||
2050 | static int func_name(LexState *ls, ExpDesc *v) | ||
2051 | { | ||
2052 | /* func_name -> NAME {field} [`:' NAME] */ | ||
2053 | int needself = 0; | ||
2054 | singlevar(ls, v); | ||
2055 | while (ls->token == '.') | ||
2056 | field(ls, v); | ||
2057 | if (ls->token == ':') { | ||
2058 | needself = 1; | ||
2059 | field(ls, v); | ||
2060 | } | ||
2061 | return needself; | ||
2062 | } | ||
2063 | |||
2064 | static void funcstat(LexState *ls, BCLine line) | ||
2065 | { | ||
2066 | /* funcstat -> FUNCTION func_name body */ | ||
2067 | FuncState *fs; | ||
2068 | int needself; | ||
2069 | ExpDesc v, b; | ||
2070 | lj_lex_next(ls); /* skip FUNCTION */ | ||
2071 | needself = func_name(ls, &v); | ||
2072 | body(ls, &b, needself, line); | ||
2073 | fs = ls->fs; | ||
2074 | storevar(fs, &v, &b); | ||
2075 | fs->pt->lineinfo[fs->pc - 1] = line; | ||
2076 | } | ||
2077 | |||
2078 | static void exprstat(LexState *ls) | ||
2079 | { | ||
2080 | /* stat -> func | assignment */ | ||
2081 | FuncState *fs = ls->fs; | ||
2082 | struct LHS_assign v; | ||
2083 | primaryexp(ls, &v.v); | ||
2084 | if (v.v.k == VCALL) { /* stat -> func */ | ||
2085 | setbc_b(bcptr(fs, &v.v), 1); /* call statement uses no results */ | ||
2086 | } else { /* stat -> assignment */ | ||
2087 | v.prev = NULL; | ||
2088 | assignment(ls, &v, 1); | ||
2089 | } | ||
2090 | } | ||
2091 | |||
2092 | static int block_follow(LexToken token) | ||
2093 | { | ||
2094 | switch (token) { | ||
2095 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | ||
2096 | return 1; | ||
2097 | default: | ||
2098 | return 0; | ||
2099 | } | ||
2100 | } | ||
2101 | |||
2102 | static void retstat(LexState *ls) | ||
2103 | { | ||
2104 | /* stat -> RETURN explist */ | ||
2105 | BCIns ins; | ||
2106 | FuncState *fs = ls->fs; | ||
2107 | lj_lex_next(ls); /* skip RETURN */ | ||
2108 | fs->pt->flags |= PROTO_HAS_RETURN; | ||
2109 | if (block_follow(ls->token) || ls->token == ';') { | ||
2110 | ins = BCINS_AD(BC_RET0, 0, 1); /* return no values */ | ||
2111 | } else { | ||
2112 | ExpDesc e; | ||
2113 | BCReg nret = explist1(ls, &e); /* optional return values */ | ||
2114 | if (nret == 1) { | ||
2115 | if (e.k == VCALL) { | ||
2116 | BCIns *i = bcptr(fs, &e); | ||
2117 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ | ||
2118 | if (bc_op(*i) == BC_VARG) goto notailcall; | ||
2119 | fs->pc--; | ||
2120 | ins = BCINS_AD(bc_op(*i)-BC_CALL+BC_CALLT, bc_a(*i), bc_c(*i)); | ||
2121 | } else { | ||
2122 | ins = BCINS_AD(BC_RET1, exp2anyreg(fs, &e), 2); | ||
2123 | } | ||
2124 | } else { | ||
2125 | if (e.k == VCALL) { | ||
2126 | notailcall: | ||
2127 | setbc_b(bcptr(fs, &e), 0); | ||
2128 | ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); | ||
2129 | } else { | ||
2130 | exp2nextreg(fs, &e); /* values must go to the `stack' */ | ||
2131 | ins = BCINS_AD(BC_RET, fs->nactvar, nret+1); | ||
2132 | } | ||
2133 | } | ||
2134 | } | ||
2135 | if (fs->pt->flags & PROTO_HAS_FNEW) | ||
2136 | emitAJ(fs, BC_UCLO, 0, 0); | ||
2137 | emitINS(fs, ins); | ||
2138 | } | ||
2139 | |||
2140 | static int statement(LexState *ls) | ||
2141 | { | ||
2142 | BCLine line = ls->linenumber; /* may be needed for error messages */ | ||
2143 | switch (ls->token) { | ||
2144 | case TK_if: | ||
2145 | ifstat(ls, line); | ||
2146 | return 0; | ||
2147 | case TK_while: | ||
2148 | whilestat(ls, line); | ||
2149 | return 0; | ||
2150 | case TK_do: | ||
2151 | lj_lex_next(ls); /* skip DO */ | ||
2152 | block(ls); | ||
2153 | checkmatch(ls, TK_end, TK_do, line); | ||
2154 | return 0; | ||
2155 | case TK_for: | ||
2156 | forstat(ls, line); | ||
2157 | return 0; | ||
2158 | case TK_repeat: | ||
2159 | repeatstat(ls, line); | ||
2160 | return 0; | ||
2161 | case TK_function: | ||
2162 | funcstat(ls, line); | ||
2163 | return 0; | ||
2164 | case TK_local: | ||
2165 | lj_lex_next(ls); /* skip LOCAL */ | ||
2166 | if (testnext(ls, TK_function)) /* local function? */ | ||
2167 | localfunc(ls); | ||
2168 | else | ||
2169 | localstat(ls); | ||
2170 | return 0; | ||
2171 | case TK_return: | ||
2172 | retstat(ls); | ||
2173 | return 1; /* must be last statement */ | ||
2174 | case TK_break: | ||
2175 | lj_lex_next(ls); /* skip BREAK */ | ||
2176 | breakstat(ls); | ||
2177 | return 1; /* must be last statement */ | ||
2178 | default: | ||
2179 | exprstat(ls); | ||
2180 | return 0; | ||
2181 | } | ||
2182 | } | ||
2183 | |||
2184 | static void chunk(LexState *ls) | ||
2185 | { | ||
2186 | /* chunk -> { stat [`;'] } */ | ||
2187 | int islast = 0; | ||
2188 | enterlevel(ls); | ||
2189 | while (!islast && !block_follow(ls->token)) { | ||
2190 | islast = statement(ls); | ||
2191 | testnext(ls, ';'); | ||
2192 | lua_assert(ls->fs->pt->framesize >= ls->fs->freereg && | ||
2193 | ls->fs->freereg >= ls->fs->nactvar); | ||
2194 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | ||
2195 | } | ||
2196 | leavelevel(ls); | ||
2197 | } | ||
2198 | |||