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