1 | /* |
2 | ** Lua parser (source code -> bytecode). |
3 | ** Copyright (C) 2005-2021 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_debug.h" |
16 | #include "lj_buf.h" |
17 | #include "lj_str.h" |
18 | #include "lj_tab.h" |
19 | #include "lj_func.h" |
20 | #include "lj_state.h" |
21 | #include "lj_bc.h" |
22 | #if LJ_HASFFI |
23 | #include "lj_ctype.h" |
24 | #endif |
25 | #include "lj_strfmt.h" |
26 | #include "lj_lex.h" |
27 | #include "lj_parse.h" |
28 | #include "lj_vm.h" |
29 | #include "lj_vmevent.h" |
30 | |
31 | /* -- Parser structures and definitions ----------------------------------- */ |
32 | |
33 | /* Expression kinds. */ |
34 | typedef enum { |
35 | /* Constant expressions must be first and in this order: */ |
36 | VKNIL, |
37 | VKFALSE, |
38 | VKTRUE, |
39 | VKSTR, /* sval = string value */ |
40 | VKNUM, /* nval = number value */ |
41 | VKLAST = VKNUM, |
42 | VKCDATA, /* nval = cdata value, not treated as a constant expression */ |
43 | /* Non-constant expressions follow: */ |
44 | VLOCAL, /* info = local register, aux = vstack index */ |
45 | VUPVAL, /* info = upvalue index, aux = vstack index */ |
46 | VGLOBAL, /* sval = string value */ |
47 | VINDEXED, /* info = table register, aux = index reg/byte/string const */ |
48 | VJMP, /* info = instruction PC */ |
49 | VRELOCABLE, /* info = instruction PC */ |
50 | VNONRELOC, /* info = result register */ |
51 | VCALL, /* info = instruction PC, aux = base */ |
52 | VVOID |
53 | } ExpKind; |
54 | |
55 | /* Expression descriptor. */ |
56 | typedef struct ExpDesc { |
57 | union { |
58 | struct { |
59 | uint32_t info; /* Primary info. */ |
60 | uint32_t aux; /* Secondary info. */ |
61 | } s; |
62 | TValue nval; /* Number value. */ |
63 | GCstr *sval; /* String value. */ |
64 | } u; |
65 | ExpKind k; |
66 | BCPos t; /* True condition jump list. */ |
67 | BCPos f; /* False condition jump list. */ |
68 | } ExpDesc; |
69 | |
70 | /* Macros for expressions. */ |
71 | #define expr_hasjump(e) ((e)->t != (e)->f) |
72 | |
73 | #define expr_isk(e) ((e)->k <= VKLAST) |
74 | #define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e)) |
75 | #define expr_isnumk(e) ((e)->k == VKNUM) |
76 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) |
77 | #define expr_isstrk(e) ((e)->k == VKSTR) |
78 | |
79 | #define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) |
80 | #define expr_numberV(e) numberVnum(expr_numtv((e))) |
81 | |
82 | /* Initialize expression. */ |
83 | static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) |
84 | { |
85 | e->k = k; |
86 | e->u.s.info = info; |
87 | e->f = e->t = NO_JMP; |
88 | } |
89 | |
90 | /* Check number constant for +-0. */ |
91 | static int expr_numiszero(ExpDesc *e) |
92 | { |
93 | TValue *o = expr_numtv(e); |
94 | return tvisint(o) ? (intV(o) == 0) : tviszero(o); |
95 | } |
96 | |
97 | /* Per-function linked list of scope blocks. */ |
98 | typedef struct FuncScope { |
99 | struct FuncScope *prev; /* Link to outer scope. */ |
100 | MSize vstart; /* Start of block-local variables. */ |
101 | uint8_t nactvar; /* Number of active vars outside the scope. */ |
102 | uint8_t flags; /* Scope flags. */ |
103 | } FuncScope; |
104 | |
105 | #define FSCOPE_LOOP 0x01 /* Scope is a (breakable) loop. */ |
106 | #define FSCOPE_BREAK 0x02 /* Break used in scope. */ |
107 | #define FSCOPE_GOLA 0x04 /* Goto or label used in scope. */ |
108 | #define FSCOPE_UPVAL 0x08 /* Upvalue in scope. */ |
109 | #define FSCOPE_NOCLOSE 0x10 /* Do not close upvalues. */ |
110 | |
111 | #define NAME_BREAK ((GCstr *)(uintptr_t)1) |
112 | |
113 | /* Index into variable stack. */ |
114 | typedef uint16_t VarIndex; |
115 | #define LJ_MAX_VSTACK (65536 - LJ_MAX_UPVAL) |
116 | |
117 | /* Variable/goto/label info. */ |
118 | #define VSTACK_VAR_RW 0x01 /* R/W variable. */ |
119 | #define VSTACK_GOTO 0x02 /* Pending goto. */ |
120 | #define VSTACK_LABEL 0x04 /* Label. */ |
121 | |
122 | /* Per-function state. */ |
123 | typedef struct FuncState { |
124 | GCtab *kt; /* Hash table for constants. */ |
125 | LexState *ls; /* Lexer state. */ |
126 | lua_State *L; /* Lua state. */ |
127 | FuncScope *bl; /* Current scope. */ |
128 | struct FuncState *prev; /* Enclosing function. */ |
129 | BCPos pc; /* Next bytecode position. */ |
130 | BCPos lasttarget; /* Bytecode position of last jump target. */ |
131 | BCPos jpc; /* Pending jump list to next bytecode. */ |
132 | BCReg freereg; /* First free register. */ |
133 | BCReg nactvar; /* Number of active local variables. */ |
134 | BCReg nkn, nkgc; /* Number of lua_Number/GCobj constants */ |
135 | BCLine linedefined; /* First line of the function definition. */ |
136 | BCInsLine *bcbase; /* Base of bytecode stack. */ |
137 | BCPos bclim; /* Limit of bytecode stack. */ |
138 | MSize vbase; /* Base of variable stack for this function. */ |
139 | uint8_t flags; /* Prototype flags. */ |
140 | uint8_t numparams; /* Number of parameters. */ |
141 | uint8_t framesize; /* Fixed frame size. */ |
142 | uint8_t nuv; /* Number of upvalues */ |
143 | VarIndex varmap[LJ_MAX_LOCVAR]; /* Map from register to variable idx. */ |
144 | VarIndex uvmap[LJ_MAX_UPVAL]; /* Map from upvalue to variable idx. */ |
145 | VarIndex uvtmp[LJ_MAX_UPVAL]; /* Temporary upvalue map. */ |
146 | } FuncState; |
147 | |
148 | /* Binary and unary operators. ORDER OPR */ |
149 | typedef enum BinOpr { |
150 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */ |
151 | OPR_CONCAT, |
152 | OPR_NE, OPR_EQ, |
153 | OPR_LT, OPR_GE, OPR_LE, OPR_GT, |
154 | OPR_AND, OPR_OR, |
155 | OPR_NOBINOPR |
156 | } BinOpr; |
157 | |
158 | LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT); |
159 | LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT); |
160 | LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT); |
161 | LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD); |
162 | LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD); |
163 | LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD); |
164 | LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); |
165 | |
166 | #ifdef LUA_USE_ASSERT |
167 | #define lj_assertFS(c, ...) (lj_assertG_(G(fs->L), (c), __VA_ARGS__)) |
168 | #else |
169 | #define lj_assertFS(c, ...) ((void)fs) |
170 | #endif |
171 | |
172 | /* -- Error handling ------------------------------------------------------ */ |
173 | |
174 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) |
175 | { |
176 | lj_lex_error(ls, ls->tok, em); |
177 | } |
178 | |
179 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok) |
180 | { |
181 | lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok)); |
182 | } |
183 | |
184 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) |
185 | { |
186 | if (fs->linedefined == 0) |
187 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what); |
188 | else |
189 | lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what); |
190 | } |
191 | |
192 | #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m) |
193 | #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m) |
194 | #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); } |
195 | |
196 | /* -- Management of constants --------------------------------------------- */ |
197 | |
198 | /* Return bytecode encoding for primitive constant. */ |
199 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) |
200 | |
201 | #define tvhaskslot(o) ((o)->u32.hi == 0) |
202 | #define tvkslot(o) ((o)->u32.lo) |
203 | |
204 | /* Add a number constant. */ |
205 | static BCReg const_num(FuncState *fs, ExpDesc *e) |
206 | { |
207 | lua_State *L = fs->L; |
208 | TValue *o; |
209 | lj_assertFS(expr_isnumk(e), "bad usage" ); |
210 | o = lj_tab_set(L, fs->kt, &e->u.nval); |
211 | if (tvhaskslot(o)) |
212 | return tvkslot(o); |
213 | o->u64 = fs->nkn; |
214 | return fs->nkn++; |
215 | } |
216 | |
217 | /* Add a GC object constant. */ |
218 | static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) |
219 | { |
220 | lua_State *L = fs->L; |
221 | TValue key, *o; |
222 | setgcV(L, &key, gc, itype); |
223 | /* NOBARRIER: the key is new or kept alive. */ |
224 | o = lj_tab_set(L, fs->kt, &key); |
225 | if (tvhaskslot(o)) |
226 | return tvkslot(o); |
227 | o->u64 = fs->nkgc; |
228 | return fs->nkgc++; |
229 | } |
230 | |
231 | /* Add a string constant. */ |
232 | static BCReg const_str(FuncState *fs, ExpDesc *e) |
233 | { |
234 | lj_assertFS(expr_isstrk(e) || e->k == VGLOBAL, "bad usage" ); |
235 | return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR); |
236 | } |
237 | |
238 | /* Anchor string constant to avoid GC. */ |
239 | GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len) |
240 | { |
241 | /* NOBARRIER: the key is new or kept alive. */ |
242 | lua_State *L = ls->L; |
243 | GCstr *s = lj_str_new(L, str, len); |
244 | TValue *tv = lj_tab_setstr(L, ls->fs->kt, s); |
245 | if (tvisnil(tv)) setboolV(tv, 1); |
246 | lj_gc_check(L); |
247 | return s; |
248 | } |
249 | |
250 | #if LJ_HASFFI |
251 | /* Anchor cdata to avoid GC. */ |
252 | void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd) |
253 | { |
254 | /* NOBARRIER: the key is new or kept alive. */ |
255 | lua_State *L = ls->L; |
256 | setcdataV(L, tv, cd); |
257 | setboolV(lj_tab_set(L, ls->fs->kt, tv), 1); |
258 | } |
259 | #endif |
260 | |
261 | /* -- Jump list handling -------------------------------------------------- */ |
262 | |
263 | /* Get next element in jump list. */ |
264 | static BCPos jmp_next(FuncState *fs, BCPos pc) |
265 | { |
266 | ptrdiff_t delta = bc_j(fs->bcbase[pc].ins); |
267 | if ((BCPos)delta == NO_JMP) |
268 | return NO_JMP; |
269 | else |
270 | return (BCPos)(((ptrdiff_t)pc+1)+delta); |
271 | } |
272 | |
273 | /* Check if any of the instructions on the jump list produce no value. */ |
274 | static int jmp_novalue(FuncState *fs, BCPos list) |
275 | { |
276 | for (; list != NO_JMP; list = jmp_next(fs, list)) { |
277 | BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins; |
278 | if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG)) |
279 | return 1; |
280 | } |
281 | return 0; |
282 | } |
283 | |
284 | /* Patch register of test instructions. */ |
285 | static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg) |
286 | { |
287 | BCInsLine *ilp = &fs->bcbase[pc >= 1 ? pc-1 : pc]; |
288 | BCOp op = bc_op(ilp->ins); |
289 | if (op == BC_ISTC || op == BC_ISFC) { |
290 | if (reg != NO_REG && reg != bc_d(ilp->ins)) { |
291 | setbc_a(&ilp->ins, reg); |
292 | } else { /* Nothing to store or already in the right register. */ |
293 | setbc_op(&ilp->ins, op+(BC_IST-BC_ISTC)); |
294 | setbc_a(&ilp->ins, 0); |
295 | } |
296 | } else if (bc_a(ilp->ins) == NO_REG) { |
297 | if (reg == NO_REG) { |
298 | ilp->ins = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0); |
299 | } else { |
300 | setbc_a(&ilp->ins, reg); |
301 | if (reg >= bc_a(ilp[1].ins)) |
302 | setbc_a(&ilp[1].ins, reg+1); |
303 | } |
304 | } else { |
305 | return 0; /* Cannot patch other instructions. */ |
306 | } |
307 | return 1; |
308 | } |
309 | |
310 | /* Drop values for all instructions on jump list. */ |
311 | static void jmp_dropval(FuncState *fs, BCPos list) |
312 | { |
313 | for (; list != NO_JMP; list = jmp_next(fs, list)) |
314 | jmp_patchtestreg(fs, list, NO_REG); |
315 | } |
316 | |
317 | /* Patch jump instruction to target. */ |
318 | static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest) |
319 | { |
320 | BCIns *jmp = &fs->bcbase[pc].ins; |
321 | BCPos offset = dest-(pc+1)+BCBIAS_J; |
322 | lj_assertFS(dest != NO_JMP, "uninitialized jump target" ); |
323 | if (offset > BCMAX_D) |
324 | err_syntax(fs->ls, LJ_ERR_XJUMP); |
325 | setbc_d(jmp, offset); |
326 | } |
327 | |
328 | /* Append to jump list. */ |
329 | static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2) |
330 | { |
331 | if (l2 == NO_JMP) { |
332 | return; |
333 | } else if (*l1 == NO_JMP) { |
334 | *l1 = l2; |
335 | } else { |
336 | BCPos list = *l1; |
337 | BCPos next; |
338 | while ((next = jmp_next(fs, list)) != NO_JMP) /* Find last element. */ |
339 | list = next; |
340 | jmp_patchins(fs, list, l2); |
341 | } |
342 | } |
343 | |
344 | /* Patch jump list and preserve produced values. */ |
345 | static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget, |
346 | BCReg reg, BCPos dtarget) |
347 | { |
348 | while (list != NO_JMP) { |
349 | BCPos next = jmp_next(fs, list); |
350 | if (jmp_patchtestreg(fs, list, reg)) |
351 | jmp_patchins(fs, list, vtarget); /* Jump to target with value. */ |
352 | else |
353 | jmp_patchins(fs, list, dtarget); /* Jump to default target. */ |
354 | list = next; |
355 | } |
356 | } |
357 | |
358 | /* Jump to following instruction. Append to list of pending jumps. */ |
359 | static void jmp_tohere(FuncState *fs, BCPos list) |
360 | { |
361 | fs->lasttarget = fs->pc; |
362 | jmp_append(fs, &fs->jpc, list); |
363 | } |
364 | |
365 | /* Patch jump list to target. */ |
366 | static void jmp_patch(FuncState *fs, BCPos list, BCPos target) |
367 | { |
368 | if (target == fs->pc) { |
369 | jmp_tohere(fs, list); |
370 | } else { |
371 | lj_assertFS(target < fs->pc, "bad jump target" ); |
372 | jmp_patchval(fs, list, target, NO_REG, target); |
373 | } |
374 | } |
375 | |
376 | /* -- Bytecode register allocator ----------------------------------------- */ |
377 | |
378 | /* Bump frame size. */ |
379 | static void bcreg_bump(FuncState *fs, BCReg n) |
380 | { |
381 | BCReg sz = fs->freereg + n; |
382 | if (sz > fs->framesize) { |
383 | if (sz >= LJ_MAX_SLOTS) |
384 | err_syntax(fs->ls, LJ_ERR_XSLOTS); |
385 | fs->framesize = (uint8_t)sz; |
386 | } |
387 | } |
388 | |
389 | /* Reserve registers. */ |
390 | static void bcreg_reserve(FuncState *fs, BCReg n) |
391 | { |
392 | bcreg_bump(fs, n); |
393 | fs->freereg += n; |
394 | } |
395 | |
396 | /* Free register. */ |
397 | static void bcreg_free(FuncState *fs, BCReg reg) |
398 | { |
399 | if (reg >= fs->nactvar) { |
400 | fs->freereg--; |
401 | lj_assertFS(reg == fs->freereg, "bad regfree" ); |
402 | } |
403 | } |
404 | |
405 | /* Free register for expression. */ |
406 | static void expr_free(FuncState *fs, ExpDesc *e) |
407 | { |
408 | if (e->k == VNONRELOC) |
409 | bcreg_free(fs, e->u.s.info); |
410 | } |
411 | |
412 | /* -- Bytecode emitter ---------------------------------------------------- */ |
413 | |
414 | /* Emit bytecode instruction. */ |
415 | static BCPos bcemit_INS(FuncState *fs, BCIns ins) |
416 | { |
417 | BCPos pc = fs->pc; |
418 | LexState *ls = fs->ls; |
419 | jmp_patchval(fs, fs->jpc, pc, NO_REG, pc); |
420 | fs->jpc = NO_JMP; |
421 | if (LJ_UNLIKELY(pc >= fs->bclim)) { |
422 | ptrdiff_t base = fs->bcbase - ls->bcstack; |
423 | checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions" ); |
424 | lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine); |
425 | fs->bclim = (BCPos)(ls->sizebcstack - base); |
426 | fs->bcbase = ls->bcstack + base; |
427 | } |
428 | fs->bcbase[pc].ins = ins; |
429 | fs->bcbase[pc].line = ls->lastline; |
430 | fs->pc = pc+1; |
431 | return pc; |
432 | } |
433 | |
434 | #define bcemit_ABC(fs, o, a, b, c) bcemit_INS(fs, BCINS_ABC(o, a, b, c)) |
435 | #define bcemit_AD(fs, o, a, d) bcemit_INS(fs, BCINS_AD(o, a, d)) |
436 | #define bcemit_AJ(fs, o, a, j) bcemit_INS(fs, BCINS_AJ(o, a, j)) |
437 | |
438 | #define bcptr(fs, e) (&(fs)->bcbase[(e)->u.s.info].ins) |
439 | |
440 | /* -- Bytecode emitter for expressions ------------------------------------ */ |
441 | |
442 | /* Discharge non-constant expression to any register. */ |
443 | static void expr_discharge(FuncState *fs, ExpDesc *e) |
444 | { |
445 | BCIns ins; |
446 | if (e->k == VUPVAL) { |
447 | ins = BCINS_AD(BC_UGET, 0, e->u.s.info); |
448 | } else if (e->k == VGLOBAL) { |
449 | ins = BCINS_AD(BC_GGET, 0, const_str(fs, e)); |
450 | } else if (e->k == VINDEXED) { |
451 | BCReg rc = e->u.s.aux; |
452 | if ((int32_t)rc < 0) { |
453 | ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc); |
454 | } else if (rc > BCMAX_C) { |
455 | ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1)); |
456 | } else { |
457 | bcreg_free(fs, rc); |
458 | ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); |
459 | } |
460 | bcreg_free(fs, e->u.s.info); |
461 | } else if (e->k == VCALL) { |
462 | e->u.s.info = e->u.s.aux; |
463 | e->k = VNONRELOC; |
464 | return; |
465 | } else if (e->k == VLOCAL) { |
466 | e->k = VNONRELOC; |
467 | return; |
468 | } else { |
469 | return; |
470 | } |
471 | e->u.s.info = bcemit_INS(fs, ins); |
472 | e->k = VRELOCABLE; |
473 | } |
474 | |
475 | /* Emit bytecode to set a range of registers to nil. */ |
476 | static void bcemit_nil(FuncState *fs, BCReg from, BCReg n) |
477 | { |
478 | if (fs->pc > fs->lasttarget) { /* No jumps to current position? */ |
479 | BCIns *ip = &fs->bcbase[fs->pc-1].ins; |
480 | BCReg pto, pfrom = bc_a(*ip); |
481 | switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */ |
482 | case BC_KPRI: |
483 | if (bc_d(*ip) != ~LJ_TNIL) break; |
484 | if (from == pfrom) { |
485 | if (n == 1) return; |
486 | } else if (from == pfrom+1) { |
487 | from = pfrom; |
488 | n++; |
489 | } else { |
490 | break; |
491 | } |
492 | *ip = BCINS_AD(BC_KNIL, from, from+n-1); /* Replace KPRI. */ |
493 | return; |
494 | case BC_KNIL: |
495 | pto = bc_d(*ip); |
496 | if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */ |
497 | if (from+n-1 > pto) |
498 | setbc_d(ip, from+n-1); /* Patch previous instruction range. */ |
499 | return; |
500 | } |
501 | break; |
502 | default: |
503 | break; |
504 | } |
505 | } |
506 | /* Emit new instruction or replace old instruction. */ |
507 | bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) : |
508 | BCINS_AD(BC_KNIL, from, from+n-1)); |
509 | } |
510 | |
511 | /* Discharge an expression to a specific register. Ignore branches. */ |
512 | static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) |
513 | { |
514 | BCIns ins; |
515 | expr_discharge(fs, e); |
516 | if (e->k == VKSTR) { |
517 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); |
518 | } else if (e->k == VKNUM) { |
519 | #if LJ_DUALNUM |
520 | cTValue *tv = expr_numtv(e); |
521 | if (tvisint(tv) && checki16(intV(tv))) |
522 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); |
523 | else |
524 | #else |
525 | lua_Number n = expr_numberV(e); |
526 | int32_t k = lj_num2int(n); |
527 | if (checki16(k) && n == (lua_Number)k) |
528 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); |
529 | else |
530 | #endif |
531 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); |
532 | #if LJ_HASFFI |
533 | } else if (e->k == VKCDATA) { |
534 | fs->flags |= PROTO_FFI; |
535 | ins = BCINS_AD(BC_KCDATA, reg, |
536 | const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); |
537 | #endif |
538 | } else if (e->k == VRELOCABLE) { |
539 | setbc_a(bcptr(fs, e), reg); |
540 | goto noins; |
541 | } else if (e->k == VNONRELOC) { |
542 | if (reg == e->u.s.info) |
543 | goto noins; |
544 | ins = BCINS_AD(BC_MOV, reg, e->u.s.info); |
545 | } else if (e->k == VKNIL) { |
546 | bcemit_nil(fs, reg, 1); |
547 | goto noins; |
548 | } else if (e->k <= VKTRUE) { |
549 | ins = BCINS_AD(BC_KPRI, reg, const_pri(e)); |
550 | } else { |
551 | lj_assertFS(e->k == VVOID || e->k == VJMP, "bad expr type %d" , e->k); |
552 | return; |
553 | } |
554 | bcemit_INS(fs, ins); |
555 | noins: |
556 | e->u.s.info = reg; |
557 | e->k = VNONRELOC; |
558 | } |
559 | |
560 | /* Forward declaration. */ |
561 | static BCPos bcemit_jmp(FuncState *fs); |
562 | |
563 | /* Discharge an expression to a specific register. */ |
564 | static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg) |
565 | { |
566 | expr_toreg_nobranch(fs, e, reg); |
567 | if (e->k == VJMP) |
568 | jmp_append(fs, &e->t, e->u.s.info); /* Add it to the true jump list. */ |
569 | if (expr_hasjump(e)) { /* Discharge expression with branches. */ |
570 | BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP; |
571 | if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) { |
572 | BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs); |
573 | jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE); |
574 | bcemit_AJ(fs, BC_JMP, fs->freereg, 1); |
575 | jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE); |
576 | jmp_tohere(fs, jval); |
577 | } |
578 | jend = fs->pc; |
579 | fs->lasttarget = jend; |
580 | jmp_patchval(fs, e->f, jend, reg, jfalse); |
581 | jmp_patchval(fs, e->t, jend, reg, jtrue); |
582 | } |
583 | e->f = e->t = NO_JMP; |
584 | e->u.s.info = reg; |
585 | e->k = VNONRELOC; |
586 | } |
587 | |
588 | /* Discharge an expression to the next free register. */ |
589 | static void expr_tonextreg(FuncState *fs, ExpDesc *e) |
590 | { |
591 | expr_discharge(fs, e); |
592 | expr_free(fs, e); |
593 | bcreg_reserve(fs, 1); |
594 | expr_toreg(fs, e, fs->freereg - 1); |
595 | } |
596 | |
597 | /* Discharge an expression to any register. */ |
598 | static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e) |
599 | { |
600 | expr_discharge(fs, e); |
601 | if (e->k == VNONRELOC) { |
602 | if (!expr_hasjump(e)) return e->u.s.info; /* Already in a register. */ |
603 | if (e->u.s.info >= fs->nactvar) { |
604 | expr_toreg(fs, e, e->u.s.info); /* Discharge to temp. register. */ |
605 | return e->u.s.info; |
606 | } |
607 | } |
608 | expr_tonextreg(fs, e); /* Discharge to next register. */ |
609 | return e->u.s.info; |
610 | } |
611 | |
612 | /* Partially discharge expression to a value. */ |
613 | static void expr_toval(FuncState *fs, ExpDesc *e) |
614 | { |
615 | if (expr_hasjump(e)) |
616 | expr_toanyreg(fs, e); |
617 | else |
618 | expr_discharge(fs, e); |
619 | } |
620 | |
621 | /* Emit store for LHS expression. */ |
622 | static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e) |
623 | { |
624 | BCIns ins; |
625 | if (var->k == VLOCAL) { |
626 | fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; |
627 | expr_free(fs, e); |
628 | expr_toreg(fs, e, var->u.s.info); |
629 | return; |
630 | } else if (var->k == VUPVAL) { |
631 | fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; |
632 | expr_toval(fs, e); |
633 | if (e->k <= VKTRUE) |
634 | ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e)); |
635 | else if (e->k == VKSTR) |
636 | ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e)); |
637 | else if (e->k == VKNUM) |
638 | ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e)); |
639 | else |
640 | ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e)); |
641 | } else if (var->k == VGLOBAL) { |
642 | BCReg ra = expr_toanyreg(fs, e); |
643 | ins = BCINS_AD(BC_GSET, ra, const_str(fs, var)); |
644 | } else { |
645 | BCReg ra, rc; |
646 | lj_assertFS(var->k == VINDEXED, "bad expr type %d" , var->k); |
647 | ra = expr_toanyreg(fs, e); |
648 | rc = var->u.s.aux; |
649 | if ((int32_t)rc < 0) { |
650 | ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc); |
651 | } else if (rc > BCMAX_C) { |
652 | ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1)); |
653 | } else { |
654 | #ifdef LUA_USE_ASSERT |
655 | /* Free late alloced key reg to avoid assert on free of value reg. */ |
656 | /* This can only happen when called from expr_table(). */ |
657 | if (e->k == VNONRELOC && ra >= fs->nactvar && rc >= ra) |
658 | bcreg_free(fs, rc); |
659 | #endif |
660 | ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc); |
661 | } |
662 | } |
663 | bcemit_INS(fs, ins); |
664 | expr_free(fs, e); |
665 | } |
666 | |
667 | /* Emit method lookup expression. */ |
668 | static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) |
669 | { |
670 | BCReg idx, func, obj = expr_toanyreg(fs, e); |
671 | expr_free(fs, e); |
672 | func = fs->freereg; |
673 | bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */ |
674 | lj_assertFS(expr_isstrk(key), "bad usage" ); |
675 | idx = const_str(fs, key); |
676 | if (idx <= BCMAX_C) { |
677 | bcreg_reserve(fs, 2+LJ_FR2); |
678 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
679 | } else { |
680 | bcreg_reserve(fs, 3+LJ_FR2); |
681 | bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx); |
682 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2); |
683 | fs->freereg--; |
684 | } |
685 | e->u.s.info = func; |
686 | e->k = VNONRELOC; |
687 | } |
688 | |
689 | /* -- Bytecode emitter for branches --------------------------------------- */ |
690 | |
691 | /* Emit unconditional branch. */ |
692 | static BCPos bcemit_jmp(FuncState *fs) |
693 | { |
694 | BCPos jpc = fs->jpc; |
695 | BCPos j = fs->pc - 1; |
696 | BCIns *ip = &fs->bcbase[j].ins; |
697 | fs->jpc = NO_JMP; |
698 | if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) { |
699 | setbc_j(ip, NO_JMP); |
700 | fs->lasttarget = j+1; |
701 | } else { |
702 | j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP); |
703 | } |
704 | jmp_append(fs, &j, jpc); |
705 | return j; |
706 | } |
707 | |
708 | /* Invert branch condition of bytecode instruction. */ |
709 | static void invertcond(FuncState *fs, ExpDesc *e) |
710 | { |
711 | BCIns *ip = &fs->bcbase[e->u.s.info - 1].ins; |
712 | setbc_op(ip, bc_op(*ip)^1); |
713 | } |
714 | |
715 | /* Emit conditional branch. */ |
716 | static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond) |
717 | { |
718 | BCPos pc; |
719 | if (e->k == VRELOCABLE) { |
720 | BCIns *ip = bcptr(fs, e); |
721 | if (bc_op(*ip) == BC_NOT) { |
722 | *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip)); |
723 | return bcemit_jmp(fs); |
724 | } |
725 | } |
726 | if (e->k != VNONRELOC) { |
727 | bcreg_reserve(fs, 1); |
728 | expr_toreg_nobranch(fs, e, fs->freereg-1); |
729 | } |
730 | bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info); |
731 | pc = bcemit_jmp(fs); |
732 | expr_free(fs, e); |
733 | return pc; |
734 | } |
735 | |
736 | /* Emit branch on true condition. */ |
737 | static void bcemit_branch_t(FuncState *fs, ExpDesc *e) |
738 | { |
739 | BCPos pc; |
740 | expr_discharge(fs, e); |
741 | if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) |
742 | pc = NO_JMP; /* Never jump. */ |
743 | else if (e->k == VJMP) |
744 | invertcond(fs, e), pc = e->u.s.info; |
745 | else if (e->k == VKFALSE || e->k == VKNIL) |
746 | expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); |
747 | else |
748 | pc = bcemit_branch(fs, e, 0); |
749 | jmp_append(fs, &e->f, pc); |
750 | jmp_tohere(fs, e->t); |
751 | e->t = NO_JMP; |
752 | } |
753 | |
754 | /* Emit branch on false condition. */ |
755 | static void bcemit_branch_f(FuncState *fs, ExpDesc *e) |
756 | { |
757 | BCPos pc; |
758 | expr_discharge(fs, e); |
759 | if (e->k == VKNIL || e->k == VKFALSE) |
760 | pc = NO_JMP; /* Never jump. */ |
761 | else if (e->k == VJMP) |
762 | pc = e->u.s.info; |
763 | else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE) |
764 | expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs); |
765 | else |
766 | pc = bcemit_branch(fs, e, 1); |
767 | jmp_append(fs, &e->t, pc); |
768 | jmp_tohere(fs, e->f); |
769 | e->f = NO_JMP; |
770 | } |
771 | |
772 | /* -- Bytecode emitter for operators -------------------------------------- */ |
773 | |
774 | /* Try constant-folding of arithmetic operators. */ |
775 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
776 | { |
777 | TValue o; |
778 | lua_Number n; |
779 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; |
780 | n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD); |
781 | setnumV(&o, n); |
782 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ |
783 | if (LJ_DUALNUM) { |
784 | int32_t k = lj_num2int(n); |
785 | if ((lua_Number)k == n) { |
786 | setintV(&e1->u.nval, k); |
787 | return 1; |
788 | } |
789 | } |
790 | setnumV(&e1->u.nval, n); |
791 | return 1; |
792 | } |
793 | |
794 | /* Emit arithmetic operator. */ |
795 | static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
796 | { |
797 | BCReg rb, rc, t; |
798 | uint32_t op; |
799 | if (foldarith(opr, e1, e2)) |
800 | return; |
801 | if (opr == OPR_POW) { |
802 | op = BC_POW; |
803 | rc = expr_toanyreg(fs, e2); |
804 | rb = expr_toanyreg(fs, e1); |
805 | } else { |
806 | op = opr-OPR_ADD+BC_ADDVV; |
807 | /* Must discharge 2nd operand first since VINDEXED might free regs. */ |
808 | expr_toval(fs, e2); |
809 | if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C) |
810 | op -= BC_ADDVV-BC_ADDVN; |
811 | else |
812 | rc = expr_toanyreg(fs, e2); |
813 | /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */ |
814 | lj_assertFS(expr_isnumk(e1) || e1->k == VNONRELOC, |
815 | "bad expr type %d" , e1->k); |
816 | expr_toval(fs, e1); |
817 | /* Avoid two consts to satisfy bytecode constraints. */ |
818 | if (expr_isnumk(e1) && !expr_isnumk(e2) && |
819 | (t = const_num(fs, e1)) <= BCMAX_B) { |
820 | rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV; |
821 | } else { |
822 | rb = expr_toanyreg(fs, e1); |
823 | } |
824 | } |
825 | /* Using expr_free might cause asserts if the order is wrong. */ |
826 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; |
827 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; |
828 | e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc); |
829 | e1->k = VRELOCABLE; |
830 | } |
831 | |
832 | /* Emit comparison operator. */ |
833 | static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
834 | { |
835 | ExpDesc *eret = e1; |
836 | BCIns ins; |
837 | expr_toval(fs, e1); |
838 | if (opr == OPR_EQ || opr == OPR_NE) { |
839 | BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV; |
840 | BCReg ra; |
841 | if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */ |
842 | ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */ |
843 | expr_toval(fs, e2); |
844 | switch (e2->k) { |
845 | case VKNIL: case VKFALSE: case VKTRUE: |
846 | ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2)); |
847 | break; |
848 | case VKSTR: |
849 | ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2)); |
850 | break; |
851 | case VKNUM: |
852 | ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2)); |
853 | break; |
854 | default: |
855 | ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2)); |
856 | break; |
857 | } |
858 | } else { |
859 | uint32_t op = opr-OPR_LT+BC_ISLT; |
860 | BCReg ra, rd; |
861 | if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */ |
862 | e1 = e2; e2 = eret; /* Swap operands. */ |
863 | op = ((op-BC_ISLT)^3)+BC_ISLT; |
864 | expr_toval(fs, e1); |
865 | ra = expr_toanyreg(fs, e1); |
866 | rd = expr_toanyreg(fs, e2); |
867 | } else { |
868 | rd = expr_toanyreg(fs, e2); |
869 | ra = expr_toanyreg(fs, e1); |
870 | } |
871 | ins = BCINS_AD(op, ra, rd); |
872 | } |
873 | /* Using expr_free might cause asserts if the order is wrong. */ |
874 | if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--; |
875 | if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--; |
876 | bcemit_INS(fs, ins); |
877 | eret->u.s.info = bcemit_jmp(fs); |
878 | eret->k = VJMP; |
879 | } |
880 | |
881 | /* Fixup left side of binary operator. */ |
882 | static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e) |
883 | { |
884 | if (op == OPR_AND) { |
885 | bcemit_branch_t(fs, e); |
886 | } else if (op == OPR_OR) { |
887 | bcemit_branch_f(fs, e); |
888 | } else if (op == OPR_CONCAT) { |
889 | expr_tonextreg(fs, e); |
890 | } else if (op == OPR_EQ || op == OPR_NE) { |
891 | if (!expr_isk_nojump(e)) expr_toanyreg(fs, e); |
892 | } else { |
893 | if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e); |
894 | } |
895 | } |
896 | |
897 | /* Emit binary operator. */ |
898 | static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) |
899 | { |
900 | if (op <= OPR_POW) { |
901 | bcemit_arith(fs, op, e1, e2); |
902 | } else if (op == OPR_AND) { |
903 | lj_assertFS(e1->t == NO_JMP, "jump list not closed" ); |
904 | expr_discharge(fs, e2); |
905 | jmp_append(fs, &e2->f, e1->f); |
906 | *e1 = *e2; |
907 | } else if (op == OPR_OR) { |
908 | lj_assertFS(e1->f == NO_JMP, "jump list not closed" ); |
909 | expr_discharge(fs, e2); |
910 | jmp_append(fs, &e2->t, e1->t); |
911 | *e1 = *e2; |
912 | } else if (op == OPR_CONCAT) { |
913 | expr_toval(fs, e2); |
914 | if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { |
915 | lj_assertFS(e1->u.s.info == bc_b(*bcptr(fs, e2))-1, |
916 | "bad CAT stack layout" ); |
917 | expr_free(fs, e1); |
918 | setbc_b(bcptr(fs, e2), e1->u.s.info); |
919 | e1->u.s.info = e2->u.s.info; |
920 | } else { |
921 | expr_tonextreg(fs, e2); |
922 | expr_free(fs, e2); |
923 | expr_free(fs, e1); |
924 | e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info); |
925 | } |
926 | e1->k = VRELOCABLE; |
927 | } else { |
928 | lj_assertFS(op == OPR_NE || op == OPR_EQ || |
929 | op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT, |
930 | "bad binop %d" , op); |
931 | bcemit_comp(fs, op, e1, e2); |
932 | } |
933 | } |
934 | |
935 | /* Emit unary operator. */ |
936 | static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) |
937 | { |
938 | if (op == BC_NOT) { |
939 | /* Swap true and false lists. */ |
940 | { BCPos temp = e->f; e->f = e->t; e->t = temp; } |
941 | jmp_dropval(fs, e->f); |
942 | jmp_dropval(fs, e->t); |
943 | expr_discharge(fs, e); |
944 | if (e->k == VKNIL || e->k == VKFALSE) { |
945 | e->k = VKTRUE; |
946 | return; |
947 | } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) { |
948 | e->k = VKFALSE; |
949 | return; |
950 | } else if (e->k == VJMP) { |
951 | invertcond(fs, e); |
952 | return; |
953 | } else if (e->k == VRELOCABLE) { |
954 | bcreg_reserve(fs, 1); |
955 | setbc_a(bcptr(fs, e), fs->freereg-1); |
956 | e->u.s.info = fs->freereg-1; |
957 | e->k = VNONRELOC; |
958 | } else { |
959 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d" , e->k); |
960 | } |
961 | } else { |
962 | lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d" , op); |
963 | if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ |
964 | #if LJ_HASFFI |
965 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ |
966 | GCcdata *cd = cdataV(&e->u.nval); |
967 | int64_t *p = (int64_t *)cdataptr(cd); |
968 | if (cd->ctypeid == CTID_COMPLEX_DOUBLE) |
969 | p[1] ^= (int64_t)U64x(80000000,00000000); |
970 | else |
971 | *p = -*p; |
972 | return; |
973 | } else |
974 | #endif |
975 | if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ |
976 | TValue *o = expr_numtv(e); |
977 | if (tvisint(o)) { |
978 | int32_t k = intV(o); |
979 | if (k == -k) |
980 | setnumV(o, -(lua_Number)k); |
981 | else |
982 | setintV(o, -k); |
983 | return; |
984 | } else { |
985 | o->u64 ^= U64x(80000000,00000000); |
986 | return; |
987 | } |
988 | } |
989 | } |
990 | expr_toanyreg(fs, e); |
991 | } |
992 | expr_free(fs, e); |
993 | e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info); |
994 | e->k = VRELOCABLE; |
995 | } |
996 | |
997 | /* -- Lexer support ------------------------------------------------------- */ |
998 | |
999 | /* Check and consume optional token. */ |
1000 | static int lex_opt(LexState *ls, LexToken tok) |
1001 | { |
1002 | if (ls->tok == tok) { |
1003 | lj_lex_next(ls); |
1004 | return 1; |
1005 | } |
1006 | return 0; |
1007 | } |
1008 | |
1009 | /* Check and consume token. */ |
1010 | static void lex_check(LexState *ls, LexToken tok) |
1011 | { |
1012 | if (ls->tok != tok) |
1013 | err_token(ls, tok); |
1014 | lj_lex_next(ls); |
1015 | } |
1016 | |
1017 | /* Check for matching token. */ |
1018 | static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) |
1019 | { |
1020 | if (!lex_opt(ls, what)) { |
1021 | if (line == ls->linenumber) { |
1022 | err_token(ls, what); |
1023 | } else { |
1024 | const char *swhat = lj_lex_token2str(ls, what); |
1025 | const char *swho = lj_lex_token2str(ls, who); |
1026 | lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line); |
1027 | } |
1028 | } |
1029 | } |
1030 | |
1031 | /* Check for string token. */ |
1032 | static GCstr *lex_str(LexState *ls) |
1033 | { |
1034 | GCstr *s; |
1035 | if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) |
1036 | err_token(ls, TK_name); |
1037 | s = strV(&ls->tokval); |
1038 | lj_lex_next(ls); |
1039 | return s; |
1040 | } |
1041 | |
1042 | /* -- Variable handling --------------------------------------------------- */ |
1043 | |
1044 | #define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]]) |
1045 | |
1046 | /* Define a new local variable. */ |
1047 | static void var_new(LexState *ls, BCReg n, GCstr *name) |
1048 | { |
1049 | FuncState *fs = ls->fs; |
1050 | MSize vtop = ls->vtop; |
1051 | checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables" ); |
1052 | if (LJ_UNLIKELY(vtop >= ls->sizevstack)) { |
1053 | if (ls->sizevstack >= LJ_MAX_VSTACK) |
1054 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); |
1055 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
1056 | } |
1057 | lj_assertFS((uintptr_t)name < VARNAME__MAX || |
1058 | lj_tab_getstr(fs->kt, name) != NULL, |
1059 | "unanchored variable name" ); |
1060 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
1061 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
1062 | fs->varmap[fs->nactvar+n] = (uint16_t)vtop; |
1063 | ls->vtop = vtop+1; |
1064 | } |
1065 | |
1066 | #define var_new_lit(ls, n, v) \ |
1067 | var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1)) |
1068 | |
1069 | #define var_new_fixed(ls, n, vn) \ |
1070 | var_new(ls, (n), (GCstr *)(uintptr_t)(vn)) |
1071 | |
1072 | /* Add local variables. */ |
1073 | static void var_add(LexState *ls, BCReg nvars) |
1074 | { |
1075 | FuncState *fs = ls->fs; |
1076 | BCReg nactvar = fs->nactvar; |
1077 | while (nvars--) { |
1078 | VarInfo *v = &var_get(ls, fs, nactvar); |
1079 | v->startpc = fs->pc; |
1080 | v->slot = nactvar++; |
1081 | v->info = 0; |
1082 | } |
1083 | fs->nactvar = nactvar; |
1084 | } |
1085 | |
1086 | /* Remove local variables. */ |
1087 | static void var_remove(LexState *ls, BCReg tolevel) |
1088 | { |
1089 | FuncState *fs = ls->fs; |
1090 | while (fs->nactvar > tolevel) |
1091 | var_get(ls, fs, --fs->nactvar).endpc = fs->pc; |
1092 | } |
1093 | |
1094 | /* Lookup local variable name. */ |
1095 | static BCReg var_lookup_local(FuncState *fs, GCstr *n) |
1096 | { |
1097 | int i; |
1098 | for (i = fs->nactvar-1; i >= 0; i--) { |
1099 | if (n == strref(var_get(fs->ls, fs, i).name)) |
1100 | return (BCReg)i; |
1101 | } |
1102 | return (BCReg)-1; /* Not found. */ |
1103 | } |
1104 | |
1105 | /* Lookup or add upvalue index. */ |
1106 | static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e) |
1107 | { |
1108 | MSize i, n = fs->nuv; |
1109 | for (i = 0; i < n; i++) |
1110 | if (fs->uvmap[i] == vidx) |
1111 | return i; /* Already exists. */ |
1112 | /* Otherwise create a new one. */ |
1113 | checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues" ); |
1114 | lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d" , e->k); |
1115 | fs->uvmap[n] = (uint16_t)vidx; |
1116 | fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info); |
1117 | fs->nuv = n+1; |
1118 | return n; |
1119 | } |
1120 | |
1121 | /* Forward declaration. */ |
1122 | static void fscope_uvmark(FuncState *fs, BCReg level); |
1123 | |
1124 | /* Recursively lookup variables in enclosing functions. */ |
1125 | static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) |
1126 | { |
1127 | if (fs) { |
1128 | BCReg reg = var_lookup_local(fs, name); |
1129 | if ((int32_t)reg >= 0) { /* Local in this function? */ |
1130 | expr_init(e, VLOCAL, reg); |
1131 | if (!first) |
1132 | fscope_uvmark(fs, reg); /* Scope now has an upvalue. */ |
1133 | return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]); |
1134 | } else { |
1135 | MSize vidx = var_lookup_(fs->prev, name, e, 0); /* Var in outer func? */ |
1136 | if ((int32_t)vidx >= 0) { /* Yes, make it an upvalue here. */ |
1137 | e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e); |
1138 | e->k = VUPVAL; |
1139 | return vidx; |
1140 | } |
1141 | } |
1142 | } else { /* Not found in any function, must be a global. */ |
1143 | expr_init(e, VGLOBAL, 0); |
1144 | e->u.sval = name; |
1145 | } |
1146 | return (MSize)-1; /* Global. */ |
1147 | } |
1148 | |
1149 | /* Lookup variable name. */ |
1150 | #define var_lookup(ls, e) \ |
1151 | var_lookup_((ls)->fs, lex_str(ls), (e), 1) |
1152 | |
1153 | /* -- Goto an label handling ---------------------------------------------- */ |
1154 | |
1155 | /* Add a new goto or label. */ |
1156 | static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc) |
1157 | { |
1158 | FuncState *fs = ls->fs; |
1159 | MSize vtop = ls->vtop; |
1160 | if (LJ_UNLIKELY(vtop >= ls->sizevstack)) { |
1161 | if (ls->sizevstack >= LJ_MAX_VSTACK) |
1162 | lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); |
1163 | lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); |
1164 | } |
1165 | lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL, |
1166 | "unanchored label name" ); |
1167 | /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ |
1168 | setgcref(ls->vstack[vtop].name, obj2gco(name)); |
1169 | ls->vstack[vtop].startpc = pc; |
1170 | ls->vstack[vtop].slot = (uint8_t)fs->nactvar; |
1171 | ls->vstack[vtop].info = info; |
1172 | ls->vtop = vtop+1; |
1173 | return vtop; |
1174 | } |
1175 | |
1176 | #define gola_isgoto(v) ((v)->info & VSTACK_GOTO) |
1177 | #define gola_islabel(v) ((v)->info & VSTACK_LABEL) |
1178 | #define gola_isgotolabel(v) ((v)->info & (VSTACK_GOTO|VSTACK_LABEL)) |
1179 | |
1180 | /* Patch goto to jump to label. */ |
1181 | static void gola_patch(LexState *ls, VarInfo *vg, VarInfo *vl) |
1182 | { |
1183 | FuncState *fs = ls->fs; |
1184 | BCPos pc = vg->startpc; |
1185 | setgcrefnull(vg->name); /* Invalidate pending goto. */ |
1186 | setbc_a(&fs->bcbase[pc].ins, vl->slot); |
1187 | jmp_patch(fs, pc, vl->startpc); |
1188 | } |
1189 | |
1190 | /* Patch goto to close upvalues. */ |
1191 | static void gola_close(LexState *ls, VarInfo *vg) |
1192 | { |
1193 | FuncState *fs = ls->fs; |
1194 | BCPos pc = vg->startpc; |
1195 | BCIns *ip = &fs->bcbase[pc].ins; |
1196 | lj_assertFS(gola_isgoto(vg), "expected goto" ); |
1197 | lj_assertFS(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO, |
1198 | "bad bytecode op %d" , bc_op(*ip)); |
1199 | setbc_a(ip, vg->slot); |
1200 | if (bc_op(*ip) == BC_JMP) { |
1201 | BCPos next = jmp_next(fs, pc); |
1202 | if (next != NO_JMP) jmp_patch(fs, next, pc); /* Jump to UCLO. */ |
1203 | setbc_op(ip, BC_UCLO); /* Turn into UCLO. */ |
1204 | setbc_j(ip, NO_JMP); |
1205 | } |
1206 | } |
1207 | |
1208 | /* Resolve pending forward gotos for label. */ |
1209 | static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx) |
1210 | { |
1211 | VarInfo *vg = ls->vstack + bl->vstart; |
1212 | VarInfo *vl = ls->vstack + idx; |
1213 | for (; vg < vl; vg++) |
1214 | if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) { |
1215 | if (vg->slot < vl->slot) { |
1216 | GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name); |
1217 | lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name" ); |
1218 | ls->linenumber = ls->fs->bcbase[vg->startpc].line; |
1219 | lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break" ); |
1220 | lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, |
1221 | strdata(strref(vg->name)), strdata(name)); |
1222 | } |
1223 | gola_patch(ls, vg, vl); |
1224 | } |
1225 | } |
1226 | |
1227 | /* Fixup remaining gotos and labels for scope. */ |
1228 | static void gola_fixup(LexState *ls, FuncScope *bl) |
1229 | { |
1230 | VarInfo *v = ls->vstack + bl->vstart; |
1231 | VarInfo *ve = ls->vstack + ls->vtop; |
1232 | for (; v < ve; v++) { |
1233 | GCstr *name = strref(v->name); |
1234 | if (name != NULL) { /* Only consider remaining valid gotos/labels. */ |
1235 | if (gola_islabel(v)) { |
1236 | VarInfo *vg; |
1237 | setgcrefnull(v->name); /* Invalidate label that goes out of scope. */ |
1238 | for (vg = v+1; vg < ve; vg++) /* Resolve pending backward gotos. */ |
1239 | if (strref(vg->name) == name && gola_isgoto(vg)) { |
1240 | if ((bl->flags&FSCOPE_UPVAL) && vg->slot > v->slot) |
1241 | gola_close(ls, vg); |
1242 | gola_patch(ls, vg, v); |
1243 | } |
1244 | } else if (gola_isgoto(v)) { |
1245 | if (bl->prev) { /* Propagate goto or break to outer scope. */ |
1246 | bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK : FSCOPE_GOLA; |
1247 | v->slot = bl->nactvar; |
1248 | if ((bl->flags & FSCOPE_UPVAL)) |
1249 | gola_close(ls, v); |
1250 | } else { /* No outer scope: undefined goto label or no loop. */ |
1251 | ls->linenumber = ls->fs->bcbase[v->startpc].line; |
1252 | if (name == NAME_BREAK) |
1253 | lj_lex_error(ls, 0, LJ_ERR_XBREAK); |
1254 | else |
1255 | lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name)); |
1256 | } |
1257 | } |
1258 | } |
1259 | } |
1260 | } |
1261 | |
1262 | /* Find existing label. */ |
1263 | static VarInfo *gola_findlabel(LexState *ls, GCstr *name) |
1264 | { |
1265 | VarInfo *v = ls->vstack + ls->fs->bl->vstart; |
1266 | VarInfo *ve = ls->vstack + ls->vtop; |
1267 | for (; v < ve; v++) |
1268 | if (strref(v->name) == name && gola_islabel(v)) |
1269 | return v; |
1270 | return NULL; |
1271 | } |
1272 | |
1273 | /* -- Scope handling ------------------------------------------------------ */ |
1274 | |
1275 | /* Begin a scope. */ |
1276 | static void fscope_begin(FuncState *fs, FuncScope *bl, int flags) |
1277 | { |
1278 | bl->nactvar = (uint8_t)fs->nactvar; |
1279 | bl->flags = flags; |
1280 | bl->vstart = fs->ls->vtop; |
1281 | bl->prev = fs->bl; |
1282 | fs->bl = bl; |
1283 | lj_assertFS(fs->freereg == fs->nactvar, "bad regalloc" ); |
1284 | } |
1285 | |
1286 | /* End a scope. */ |
1287 | static void fscope_end(FuncState *fs) |
1288 | { |
1289 | FuncScope *bl = fs->bl; |
1290 | LexState *ls = fs->ls; |
1291 | fs->bl = bl->prev; |
1292 | var_remove(ls, bl->nactvar); |
1293 | fs->freereg = fs->nactvar; |
1294 | lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc" ); |
1295 | if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) |
1296 | bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); |
1297 | if ((bl->flags & FSCOPE_BREAK)) { |
1298 | if ((bl->flags & FSCOPE_LOOP)) { |
1299 | MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc); |
1300 | ls->vtop = idx; /* Drop break label immediately. */ |
1301 | gola_resolve(ls, bl, idx); |
1302 | } else { /* Need the fixup step to propagate the breaks. */ |
1303 | gola_fixup(ls, bl); |
1304 | return; |
1305 | } |
1306 | } |
1307 | if ((bl->flags & FSCOPE_GOLA)) { |
1308 | gola_fixup(ls, bl); |
1309 | } |
1310 | } |
1311 | |
1312 | /* Mark scope as having an upvalue. */ |
1313 | static void fscope_uvmark(FuncState *fs, BCReg level) |
1314 | { |
1315 | FuncScope *bl; |
1316 | for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev) |
1317 | ; |
1318 | if (bl) |
1319 | bl->flags |= FSCOPE_UPVAL; |
1320 | } |
1321 | |
1322 | /* -- Function state management ------------------------------------------- */ |
1323 | |
1324 | /* Fixup bytecode for prototype. */ |
1325 | static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n) |
1326 | { |
1327 | BCInsLine *base = fs->bcbase; |
1328 | MSize i; |
1329 | pt->sizebc = n; |
1330 | bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF, |
1331 | fs->framesize, 0); |
1332 | for (i = 1; i < n; i++) |
1333 | bc[i] = base[i].ins; |
1334 | } |
1335 | |
1336 | /* Fixup upvalues for child prototype, step #2. */ |
1337 | static void fs_fixup_uv2(FuncState *fs, GCproto *pt) |
1338 | { |
1339 | VarInfo *vstack = fs->ls->vstack; |
1340 | uint16_t *uv = proto_uv(pt); |
1341 | MSize i, n = pt->sizeuv; |
1342 | for (i = 0; i < n; i++) { |
1343 | VarIndex vidx = uv[i]; |
1344 | if (vidx >= LJ_MAX_VSTACK) |
1345 | uv[i] = vidx - LJ_MAX_VSTACK; |
1346 | else if ((vstack[vidx].info & VSTACK_VAR_RW)) |
1347 | uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL; |
1348 | else |
1349 | uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL | PROTO_UV_IMMUTABLE; |
1350 | } |
1351 | } |
1352 | |
1353 | /* Fixup constants for prototype. */ |
1354 | static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) |
1355 | { |
1356 | GCtab *kt; |
1357 | TValue *array; |
1358 | Node *node; |
1359 | MSize i, hmask; |
1360 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants" ); |
1361 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants" ); |
1362 | setmref(pt->k, kptr); |
1363 | pt->sizekn = fs->nkn; |
1364 | pt->sizekgc = fs->nkgc; |
1365 | kt = fs->kt; |
1366 | array = tvref(kt->array); |
1367 | for (i = 0; i < kt->asize; i++) |
1368 | if (tvhaskslot(&array[i])) { |
1369 | TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])]; |
1370 | if (LJ_DUALNUM) |
1371 | setintV(tv, (int32_t)i); |
1372 | else |
1373 | setnumV(tv, (lua_Number)i); |
1374 | } |
1375 | node = noderef(kt->node); |
1376 | hmask = kt->hmask; |
1377 | for (i = 0; i <= hmask; i++) { |
1378 | Node *n = &node[i]; |
1379 | if (tvhaskslot(&n->val)) { |
1380 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); |
1381 | lj_assertFS(!tvisint(&n->key), "unexpected integer key" ); |
1382 | if (tvisnum(&n->key)) { |
1383 | TValue *tv = &((TValue *)kptr)[kidx]; |
1384 | if (LJ_DUALNUM) { |
1385 | lua_Number nn = numV(&n->key); |
1386 | int32_t k = lj_num2int(nn); |
1387 | lj_assertFS(!tvismzero(&n->key), "unexpected -0 key" ); |
1388 | if ((lua_Number)k == nn) |
1389 | setintV(tv, k); |
1390 | else |
1391 | *tv = n->key; |
1392 | } else { |
1393 | *tv = n->key; |
1394 | } |
1395 | } else { |
1396 | GCobj *o = gcV(&n->key); |
1397 | setgcref(((GCRef *)kptr)[~kidx], o); |
1398 | lj_gc_objbarrier(fs->L, pt, o); |
1399 | if (tvisproto(&n->key)) |
1400 | fs_fixup_uv2(fs, gco2pt(o)); |
1401 | } |
1402 | } |
1403 | } |
1404 | } |
1405 | |
1406 | /* Fixup upvalues for prototype, step #1. */ |
1407 | static void fs_fixup_uv1(FuncState *fs, GCproto *pt, uint16_t *uv) |
1408 | { |
1409 | setmref(pt->uv, uv); |
1410 | pt->sizeuv = fs->nuv; |
1411 | memcpy(uv, fs->uvtmp, fs->nuv*sizeof(VarIndex)); |
1412 | } |
1413 | |
1414 | #ifndef LUAJIT_DISABLE_DEBUGINFO |
1415 | /* Prepare lineinfo for prototype. */ |
1416 | static size_t fs_prep_line(FuncState *fs, BCLine numline) |
1417 | { |
1418 | return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2); |
1419 | } |
1420 | |
1421 | /* Fixup lineinfo for prototype. */ |
1422 | static void fs_fixup_line(FuncState *fs, GCproto *pt, |
1423 | void *lineinfo, BCLine numline) |
1424 | { |
1425 | BCInsLine *base = fs->bcbase + 1; |
1426 | BCLine first = fs->linedefined; |
1427 | MSize i = 0, n = fs->pc-1; |
1428 | pt->firstline = fs->linedefined; |
1429 | pt->numline = numline; |
1430 | setmref(pt->lineinfo, lineinfo); |
1431 | if (LJ_LIKELY(numline < 256)) { |
1432 | uint8_t *li = (uint8_t *)lineinfo; |
1433 | do { |
1434 | BCLine delta = base[i].line - first; |
1435 | lj_assertFS(delta >= 0 && delta < 256, "bad line delta" ); |
1436 | li[i] = (uint8_t)delta; |
1437 | } while (++i < n); |
1438 | } else if (LJ_LIKELY(numline < 65536)) { |
1439 | uint16_t *li = (uint16_t *)lineinfo; |
1440 | do { |
1441 | BCLine delta = base[i].line - first; |
1442 | lj_assertFS(delta >= 0 && delta < 65536, "bad line delta" ); |
1443 | li[i] = (uint16_t)delta; |
1444 | } while (++i < n); |
1445 | } else { |
1446 | uint32_t *li = (uint32_t *)lineinfo; |
1447 | do { |
1448 | BCLine delta = base[i].line - first; |
1449 | lj_assertFS(delta >= 0, "bad line delta" ); |
1450 | li[i] = (uint32_t)delta; |
1451 | } while (++i < n); |
1452 | } |
1453 | } |
1454 | |
1455 | /* Prepare variable info for prototype. */ |
1456 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
1457 | { |
1458 | VarInfo *vs =ls->vstack, *ve; |
1459 | MSize i, n; |
1460 | BCPos lastpc; |
1461 | lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ |
1462 | /* Store upvalue names. */ |
1463 | for (i = 0, n = fs->nuv; i < n; i++) { |
1464 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
1465 | MSize len = s->len+1; |
1466 | char *p = lj_buf_more(&ls->sb, len); |
1467 | p = lj_buf_wmem(p, strdata(s), len); |
1468 | setsbufP(&ls->sb, p); |
1469 | } |
1470 | *ofsvar = sbuflen(&ls->sb); |
1471 | lastpc = 0; |
1472 | /* Store local variable names and compressed ranges. */ |
1473 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
1474 | if (!gola_isgotolabel(vs)) { |
1475 | GCstr *s = strref(vs->name); |
1476 | BCPos startpc; |
1477 | char *p; |
1478 | if ((uintptr_t)s < VARNAME__MAX) { |
1479 | p = lj_buf_more(&ls->sb, 1 + 2*5); |
1480 | *p++ = (char)(uintptr_t)s; |
1481 | } else { |
1482 | MSize len = s->len+1; |
1483 | p = lj_buf_more(&ls->sb, len + 2*5); |
1484 | p = lj_buf_wmem(p, strdata(s), len); |
1485 | } |
1486 | startpc = vs->startpc; |
1487 | p = lj_strfmt_wuleb128(p, startpc-lastpc); |
1488 | p = lj_strfmt_wuleb128(p, vs->endpc-startpc); |
1489 | setsbufP(&ls->sb, p); |
1490 | lastpc = startpc; |
1491 | } |
1492 | } |
1493 | lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ |
1494 | return sbuflen(&ls->sb); |
1495 | } |
1496 | |
1497 | /* Fixup variable info for prototype. */ |
1498 | static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) |
1499 | { |
1500 | setmref(pt->uvinfo, p); |
1501 | setmref(pt->varinfo, (char *)p + ofsvar); |
1502 | memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
1503 | } |
1504 | #else |
1505 | |
1506 | /* Initialize with empty debug info, if disabled. */ |
1507 | #define fs_prep_line(fs, numline) (UNUSED(numline), 0) |
1508 | #define fs_fixup_line(fs, pt, li, numline) \ |
1509 | pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL) |
1510 | #define fs_prep_var(ls, fs, ofsvar) (UNUSED(ofsvar), 0) |
1511 | #define fs_fixup_var(ls, pt, p, ofsvar) \ |
1512 | setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL) |
1513 | |
1514 | #endif |
1515 | |
1516 | /* Check if bytecode op returns. */ |
1517 | static int bcopisret(BCOp op) |
1518 | { |
1519 | switch (op) { |
1520 | case BC_CALLMT: case BC_CALLT: |
1521 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: |
1522 | return 1; |
1523 | default: |
1524 | return 0; |
1525 | } |
1526 | } |
1527 | |
1528 | /* Fixup return instruction for prototype. */ |
1529 | static void fs_fixup_ret(FuncState *fs) |
1530 | { |
1531 | BCPos lastpc = fs->pc; |
1532 | if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { |
1533 | if ((fs->bl->flags & FSCOPE_UPVAL)) |
1534 | bcemit_AJ(fs, BC_UCLO, 0, 0); |
1535 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ |
1536 | } |
1537 | fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */ |
1538 | fscope_end(fs); |
1539 | lj_assertFS(fs->bl == NULL, "bad scope nesting" ); |
1540 | /* May need to fixup returns encoded before first function was created. */ |
1541 | if (fs->flags & PROTO_FIXUP_RETURN) { |
1542 | BCPos pc; |
1543 | for (pc = 1; pc < lastpc; pc++) { |
1544 | BCIns ins = fs->bcbase[pc].ins; |
1545 | BCPos offset; |
1546 | switch (bc_op(ins)) { |
1547 | case BC_CALLMT: case BC_CALLT: |
1548 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: |
1549 | offset = bcemit_INS(fs, ins); /* Copy original instruction. */ |
1550 | fs->bcbase[offset].line = fs->bcbase[pc].line; |
1551 | offset = offset-(pc+1)+BCBIAS_J; |
1552 | if (offset > BCMAX_D) |
1553 | err_syntax(fs->ls, LJ_ERR_XFIXUP); |
1554 | /* Replace with UCLO plus branch. */ |
1555 | fs->bcbase[pc].ins = BCINS_AD(BC_UCLO, 0, offset); |
1556 | break; |
1557 | case BC_UCLO: |
1558 | return; /* We're done. */ |
1559 | default: |
1560 | break; |
1561 | } |
1562 | } |
1563 | } |
1564 | } |
1565 | |
1566 | /* Finish a FuncState and return the new prototype. */ |
1567 | static GCproto *fs_finish(LexState *ls, BCLine line) |
1568 | { |
1569 | lua_State *L = ls->L; |
1570 | FuncState *fs = ls->fs; |
1571 | BCLine numline = line - fs->linedefined; |
1572 | size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar; |
1573 | GCproto *pt; |
1574 | |
1575 | /* Apply final fixups. */ |
1576 | fs_fixup_ret(fs); |
1577 | |
1578 | /* Calculate total size of prototype including all colocated arrays. */ |
1579 | sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); |
1580 | sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1); |
1581 | ofsk = sizept; sizept += fs->nkn*sizeof(TValue); |
1582 | ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2; |
1583 | ofsli = sizept; sizept += fs_prep_line(fs, numline); |
1584 | ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar); |
1585 | |
1586 | /* Allocate prototype and initialize its fields. */ |
1587 | pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); |
1588 | pt->gct = ~LJ_TPROTO; |
1589 | pt->sizept = (MSize)sizept; |
1590 | pt->trace = 0; |
1591 | pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN)); |
1592 | pt->numparams = fs->numparams; |
1593 | pt->framesize = fs->framesize; |
1594 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); |
1595 | |
1596 | /* Close potentially uninitialized gap between bc and kgc. */ |
1597 | *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0; |
1598 | fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc); |
1599 | fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); |
1600 | fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv)); |
1601 | fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); |
1602 | fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); |
1603 | |
1604 | lj_vmevent_send(L, BC, |
1605 | setprotoV(L, L->top++, pt); |
1606 | ); |
1607 | |
1608 | L->top--; /* Pop table of constants. */ |
1609 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
1610 | ls->fs = fs->prev; |
1611 | lj_assertL(ls->fs != NULL || ls->tok == TK_eof, "bad parser state" ); |
1612 | return pt; |
1613 | } |
1614 | |
1615 | /* Initialize a new FuncState. */ |
1616 | static void fs_init(LexState *ls, FuncState *fs) |
1617 | { |
1618 | lua_State *L = ls->L; |
1619 | fs->prev = ls->fs; ls->fs = fs; /* Append to list. */ |
1620 | fs->ls = ls; |
1621 | fs->vbase = ls->vtop; |
1622 | fs->L = L; |
1623 | fs->pc = 0; |
1624 | fs->lasttarget = 0; |
1625 | fs->jpc = NO_JMP; |
1626 | fs->freereg = 0; |
1627 | fs->nkgc = 0; |
1628 | fs->nkn = 0; |
1629 | fs->nactvar = 0; |
1630 | fs->nuv = 0; |
1631 | fs->bl = NULL; |
1632 | fs->flags = 0; |
1633 | fs->framesize = 1; /* Minimum frame size. */ |
1634 | fs->kt = lj_tab_new(L, 0, 0); |
1635 | /* Anchor table of constants in stack to avoid being collected. */ |
1636 | settabV(L, L->top, fs->kt); |
1637 | incr_top(L); |
1638 | } |
1639 | |
1640 | /* -- Expressions --------------------------------------------------------- */ |
1641 | |
1642 | /* Forward declaration. */ |
1643 | static void expr(LexState *ls, ExpDesc *v); |
1644 | |
1645 | /* Return string expression. */ |
1646 | static void expr_str(LexState *ls, ExpDesc *e) |
1647 | { |
1648 | expr_init(e, VKSTR, 0); |
1649 | e->u.sval = lex_str(ls); |
1650 | } |
1651 | |
1652 | /* Return index expression. */ |
1653 | static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) |
1654 | { |
1655 | /* Already called: expr_toval(fs, e). */ |
1656 | t->k = VINDEXED; |
1657 | if (expr_isnumk(e)) { |
1658 | #if LJ_DUALNUM |
1659 | if (tvisint(expr_numtv(e))) { |
1660 | int32_t k = intV(expr_numtv(e)); |
1661 | if (checku8(k)) { |
1662 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ |
1663 | return; |
1664 | } |
1665 | } |
1666 | #else |
1667 | lua_Number n = expr_numberV(e); |
1668 | int32_t k = lj_num2int(n); |
1669 | if (checku8(k) && n == (lua_Number)k) { |
1670 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ |
1671 | return; |
1672 | } |
1673 | #endif |
1674 | } else if (expr_isstrk(e)) { |
1675 | BCReg idx = const_str(fs, e); |
1676 | if (idx <= BCMAX_C) { |
1677 | t->u.s.aux = ~idx; /* -256..-1: const string key */ |
1678 | return; |
1679 | } |
1680 | } |
1681 | t->u.s.aux = expr_toanyreg(fs, e); /* 0..255: register */ |
1682 | } |
1683 | |
1684 | /* Parse index expression with named field. */ |
1685 | static void expr_field(LexState *ls, ExpDesc *v) |
1686 | { |
1687 | FuncState *fs = ls->fs; |
1688 | ExpDesc key; |
1689 | expr_toanyreg(fs, v); |
1690 | lj_lex_next(ls); /* Skip dot or colon. */ |
1691 | expr_str(ls, &key); |
1692 | expr_index(fs, v, &key); |
1693 | } |
1694 | |
1695 | /* Parse index expression with brackets. */ |
1696 | static void expr_bracket(LexState *ls, ExpDesc *v) |
1697 | { |
1698 | lj_lex_next(ls); /* Skip '['. */ |
1699 | expr(ls, v); |
1700 | expr_toval(ls->fs, v); |
1701 | lex_check(ls, ']'); |
1702 | } |
1703 | |
1704 | /* Get value of constant expression. */ |
1705 | static void expr_kvalue(FuncState *fs, TValue *v, ExpDesc *e) |
1706 | { |
1707 | UNUSED(fs); |
1708 | if (e->k <= VKTRUE) { |
1709 | setpriV(v, ~(uint32_t)e->k); |
1710 | } else if (e->k == VKSTR) { |
1711 | setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); |
1712 | } else { |
1713 | lj_assertFS(tvisnumber(expr_numtv(e)), "bad number constant" ); |
1714 | *v = *expr_numtv(e); |
1715 | } |
1716 | } |
1717 | |
1718 | /* Parse table constructor expression. */ |
1719 | static void expr_table(LexState *ls, ExpDesc *e) |
1720 | { |
1721 | FuncState *fs = ls->fs; |
1722 | BCLine line = ls->linenumber; |
1723 | GCtab *t = NULL; |
1724 | int vcall = 0, needarr = 0, fixt = 0; |
1725 | uint32_t narr = 1; /* First array index. */ |
1726 | uint32_t nhash = 0; /* Number of hash entries. */ |
1727 | BCReg freg = fs->freereg; |
1728 | BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0); |
1729 | expr_init(e, VNONRELOC, freg); |
1730 | bcreg_reserve(fs, 1); |
1731 | freg++; |
1732 | lex_check(ls, '{'); |
1733 | while (ls->tok != '}') { |
1734 | ExpDesc key, val; |
1735 | vcall = 0; |
1736 | if (ls->tok == '[') { |
1737 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1738 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1739 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1740 | lex_check(ls, '='); |
1741 | } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && |
1742 | lj_lex_lookahead(ls) == '=') { |
1743 | expr_str(ls, &key); |
1744 | lex_check(ls, '='); |
1745 | nhash++; |
1746 | } else { |
1747 | expr_init(&key, VKNUM, 0); |
1748 | setintV(&key.u.nval, (int)narr); |
1749 | narr++; |
1750 | needarr = vcall = 1; |
1751 | } |
1752 | expr(ls, &val); |
1753 | if (expr_isk(&key) && key.k != VKNIL && |
1754 | (key.k == VKSTR || expr_isk_nojump(&val))) { |
1755 | TValue k, *v; |
1756 | if (!t) { /* Create template table on demand. */ |
1757 | BCReg kidx; |
1758 | t = lj_tab_new(fs->L, needarr ? narr : 0, hsize2hbits(nhash)); |
1759 | kidx = const_gc(fs, obj2gco(t), LJ_TTAB); |
1760 | fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx); |
1761 | } |
1762 | vcall = 0; |
1763 | expr_kvalue(fs, &k, &key); |
1764 | v = lj_tab_set(fs->L, t, &k); |
1765 | lj_gc_anybarriert(fs->L, t); |
1766 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ |
1767 | expr_kvalue(fs, v, &val); |
1768 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ |
1769 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ |
1770 | fixt = 1; /* Fix this later, after all resizes. */ |
1771 | goto nonconst; |
1772 | } |
1773 | } else { |
1774 | nonconst: |
1775 | if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; } |
1776 | if (expr_isk(&key)) expr_index(fs, e, &key); |
1777 | bcemit_store(fs, e, &val); |
1778 | } |
1779 | fs->freereg = freg; |
1780 | if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break; |
1781 | } |
1782 | lex_match(ls, '}', '{', line); |
1783 | if (vcall) { |
1784 | BCInsLine *ilp = &fs->bcbase[fs->pc-1]; |
1785 | ExpDesc en; |
1786 | lj_assertFS(bc_a(ilp->ins) == freg && |
1787 | bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB), |
1788 | "bad CALL code generation" ); |
1789 | expr_init(&en, VKNUM, 0); |
1790 | en.u.nval.u32.lo = narr-1; |
1791 | en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */ |
1792 | if (narr > 256) { fs->pc--; ilp--; } |
1793 | ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en)); |
1794 | setbc_b(&ilp[-1].ins, 0); |
1795 | } |
1796 | if (pc == fs->pc-1) { /* Make expr relocable if possible. */ |
1797 | e->u.s.info = pc; |
1798 | fs->freereg--; |
1799 | e->k = VRELOCABLE; |
1800 | } else { |
1801 | e->k = VNONRELOC; /* May have been changed by expr_index. */ |
1802 | } |
1803 | if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */ |
1804 | BCIns *ip = &fs->bcbase[pc].ins; |
1805 | if (!needarr) narr = 0; |
1806 | else if (narr < 3) narr = 3; |
1807 | else if (narr > 0x7ff) narr = 0x7ff; |
1808 | setbc_d(ip, narr|(hsize2hbits(nhash)<<11)); |
1809 | } else { |
1810 | if (needarr && t->asize < narr) |
1811 | lj_tab_reasize(fs->L, t, narr-1); |
1812 | if (fixt) { /* Fix value for dummy keys in template table. */ |
1813 | Node *node = noderef(t->node); |
1814 | uint32_t i, hmask = t->hmask; |
1815 | for (i = 0; i <= hmask; i++) { |
1816 | Node *n = &node[i]; |
1817 | if (tvistab(&n->val)) { |
1818 | lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table" ); |
1819 | setnilV(&n->val); /* Turn value into nil. */ |
1820 | } |
1821 | } |
1822 | } |
1823 | lj_gc_check(fs->L); |
1824 | } |
1825 | } |
1826 | |
1827 | /* Parse function parameters. */ |
1828 | static BCReg parse_params(LexState *ls, int needself) |
1829 | { |
1830 | FuncState *fs = ls->fs; |
1831 | BCReg nparams = 0; |
1832 | lex_check(ls, '('); |
1833 | if (needself) |
1834 | var_new_lit(ls, nparams++, "self" ); |
1835 | if (ls->tok != ')') { |
1836 | do { |
1837 | if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1838 | var_new(ls, nparams++, lex_str(ls)); |
1839 | } else if (ls->tok == TK_dots) { |
1840 | lj_lex_next(ls); |
1841 | fs->flags |= PROTO_VARARG; |
1842 | break; |
1843 | } else { |
1844 | err_syntax(ls, LJ_ERR_XPARAM); |
1845 | } |
1846 | } while (lex_opt(ls, ',')); |
1847 | } |
1848 | var_add(ls, nparams); |
1849 | lj_assertFS(fs->nactvar == nparams, "bad regalloc" ); |
1850 | bcreg_reserve(fs, nparams); |
1851 | lex_check(ls, ')'); |
1852 | return nparams; |
1853 | } |
1854 | |
1855 | /* Forward declaration. */ |
1856 | static void parse_chunk(LexState *ls); |
1857 | |
1858 | /* Parse body of a function. */ |
1859 | static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) |
1860 | { |
1861 | FuncState fs, *pfs = ls->fs; |
1862 | FuncScope bl; |
1863 | GCproto *pt; |
1864 | ptrdiff_t oldbase = pfs->bcbase - ls->bcstack; |
1865 | fs_init(ls, &fs); |
1866 | fscope_begin(&fs, &bl, 0); |
1867 | fs.linedefined = line; |
1868 | fs.numparams = (uint8_t)parse_params(ls, needself); |
1869 | fs.bcbase = pfs->bcbase + pfs->pc; |
1870 | fs.bclim = pfs->bclim - pfs->pc; |
1871 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ |
1872 | parse_chunk(ls); |
1873 | if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); |
1874 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); |
1875 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
1876 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
1877 | /* Store new prototype in the constant array of the parent. */ |
1878 | expr_init(e, VRELOCABLE, |
1879 | bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); |
1880 | #if LJ_HASFFI |
1881 | pfs->flags |= (fs.flags & PROTO_FFI); |
1882 | #endif |
1883 | if (!(pfs->flags & PROTO_CHILD)) { |
1884 | if (pfs->flags & PROTO_HAS_RETURN) |
1885 | pfs->flags |= PROTO_FIXUP_RETURN; |
1886 | pfs->flags |= PROTO_CHILD; |
1887 | } |
1888 | lj_lex_next(ls); |
1889 | } |
1890 | |
1891 | /* Parse expression list. Last expression is left open. */ |
1892 | static BCReg expr_list(LexState *ls, ExpDesc *v) |
1893 | { |
1894 | BCReg n = 1; |
1895 | expr(ls, v); |
1896 | while (lex_opt(ls, ',')) { |
1897 | expr_tonextreg(ls->fs, v); |
1898 | expr(ls, v); |
1899 | n++; |
1900 | } |
1901 | return n; |
1902 | } |
1903 | |
1904 | /* Parse function argument list. */ |
1905 | static void parse_args(LexState *ls, ExpDesc *e) |
1906 | { |
1907 | FuncState *fs = ls->fs; |
1908 | ExpDesc args; |
1909 | BCIns ins; |
1910 | BCReg base; |
1911 | BCLine line = ls->linenumber; |
1912 | if (ls->tok == '(') { |
1913 | #if !LJ_52 |
1914 | if (line != ls->lastline) |
1915 | err_syntax(ls, LJ_ERR_XAMBIG); |
1916 | #endif |
1917 | lj_lex_next(ls); |
1918 | if (ls->tok == ')') { /* f(). */ |
1919 | args.k = VVOID; |
1920 | } else { |
1921 | expr_list(ls, &args); |
1922 | if (args.k == VCALL) /* f(a, b, g()) or f(a, b, ...). */ |
1923 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
1924 | } |
1925 | lex_match(ls, ')', '(', line); |
1926 | } else if (ls->tok == '{') { |
1927 | expr_table(ls, &args); |
1928 | } else if (ls->tok == TK_string) { |
1929 | expr_init(&args, VKSTR, 0); |
1930 | args.u.sval = strV(&ls->tokval); |
1931 | lj_lex_next(ls); |
1932 | } else { |
1933 | err_syntax(ls, LJ_ERR_XFUNARG); |
1934 | return; /* Silence compiler. */ |
1935 | } |
1936 | lj_assertFS(e->k == VNONRELOC, "bad expr type %d" , e->k); |
1937 | base = e->u.s.info; /* Base register for call. */ |
1938 | if (args.k == VCALL) { |
1939 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); |
1940 | } else { |
1941 | if (args.k != VVOID) |
1942 | expr_tonextreg(fs, &args); |
1943 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); |
1944 | } |
1945 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1946 | e->u.s.aux = base; |
1947 | fs->bcbase[fs->pc - 1].line = line; |
1948 | fs->freereg = base+1; /* Leave one result by default. */ |
1949 | } |
1950 | |
1951 | /* Parse primary expression. */ |
1952 | static void expr_primary(LexState *ls, ExpDesc *v) |
1953 | { |
1954 | FuncState *fs = ls->fs; |
1955 | /* Parse prefix expression. */ |
1956 | if (ls->tok == '(') { |
1957 | BCLine line = ls->linenumber; |
1958 | lj_lex_next(ls); |
1959 | expr(ls, v); |
1960 | lex_match(ls, ')', '(', line); |
1961 | expr_discharge(ls->fs, v); |
1962 | } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1963 | var_lookup(ls, v); |
1964 | } else { |
1965 | err_syntax(ls, LJ_ERR_XSYMBOL); |
1966 | } |
1967 | for (;;) { /* Parse multiple expression suffixes. */ |
1968 | if (ls->tok == '.') { |
1969 | expr_field(ls, v); |
1970 | } else if (ls->tok == '[') { |
1971 | ExpDesc key; |
1972 | expr_toanyreg(fs, v); |
1973 | expr_bracket(ls, &key); |
1974 | expr_index(fs, v, &key); |
1975 | } else if (ls->tok == ':') { |
1976 | ExpDesc key; |
1977 | lj_lex_next(ls); |
1978 | expr_str(ls, &key); |
1979 | bcemit_method(fs, v, &key); |
1980 | parse_args(ls, v); |
1981 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
1982 | expr_tonextreg(fs, v); |
1983 | if (LJ_FR2) bcreg_reserve(fs, 1); |
1984 | parse_args(ls, v); |
1985 | } else { |
1986 | break; |
1987 | } |
1988 | } |
1989 | } |
1990 | |
1991 | /* Parse simple expression. */ |
1992 | static void expr_simple(LexState *ls, ExpDesc *v) |
1993 | { |
1994 | switch (ls->tok) { |
1995 | case TK_number: |
1996 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); |
1997 | copyTV(ls->L, &v->u.nval, &ls->tokval); |
1998 | break; |
1999 | case TK_string: |
2000 | expr_init(v, VKSTR, 0); |
2001 | v->u.sval = strV(&ls->tokval); |
2002 | break; |
2003 | case TK_nil: |
2004 | expr_init(v, VKNIL, 0); |
2005 | break; |
2006 | case TK_true: |
2007 | expr_init(v, VKTRUE, 0); |
2008 | break; |
2009 | case TK_false: |
2010 | expr_init(v, VKFALSE, 0); |
2011 | break; |
2012 | case TK_dots: { /* Vararg. */ |
2013 | FuncState *fs = ls->fs; |
2014 | BCReg base; |
2015 | checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS); |
2016 | bcreg_reserve(fs, 1); |
2017 | base = fs->freereg-1; |
2018 | expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); |
2019 | v->u.s.aux = base; |
2020 | break; |
2021 | } |
2022 | case '{': /* Table constructor. */ |
2023 | expr_table(ls, v); |
2024 | return; |
2025 | case TK_function: |
2026 | lj_lex_next(ls); |
2027 | parse_body(ls, v, 0, ls->linenumber); |
2028 | return; |
2029 | default: |
2030 | expr_primary(ls, v); |
2031 | return; |
2032 | } |
2033 | lj_lex_next(ls); |
2034 | } |
2035 | |
2036 | /* Manage syntactic levels to avoid blowing up the stack. */ |
2037 | static void synlevel_begin(LexState *ls) |
2038 | { |
2039 | if (++ls->level >= LJ_MAX_XLEVEL) |
2040 | lj_lex_error(ls, 0, LJ_ERR_XLEVELS); |
2041 | } |
2042 | |
2043 | #define synlevel_end(ls) ((ls)->level--) |
2044 | |
2045 | /* Convert token to binary operator. */ |
2046 | static BinOpr token2binop(LexToken tok) |
2047 | { |
2048 | switch (tok) { |
2049 | case '+': return OPR_ADD; |
2050 | case '-': return OPR_SUB; |
2051 | case '*': return OPR_MUL; |
2052 | case '/': return OPR_DIV; |
2053 | case '%': return OPR_MOD; |
2054 | case '^': return OPR_POW; |
2055 | case TK_concat: return OPR_CONCAT; |
2056 | case TK_ne: return OPR_NE; |
2057 | case TK_eq: return OPR_EQ; |
2058 | case '<': return OPR_LT; |
2059 | case TK_le: return OPR_LE; |
2060 | case '>': return OPR_GT; |
2061 | case TK_ge: return OPR_GE; |
2062 | case TK_and: return OPR_AND; |
2063 | case TK_or: return OPR_OR; |
2064 | default: return OPR_NOBINOPR; |
2065 | } |
2066 | } |
2067 | |
2068 | /* Priorities for each binary operator. ORDER OPR. */ |
2069 | static const struct { |
2070 | uint8_t left; /* Left priority. */ |
2071 | uint8_t right; /* Right priority. */ |
2072 | } priority[] = { |
2073 | {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ |
2074 | {10,9}, {5,4}, /* POW CONCAT (right associative) */ |
2075 | {3,3}, {3,3}, /* EQ NE */ |
2076 | {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */ |
2077 | {2,2}, {1,1} /* AND OR */ |
2078 | }; |
2079 | |
2080 | #define UNARY_PRIORITY 8 /* Priority for unary operators. */ |
2081 | |
2082 | /* Forward declaration. */ |
2083 | static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); |
2084 | |
2085 | /* Parse unary expression. */ |
2086 | static void expr_unop(LexState *ls, ExpDesc *v) |
2087 | { |
2088 | BCOp op; |
2089 | if (ls->tok == TK_not) { |
2090 | op = BC_NOT; |
2091 | } else if (ls->tok == '-') { |
2092 | op = BC_UNM; |
2093 | } else if (ls->tok == '#') { |
2094 | op = BC_LEN; |
2095 | } else { |
2096 | expr_simple(ls, v); |
2097 | return; |
2098 | } |
2099 | lj_lex_next(ls); |
2100 | expr_binop(ls, v, UNARY_PRIORITY); |
2101 | bcemit_unop(ls->fs, op, v); |
2102 | } |
2103 | |
2104 | /* Parse binary expressions with priority higher than the limit. */ |
2105 | static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) |
2106 | { |
2107 | BinOpr op; |
2108 | synlevel_begin(ls); |
2109 | expr_unop(ls, v); |
2110 | op = token2binop(ls->tok); |
2111 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
2112 | ExpDesc v2; |
2113 | BinOpr nextop; |
2114 | lj_lex_next(ls); |
2115 | bcemit_binop_left(ls->fs, op, v); |
2116 | /* Parse binary expression with higher priority. */ |
2117 | nextop = expr_binop(ls, &v2, priority[op].right); |
2118 | bcemit_binop(ls->fs, op, v, &v2); |
2119 | op = nextop; |
2120 | } |
2121 | synlevel_end(ls); |
2122 | return op; /* Return unconsumed binary operator (if any). */ |
2123 | } |
2124 | |
2125 | /* Parse expression. */ |
2126 | static void expr(LexState *ls, ExpDesc *v) |
2127 | { |
2128 | expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */ |
2129 | } |
2130 | |
2131 | /* Assign expression to the next register. */ |
2132 | static void expr_next(LexState *ls) |
2133 | { |
2134 | ExpDesc e; |
2135 | expr(ls, &e); |
2136 | expr_tonextreg(ls->fs, &e); |
2137 | } |
2138 | |
2139 | /* Parse conditional expression. */ |
2140 | static BCPos expr_cond(LexState *ls) |
2141 | { |
2142 | ExpDesc v; |
2143 | expr(ls, &v); |
2144 | if (v.k == VKNIL) v.k = VKFALSE; |
2145 | bcemit_branch_t(ls->fs, &v); |
2146 | return v.f; |
2147 | } |
2148 | |
2149 | /* -- Assignments --------------------------------------------------------- */ |
2150 | |
2151 | /* List of LHS variables. */ |
2152 | typedef struct LHSVarList { |
2153 | ExpDesc v; /* LHS variable. */ |
2154 | struct LHSVarList *prev; /* Link to previous LHS variable. */ |
2155 | } LHSVarList; |
2156 | |
2157 | /* Eliminate write-after-read hazards for local variable assignment. */ |
2158 | static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v) |
2159 | { |
2160 | FuncState *fs = ls->fs; |
2161 | BCReg reg = v->u.s.info; /* Check against this variable. */ |
2162 | BCReg tmp = fs->freereg; /* Rename to this temp. register (if needed). */ |
2163 | int hazard = 0; |
2164 | for (; lh; lh = lh->prev) { |
2165 | if (lh->v.k == VINDEXED) { |
2166 | if (lh->v.u.s.info == reg) { /* t[i], t = 1, 2 */ |
2167 | hazard = 1; |
2168 | lh->v.u.s.info = tmp; |
2169 | } |
2170 | if (lh->v.u.s.aux == reg) { /* t[i], i = 1, 2 */ |
2171 | hazard = 1; |
2172 | lh->v.u.s.aux = tmp; |
2173 | } |
2174 | } |
2175 | } |
2176 | if (hazard) { |
2177 | bcemit_AD(fs, BC_MOV, tmp, reg); /* Rename conflicting variable. */ |
2178 | bcreg_reserve(fs, 1); |
2179 | } |
2180 | } |
2181 | |
2182 | /* Adjust LHS/RHS of an assignment. */ |
2183 | static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) |
2184 | { |
2185 | FuncState *fs = ls->fs; |
2186 | int32_t = (int32_t)nvars - (int32_t)nexps; |
2187 | if (e->k == VCALL) { |
2188 | extra++; /* Compensate for the VCALL itself. */ |
2189 | if (extra < 0) extra = 0; |
2190 | setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */ |
2191 | if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1); |
2192 | } else { |
2193 | if (e->k != VVOID) |
2194 | expr_tonextreg(fs, e); /* Close last expression. */ |
2195 | if (extra > 0) { /* Leftover LHS are set to nil. */ |
2196 | BCReg reg = fs->freereg; |
2197 | bcreg_reserve(fs, (BCReg)extra); |
2198 | bcemit_nil(fs, reg, (BCReg)extra); |
2199 | } |
2200 | } |
2201 | if (nexps > nvars) |
2202 | ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ |
2203 | } |
2204 | |
2205 | /* Recursively parse assignment statement. */ |
2206 | static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars) |
2207 | { |
2208 | ExpDesc e; |
2209 | checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); |
2210 | if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */ |
2211 | LHSVarList vl; |
2212 | vl.prev = lh; |
2213 | expr_primary(ls, &vl.v); |
2214 | if (vl.v.k == VLOCAL) |
2215 | assign_hazard(ls, lh, &vl.v); |
2216 | checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names" ); |
2217 | parse_assignment(ls, &vl, nvars+1); |
2218 | } else { /* Parse RHS. */ |
2219 | BCReg nexps; |
2220 | lex_check(ls, '='); |
2221 | nexps = expr_list(ls, &e); |
2222 | if (nexps == nvars) { |
2223 | if (e.k == VCALL) { |
2224 | if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { /* Vararg assignment. */ |
2225 | ls->fs->freereg--; |
2226 | e.k = VRELOCABLE; |
2227 | } else { /* Multiple call results. */ |
2228 | e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */ |
2229 | e.k = VNONRELOC; |
2230 | } |
2231 | } |
2232 | bcemit_store(ls->fs, &lh->v, &e); |
2233 | return; |
2234 | } |
2235 | assign_adjust(ls, nvars, nexps, &e); |
2236 | } |
2237 | /* Assign RHS to LHS and recurse downwards. */ |
2238 | expr_init(&e, VNONRELOC, ls->fs->freereg-1); |
2239 | bcemit_store(ls->fs, &lh->v, &e); |
2240 | } |
2241 | |
2242 | /* Parse call statement or assignment. */ |
2243 | static void parse_call_assign(LexState *ls) |
2244 | { |
2245 | FuncState *fs = ls->fs; |
2246 | LHSVarList vl; |
2247 | expr_primary(ls, &vl.v); |
2248 | if (vl.v.k == VCALL) { /* Function call statement. */ |
2249 | setbc_b(bcptr(fs, &vl.v), 1); /* No results. */ |
2250 | } else { /* Start of an assignment. */ |
2251 | vl.prev = NULL; |
2252 | parse_assignment(ls, &vl, 1); |
2253 | } |
2254 | } |
2255 | |
2256 | /* Parse 'local' statement. */ |
2257 | static void parse_local(LexState *ls) |
2258 | { |
2259 | if (lex_opt(ls, TK_function)) { /* Local function declaration. */ |
2260 | ExpDesc v, b; |
2261 | FuncState *fs = ls->fs; |
2262 | var_new(ls, 0, lex_str(ls)); |
2263 | expr_init(&v, VLOCAL, fs->freereg); |
2264 | v.u.s.aux = fs->varmap[fs->freereg]; |
2265 | bcreg_reserve(fs, 1); |
2266 | var_add(ls, 1); |
2267 | parse_body(ls, &b, 0, ls->linenumber); |
2268 | /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */ |
2269 | expr_free(fs, &b); |
2270 | expr_toreg(fs, &b, v.u.s.info); |
2271 | /* The upvalue is in scope, but the local is only valid after the store. */ |
2272 | var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc; |
2273 | } else { /* Local variable declaration. */ |
2274 | ExpDesc e; |
2275 | BCReg nexps, nvars = 0; |
2276 | do { /* Collect LHS. */ |
2277 | var_new(ls, nvars++, lex_str(ls)); |
2278 | } while (lex_opt(ls, ',')); |
2279 | if (lex_opt(ls, '=')) { /* Optional RHS. */ |
2280 | nexps = expr_list(ls, &e); |
2281 | } else { /* Or implicitly set to nil. */ |
2282 | e.k = VVOID; |
2283 | nexps = 0; |
2284 | } |
2285 | assign_adjust(ls, nvars, nexps, &e); |
2286 | var_add(ls, nvars); |
2287 | } |
2288 | } |
2289 | |
2290 | /* Parse 'function' statement. */ |
2291 | static void parse_func(LexState *ls, BCLine line) |
2292 | { |
2293 | FuncState *fs; |
2294 | ExpDesc v, b; |
2295 | int needself = 0; |
2296 | lj_lex_next(ls); /* Skip 'function'. */ |
2297 | /* Parse function name. */ |
2298 | var_lookup(ls, &v); |
2299 | while (ls->tok == '.') /* Multiple dot-separated fields. */ |
2300 | expr_field(ls, &v); |
2301 | if (ls->tok == ':') { /* Optional colon to signify method call. */ |
2302 | needself = 1; |
2303 | expr_field(ls, &v); |
2304 | } |
2305 | parse_body(ls, &b, needself, line); |
2306 | fs = ls->fs; |
2307 | bcemit_store(fs, &v, &b); |
2308 | fs->bcbase[fs->pc - 1].line = line; /* Set line for the store. */ |
2309 | } |
2310 | |
2311 | /* -- Control transfer statements ----------------------------------------- */ |
2312 | |
2313 | /* Check for end of block. */ |
2314 | static int parse_isend(LexToken tok) |
2315 | { |
2316 | switch (tok) { |
2317 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: |
2318 | return 1; |
2319 | default: |
2320 | return 0; |
2321 | } |
2322 | } |
2323 | |
2324 | /* Parse 'return' statement. */ |
2325 | static void parse_return(LexState *ls) |
2326 | { |
2327 | BCIns ins; |
2328 | FuncState *fs = ls->fs; |
2329 | lj_lex_next(ls); /* Skip 'return'. */ |
2330 | fs->flags |= PROTO_HAS_RETURN; |
2331 | if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ |
2332 | ins = BCINS_AD(BC_RET0, 0, 1); |
2333 | } else { /* Return with one or more values. */ |
2334 | ExpDesc e; /* Receives the _last_ expression in the list. */ |
2335 | BCReg nret = expr_list(ls, &e); |
2336 | if (nret == 1) { /* Return one result. */ |
2337 | if (e.k == VCALL) { /* Check for tail call. */ |
2338 | BCIns *ip = bcptr(fs, &e); |
2339 | /* It doesn't pay off to add BC_VARGT just for 'return ...'. */ |
2340 | if (bc_op(*ip) == BC_VARG) goto notailcall; |
2341 | fs->pc--; |
2342 | ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip)); |
2343 | } else { /* Can return the result from any register. */ |
2344 | ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); |
2345 | } |
2346 | } else { |
2347 | if (e.k == VCALL) { /* Append all results from a call. */ |
2348 | notailcall: |
2349 | setbc_b(bcptr(fs, &e), 0); |
2350 | ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); |
2351 | } else { |
2352 | expr_tonextreg(fs, &e); /* Force contiguous registers. */ |
2353 | ins = BCINS_AD(BC_RET, fs->nactvar, nret+1); |
2354 | } |
2355 | } |
2356 | } |
2357 | if (fs->flags & PROTO_CHILD) |
2358 | bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ |
2359 | bcemit_INS(fs, ins); |
2360 | } |
2361 | |
2362 | /* Parse 'break' statement. */ |
2363 | static void parse_break(LexState *ls) |
2364 | { |
2365 | ls->fs->bl->flags |= FSCOPE_BREAK; |
2366 | gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs)); |
2367 | } |
2368 | |
2369 | /* Parse 'goto' statement. */ |
2370 | static void parse_goto(LexState *ls) |
2371 | { |
2372 | FuncState *fs = ls->fs; |
2373 | GCstr *name = lex_str(ls); |
2374 | VarInfo *vl = gola_findlabel(ls, name); |
2375 | if (vl) /* Treat backwards goto within same scope like a loop. */ |
2376 | bcemit_AJ(fs, BC_LOOP, vl->slot, -1); /* No BC range check. */ |
2377 | fs->bl->flags |= FSCOPE_GOLA; |
2378 | gola_new(ls, name, VSTACK_GOTO, bcemit_jmp(fs)); |
2379 | } |
2380 | |
2381 | /* Parse label. */ |
2382 | static void parse_label(LexState *ls) |
2383 | { |
2384 | FuncState *fs = ls->fs; |
2385 | GCstr *name; |
2386 | MSize idx; |
2387 | fs->lasttarget = fs->pc; |
2388 | fs->bl->flags |= FSCOPE_GOLA; |
2389 | lj_lex_next(ls); /* Skip '::'. */ |
2390 | name = lex_str(ls); |
2391 | if (gola_findlabel(ls, name)) |
2392 | lj_lex_error(ls, 0, LJ_ERR_XLDUP, strdata(name)); |
2393 | idx = gola_new(ls, name, VSTACK_LABEL, fs->pc); |
2394 | lex_check(ls, TK_label); |
2395 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ |
2396 | for (;;) { |
2397 | if (ls->tok == TK_label) { |
2398 | synlevel_begin(ls); |
2399 | parse_label(ls); |
2400 | synlevel_end(ls); |
2401 | } else if (LJ_52 && ls->tok == ';') { |
2402 | lj_lex_next(ls); |
2403 | } else { |
2404 | break; |
2405 | } |
2406 | } |
2407 | /* Trailing label is considered to be outside of scope. */ |
2408 | if (parse_isend(ls->tok) && ls->tok != TK_until) |
2409 | ls->vstack[idx].slot = fs->bl->nactvar; |
2410 | gola_resolve(ls, fs->bl, idx); |
2411 | } |
2412 | |
2413 | /* -- Blocks, loops and conditional statements ---------------------------- */ |
2414 | |
2415 | /* Parse a block. */ |
2416 | static void parse_block(LexState *ls) |
2417 | { |
2418 | FuncState *fs = ls->fs; |
2419 | FuncScope bl; |
2420 | fscope_begin(fs, &bl, 0); |
2421 | parse_chunk(ls); |
2422 | fscope_end(fs); |
2423 | } |
2424 | |
2425 | /* Parse 'while' statement. */ |
2426 | static void parse_while(LexState *ls, BCLine line) |
2427 | { |
2428 | FuncState *fs = ls->fs; |
2429 | BCPos start, loop, condexit; |
2430 | FuncScope bl; |
2431 | lj_lex_next(ls); /* Skip 'while'. */ |
2432 | start = fs->lasttarget = fs->pc; |
2433 | condexit = expr_cond(ls); |
2434 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
2435 | lex_check(ls, TK_do); |
2436 | loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); |
2437 | parse_block(ls); |
2438 | jmp_patch(fs, bcemit_jmp(fs), start); |
2439 | lex_match(ls, TK_end, TK_while, line); |
2440 | fscope_end(fs); |
2441 | jmp_tohere(fs, condexit); |
2442 | jmp_patchins(fs, loop, fs->pc); |
2443 | } |
2444 | |
2445 | /* Parse 'repeat' statement. */ |
2446 | static void parse_repeat(LexState *ls, BCLine line) |
2447 | { |
2448 | FuncState *fs = ls->fs; |
2449 | BCPos loop = fs->lasttarget = fs->pc; |
2450 | BCPos condexit; |
2451 | FuncScope bl1, bl2; |
2452 | fscope_begin(fs, &bl1, FSCOPE_LOOP); /* Breakable loop scope. */ |
2453 | fscope_begin(fs, &bl2, 0); /* Inner scope. */ |
2454 | lj_lex_next(ls); /* Skip 'repeat'. */ |
2455 | bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); |
2456 | parse_chunk(ls); |
2457 | lex_match(ls, TK_until, TK_repeat, line); |
2458 | condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */ |
2459 | if (!(bl2.flags & FSCOPE_UPVAL)) { /* No upvalues? Just end inner scope. */ |
2460 | fscope_end(fs); |
2461 | } else { /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */ |
2462 | parse_break(ls); /* Break from loop and close upvalues. */ |
2463 | jmp_tohere(fs, condexit); |
2464 | fscope_end(fs); /* End inner scope and close upvalues. */ |
2465 | condexit = bcemit_jmp(fs); |
2466 | } |
2467 | jmp_patch(fs, condexit, loop); /* Jump backwards if !cond. */ |
2468 | jmp_patchins(fs, loop, fs->pc); |
2469 | fscope_end(fs); /* End loop scope. */ |
2470 | } |
2471 | |
2472 | /* Parse numeric 'for'. */ |
2473 | static void parse_for_num(LexState *ls, GCstr *varname, BCLine line) |
2474 | { |
2475 | FuncState *fs = ls->fs; |
2476 | BCReg base = fs->freereg; |
2477 | FuncScope bl; |
2478 | BCPos loop, loopend; |
2479 | /* Hidden control variables. */ |
2480 | var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX); |
2481 | var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP); |
2482 | var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP); |
2483 | /* Visible copy of index variable. */ |
2484 | var_new(ls, FORL_EXT, varname); |
2485 | lex_check(ls, '='); |
2486 | expr_next(ls); |
2487 | lex_check(ls, ','); |
2488 | expr_next(ls); |
2489 | if (lex_opt(ls, ',')) { |
2490 | expr_next(ls); |
2491 | } else { |
2492 | bcemit_AD(fs, BC_KSHORT, fs->freereg, 1); /* Default step is 1. */ |
2493 | bcreg_reserve(fs, 1); |
2494 | } |
2495 | var_add(ls, 3); /* Hidden control variables. */ |
2496 | lex_check(ls, TK_do); |
2497 | loop = bcemit_AJ(fs, BC_FORI, base, NO_JMP); |
2498 | fscope_begin(fs, &bl, 0); /* Scope for visible variables. */ |
2499 | var_add(ls, 1); |
2500 | bcreg_reserve(fs, 1); |
2501 | parse_block(ls); |
2502 | fscope_end(fs); |
2503 | /* Perform loop inversion. Loop control instructions are at the end. */ |
2504 | loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP); |
2505 | fs->bcbase[loopend].line = line; /* Fix line for control ins. */ |
2506 | jmp_patchins(fs, loopend, loop+1); |
2507 | jmp_patchins(fs, loop, fs->pc); |
2508 | } |
2509 | |
2510 | /* Try to predict whether the iterator is next() and specialize the bytecode. |
2511 | ** Detecting next() and pairs() by name is simplistic, but quite effective. |
2512 | ** The interpreter backs off if the check for the closure fails at runtime. |
2513 | */ |
2514 | static int predict_next(LexState *ls, FuncState *fs, BCPos pc) |
2515 | { |
2516 | BCIns ins = fs->bcbase[pc].ins; |
2517 | GCstr *name; |
2518 | cTValue *o; |
2519 | switch (bc_op(ins)) { |
2520 | case BC_MOV: |
2521 | name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name)); |
2522 | break; |
2523 | case BC_UGET: |
2524 | name = gco2str(gcref(ls->vstack[fs->uvmap[bc_d(ins)]].name)); |
2525 | break; |
2526 | case BC_GGET: |
2527 | /* There's no inverse index (yet), so lookup the strings. */ |
2528 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs" )); |
2529 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2530 | return 1; |
2531 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next" )); |
2532 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2533 | return 1; |
2534 | return 0; |
2535 | default: |
2536 | return 0; |
2537 | } |
2538 | return (name->len == 5 && !strcmp(strdata(name), "pairs" )) || |
2539 | (name->len == 4 && !strcmp(strdata(name), "next" )); |
2540 | } |
2541 | |
2542 | /* Parse 'for' iterator. */ |
2543 | static void parse_for_iter(LexState *ls, GCstr *indexname) |
2544 | { |
2545 | FuncState *fs = ls->fs; |
2546 | ExpDesc e; |
2547 | BCReg nvars = 0; |
2548 | BCLine line; |
2549 | BCReg base = fs->freereg + 3; |
2550 | BCPos loop, loopend, exprpc = fs->pc; |
2551 | FuncScope bl; |
2552 | int isnext; |
2553 | /* Hidden control variables. */ |
2554 | var_new_fixed(ls, nvars++, VARNAME_FOR_GEN); |
2555 | var_new_fixed(ls, nvars++, VARNAME_FOR_STATE); |
2556 | var_new_fixed(ls, nvars++, VARNAME_FOR_CTL); |
2557 | /* Visible variables returned from iterator. */ |
2558 | var_new(ls, nvars++, indexname); |
2559 | while (lex_opt(ls, ',')) |
2560 | var_new(ls, nvars++, lex_str(ls)); |
2561 | lex_check(ls, TK_in); |
2562 | line = ls->linenumber; |
2563 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
2564 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
2565 | bcreg_bump(fs, 3+LJ_FR2); |
2566 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); |
2567 | var_add(ls, 3); /* Hidden control variables. */ |
2568 | lex_check(ls, TK_do); |
2569 | loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP); |
2570 | fscope_begin(fs, &bl, 0); /* Scope for visible variables. */ |
2571 | var_add(ls, nvars-3); |
2572 | bcreg_reserve(fs, nvars-3); |
2573 | parse_block(ls); |
2574 | fscope_end(fs); |
2575 | /* Perform loop inversion. Loop control instructions are at the end. */ |
2576 | jmp_patchins(fs, loop, fs->pc); |
2577 | bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1); |
2578 | loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP); |
2579 | fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */ |
2580 | fs->bcbase[loopend].line = line; |
2581 | jmp_patchins(fs, loopend, loop+1); |
2582 | } |
2583 | |
2584 | /* Parse 'for' statement. */ |
2585 | static void parse_for(LexState *ls, BCLine line) |
2586 | { |
2587 | FuncState *fs = ls->fs; |
2588 | GCstr *varname; |
2589 | FuncScope bl; |
2590 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
2591 | lj_lex_next(ls); /* Skip 'for'. */ |
2592 | varname = lex_str(ls); /* Get first variable name. */ |
2593 | if (ls->tok == '=') |
2594 | parse_for_num(ls, varname, line); |
2595 | else if (ls->tok == ',' || ls->tok == TK_in) |
2596 | parse_for_iter(ls, varname); |
2597 | else |
2598 | err_syntax(ls, LJ_ERR_XFOR); |
2599 | lex_match(ls, TK_end, TK_for, line); |
2600 | fscope_end(fs); /* Resolve break list. */ |
2601 | } |
2602 | |
2603 | /* Parse condition and 'then' block. */ |
2604 | static BCPos parse_then(LexState *ls) |
2605 | { |
2606 | BCPos condexit; |
2607 | lj_lex_next(ls); /* Skip 'if' or 'elseif'. */ |
2608 | condexit = expr_cond(ls); |
2609 | lex_check(ls, TK_then); |
2610 | parse_block(ls); |
2611 | return condexit; |
2612 | } |
2613 | |
2614 | /* Parse 'if' statement. */ |
2615 | static void parse_if(LexState *ls, BCLine line) |
2616 | { |
2617 | FuncState *fs = ls->fs; |
2618 | BCPos flist; |
2619 | BCPos escapelist = NO_JMP; |
2620 | flist = parse_then(ls); |
2621 | while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
2622 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2623 | jmp_tohere(fs, flist); |
2624 | flist = parse_then(ls); |
2625 | } |
2626 | if (ls->tok == TK_else) { /* Parse optional 'else' block. */ |
2627 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2628 | jmp_tohere(fs, flist); |
2629 | lj_lex_next(ls); /* Skip 'else'. */ |
2630 | parse_block(ls); |
2631 | } else { |
2632 | jmp_append(fs, &escapelist, flist); |
2633 | } |
2634 | jmp_tohere(fs, escapelist); |
2635 | lex_match(ls, TK_end, TK_if, line); |
2636 | } |
2637 | |
2638 | /* -- Parse statements ---------------------------------------------------- */ |
2639 | |
2640 | /* Parse a statement. Returns 1 if it must be the last one in a chunk. */ |
2641 | static int parse_stmt(LexState *ls) |
2642 | { |
2643 | BCLine line = ls->linenumber; |
2644 | switch (ls->tok) { |
2645 | case TK_if: |
2646 | parse_if(ls, line); |
2647 | break; |
2648 | case TK_while: |
2649 | parse_while(ls, line); |
2650 | break; |
2651 | case TK_do: |
2652 | lj_lex_next(ls); |
2653 | parse_block(ls); |
2654 | lex_match(ls, TK_end, TK_do, line); |
2655 | break; |
2656 | case TK_for: |
2657 | parse_for(ls, line); |
2658 | break; |
2659 | case TK_repeat: |
2660 | parse_repeat(ls, line); |
2661 | break; |
2662 | case TK_function: |
2663 | parse_func(ls, line); |
2664 | break; |
2665 | case TK_local: |
2666 | lj_lex_next(ls); |
2667 | parse_local(ls); |
2668 | break; |
2669 | case TK_return: |
2670 | parse_return(ls); |
2671 | return 1; /* Must be last. */ |
2672 | case TK_break: |
2673 | lj_lex_next(ls); |
2674 | parse_break(ls); |
2675 | return !LJ_52; /* Must be last in Lua 5.1. */ |
2676 | #if LJ_52 |
2677 | case ';': |
2678 | lj_lex_next(ls); |
2679 | break; |
2680 | #endif |
2681 | case TK_label: |
2682 | parse_label(ls); |
2683 | break; |
2684 | case TK_goto: |
2685 | if (LJ_52 || lj_lex_lookahead(ls) == TK_name) { |
2686 | lj_lex_next(ls); |
2687 | parse_goto(ls); |
2688 | break; |
2689 | } |
2690 | /* fallthrough */ |
2691 | default: |
2692 | parse_call_assign(ls); |
2693 | break; |
2694 | } |
2695 | return 0; |
2696 | } |
2697 | |
2698 | /* A chunk is a list of statements optionally separated by semicolons. */ |
2699 | static void parse_chunk(LexState *ls) |
2700 | { |
2701 | int islast = 0; |
2702 | synlevel_begin(ls); |
2703 | while (!islast && !parse_isend(ls->tok)) { |
2704 | islast = parse_stmt(ls); |
2705 | lex_opt(ls, ';'); |
2706 | lj_assertLS(ls->fs->framesize >= ls->fs->freereg && |
2707 | ls->fs->freereg >= ls->fs->nactvar, |
2708 | "bad regalloc" ); |
2709 | ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */ |
2710 | } |
2711 | synlevel_end(ls); |
2712 | } |
2713 | |
2714 | /* Entry point of bytecode parser. */ |
2715 | GCproto *lj_parse(LexState *ls) |
2716 | { |
2717 | FuncState fs; |
2718 | FuncScope bl; |
2719 | GCproto *pt; |
2720 | lua_State *L = ls->L; |
2721 | #ifdef LUAJIT_DISABLE_DEBUGINFO |
2722 | ls->chunkname = lj_str_newlit(L, "=" ); |
2723 | #else |
2724 | ls->chunkname = lj_str_newz(L, ls->chunkarg); |
2725 | #endif |
2726 | setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */ |
2727 | incr_top(L); |
2728 | ls->level = 0; |
2729 | fs_init(ls, &fs); |
2730 | fs.linedefined = 0; |
2731 | fs.numparams = 0; |
2732 | fs.bcbase = NULL; |
2733 | fs.bclim = 0; |
2734 | fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */ |
2735 | fscope_begin(&fs, &bl, 0); |
2736 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
2737 | lj_lex_next(ls); /* Read-ahead first token. */ |
2738 | parse_chunk(ls); |
2739 | if (ls->tok != TK_eof) |
2740 | err_token(ls, TK_eof); |
2741 | pt = fs_finish(ls, ls->linenumber); |
2742 | L->top--; /* Drop chunkname. */ |
2743 | lj_assertL(fs.prev == NULL && ls->fs == NULL, "mismatched frame nesting" ); |
2744 | lj_assertL(pt->sizeuv == 0, "toplevel proto has upvalues" ); |
2745 | return pt; |
2746 | } |
2747 | |
2748 | |