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