Line data Source code
1 : /*
2 : ** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $
3 : ** Code generator for Lua
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 :
8 : #include <stdlib.h>
9 :
10 : #define lcode_c
11 : #define LUA_CORE
12 :
13 : #include "lua.h"
14 :
15 : #include "lcode.h"
16 : #include "ldebug.h"
17 : #include "ldo.h"
18 : #include "lgc.h"
19 : #include "llex.h"
20 : #include "lmem.h"
21 : #include "lobject.h"
22 : #include "lopcodes.h"
23 : #include "lparser.h"
24 : #include "lstring.h"
25 : #include "ltable.h"
26 : #include "lvm.h"
27 :
28 :
29 : #define hasjumps(e) ((e)->t != (e)->f)
30 :
31 :
32 3564 : static int isnumeral(expdesc *e) {
33 3564 : return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
34 : }
35 :
36 :
37 281 : void luaK_nil (FuncState *fs, int from, int n) {
38 : Instruction *previous;
39 281 : int l = from + n - 1; /* last register to set nil */
40 281 : if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
41 264 : previous = &fs->f->code[fs->pc-1];
42 264 : if (GET_OPCODE(*previous) == OP_LOADNIL) {
43 5 : int pfrom = GETARG_A(*previous);
44 5 : int pl = pfrom + GETARG_B(*previous);
45 5 : if ((pfrom <= from && from <= pl + 1) ||
46 0 : (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
47 5 : if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
48 5 : if (pl > l) l = pl; /* l = max(l, pl) */
49 5 : SETARG_A(*previous, from);
50 5 : SETARG_B(*previous, l - from);
51 5 : return;
52 : }
53 : } /* else go through */
54 : }
55 276 : luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
56 : }
57 :
58 :
59 2962 : int luaK_jump (FuncState *fs) {
60 2962 : int jpc = fs->jpc; /* save list of jumps to here */
61 : int j;
62 2962 : fs->jpc = NO_JUMP;
63 2962 : j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
64 2962 : luaK_concat(fs, &j, jpc); /* keep them on hold */
65 2962 : return j;
66 : }
67 :
68 :
69 3170 : void luaK_ret (FuncState *fs, int first, int nret) {
70 3170 : luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
71 3170 : }
72 :
73 :
74 2165 : static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
75 2165 : luaK_codeABC(fs, op, A, B, C);
76 2165 : return luaK_jump(fs);
77 : }
78 :
79 :
80 3757 : static void fixjump (FuncState *fs, int pc, int dest) {
81 3757 : Instruction *jmp = &fs->f->code[pc];
82 3757 : int offset = dest-(pc+1);
83 : lua_assert(dest != NO_JUMP);
84 3757 : if (abs(offset) > MAXARG_sBx)
85 0 : luaX_syntaxerror(fs->ls, "control structure too long");
86 3757 : SETARG_sBx(*jmp, offset);
87 3757 : }
88 :
89 :
90 : /*
91 : ** returns current `pc' and marks it as a jump target (to avoid wrong
92 : ** optimizations with consecutive instructions not in the same basic block).
93 : */
94 6892 : int luaK_getlabel (FuncState *fs) {
95 6892 : fs->lasttarget = fs->pc;
96 6892 : return fs->pc;
97 : }
98 :
99 :
100 4037 : static int getjump (FuncState *fs, int pc) {
101 4037 : int offset = GETARG_sBx(fs->f->code[pc]);
102 4037 : if (offset == NO_JUMP) /* point to itself represents end of list */
103 3789 : return NO_JUMP; /* end of list */
104 : else
105 248 : return (pc+1)+offset; /* turn offset into absolute position */
106 : }
107 :
108 :
109 4720 : static Instruction *getjumpcontrol (FuncState *fs, int pc) {
110 4720 : Instruction *pi = &fs->f->code[pc];
111 4720 : if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
112 3334 : return pi-1;
113 : else
114 1386 : return pi;
115 : }
116 :
117 :
118 : /*
119 : ** check whether list has any jump that do not produce a value
120 : ** (or produce an inverted value)
121 : */
122 763 : static int need_value (FuncState *fs, int list) {
123 929 : for (; list != NO_JUMP; list = getjump(fs, list)) {
124 592 : Instruction i = *getjumpcontrol(fs, list);
125 592 : if (GET_OPCODE(i) != OP_TESTSET) return 1;
126 : }
127 337 : return 0; /* not found */
128 : }
129 :
130 :
131 3551 : static int patchtestreg (FuncState *fs, int node, int reg) {
132 3551 : Instruction *i = getjumpcontrol(fs, node);
133 3551 : if (GET_OPCODE(*i) != OP_TESTSET)
134 2776 : return 0; /* cannot patch other instructions */
135 775 : if (reg != NO_REG && reg != GETARG_B(*i))
136 4 : SETARG_A(*i, reg);
137 : else /* no register to put value or register already has the value */
138 771 : *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
139 :
140 775 : return 1;
141 : }
142 :
143 :
144 894 : static void removevalues (FuncState *fs, int list) {
145 894 : for (; list != NO_JUMP; list = getjump(fs, list))
146 0 : patchtestreg(fs, list, NO_REG);
147 894 : }
148 :
149 :
150 58184 : static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
151 : int dtarget) {
152 61735 : while (list != NO_JUMP) {
153 3551 : int next = getjump(fs, list);
154 3551 : if (patchtestreg(fs, list, reg))
155 775 : fixjump(fs, list, vtarget);
156 : else
157 2776 : fixjump(fs, list, dtarget); /* jump to default target */
158 3551 : list = next;
159 : }
160 58184 : }
161 :
162 :
163 56618 : static void dischargejpc (FuncState *fs) {
164 56618 : patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
165 56618 : fs->jpc = NO_JUMP;
166 56618 : }
167 :
168 :
169 397 : void luaK_patchlist (FuncState *fs, int list, int target) {
170 397 : if (target == fs->pc)
171 15 : luaK_patchtohere(fs, list);
172 : else {
173 : lua_assert(target < fs->pc);
174 382 : patchlistaux(fs, list, target, NO_REG, target);
175 : }
176 397 : }
177 :
178 :
179 72 : LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
180 72 : level++; /* argument is +1 to reserve 0 as non-op */
181 149 : while (list != NO_JUMP) {
182 77 : int next = getjump(fs, list);
183 : lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
184 : (GETARG_A(fs->f->code[list]) == 0 ||
185 : GETARG_A(fs->f->code[list]) >= level));
186 77 : SETARG_A(fs->f->code[list], level);
187 77 : list = next;
188 : }
189 72 : }
190 :
191 :
192 5381 : void luaK_patchtohere (FuncState *fs, int list) {
193 5381 : luaK_getlabel(fs);
194 5381 : luaK_concat(fs, &fs->jpc, list);
195 5381 : }
196 :
197 :
198 11460 : void luaK_concat (FuncState *fs, int *l1, int l2) {
199 11460 : if (l2 == NO_JUMP) return;
200 5540 : else if (*l1 == NO_JUMP)
201 5334 : *l1 = l2;
202 : else {
203 206 : int list = *l1;
204 : int next;
205 243 : while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
206 37 : list = next;
207 206 : fixjump(fs, list, l2);
208 : }
209 : }
210 :
211 :
212 56618 : static int luaK_code (FuncState *fs, Instruction i) {
213 56618 : Proto *f = fs->f;
214 56618 : dischargejpc(fs); /* `pc' will change */
215 : /* put new instruction in code array */
216 56618 : luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
217 : MAX_INT, "opcodes");
218 56618 : f->code[fs->pc] = i;
219 : /* save corresponding line information */
220 56618 : luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
221 : MAX_INT, "opcodes");
222 56618 : f->lineinfo[fs->pc] = fs->ls->lastline;
223 56618 : return fs->pc++;
224 : }
225 :
226 :
227 41811 : int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
228 : lua_assert(getOpMode(o) == iABC);
229 : lua_assert(getBMode(o) != OpArgN || b == 0);
230 : lua_assert(getCMode(o) != OpArgN || c == 0);
231 : lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
232 41811 : return luaK_code(fs, CREATE_ABC(o, a, b, c));
233 : }
234 :
235 :
236 14807 : int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
237 : lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
238 : lua_assert(getCMode(o) == OpArgN);
239 : lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
240 14807 : return luaK_code(fs, CREATE_ABx(o, a, bc));
241 : }
242 :
243 :
244 0 : static int codeextraarg (FuncState *fs, int a) {
245 : lua_assert(a <= MAXARG_Ax);
246 0 : return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
247 : }
248 :
249 :
250 9554 : int luaK_codek (FuncState *fs, int reg, int k) {
251 9554 : if (k <= MAXARG_Bx)
252 9554 : return luaK_codeABx(fs, OP_LOADK, reg, k);
253 : else {
254 0 : int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
255 0 : codeextraarg(fs, k);
256 0 : return p;
257 : }
258 : }
259 :
260 :
261 39130 : void luaK_checkstack (FuncState *fs, int n) {
262 39130 : int newstack = fs->freereg + n;
263 39130 : if (newstack > fs->f->maxstacksize) {
264 7115 : if (newstack >= MAXSTACK)
265 0 : luaX_syntaxerror(fs->ls, "function or expression too complex");
266 7115 : fs->f->maxstacksize = cast_byte(newstack);
267 : }
268 39130 : }
269 :
270 :
271 39090 : void luaK_reserveregs (FuncState *fs, int n) {
272 39090 : luaK_checkstack(fs, n);
273 39090 : fs->freereg += n;
274 39090 : }
275 :
276 :
277 31301 : static void freereg (FuncState *fs, int reg) {
278 31301 : if (!ISK(reg) && reg >= fs->nactvar) {
279 12162 : fs->freereg--;
280 : lua_assert(reg == fs->freereg);
281 : }
282 31301 : }
283 :
284 :
285 48875 : static void freeexp (FuncState *fs, expdesc *e) {
286 48875 : if (e->k == VNONRELOC)
287 18429 : freereg(fs, e->u.info);
288 48875 : }
289 :
290 :
291 23531 : static int addk (FuncState *fs, TValue *key, TValue *v) {
292 23531 : lua_State *L = fs->ls->L;
293 23531 : TValue *idx = luaH_set(L, fs->h, key);
294 23531 : Proto *f = fs->f;
295 : int k, oldsize;
296 23531 : if (ttisnumber(idx)) {
297 10191 : lua_Number n = nvalue(idx);
298 10191 : lua_number2int(k, n);
299 10191 : if (luaV_rawequalobj(&f->k[k], v))
300 10190 : return k;
301 : /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
302 : go through and create a new entry for this value */
303 : }
304 : /* constant not found; create a new entry */
305 13341 : oldsize = f->sizek;
306 13341 : k = fs->nk;
307 : /* numerical value does not need GC barrier;
308 : table has no metatable, so it does not need to invalidate cache */
309 13341 : setnvalue(idx, cast_num(k));
310 13341 : luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
311 33405 : while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
312 13341 : setobj(L, &f->k[k], v);
313 13341 : fs->nk++;
314 13341 : luaC_barrier(L, f, v);
315 13341 : return k;
316 : }
317 :
318 :
319 19732 : int luaK_stringK (FuncState *fs, TString *s) {
320 : TValue o;
321 19732 : setsvalue(fs->ls->L, &o, s);
322 19732 : return addk(fs, &o, &o);
323 : }
324 :
325 :
326 3609 : int luaK_numberK (FuncState *fs, lua_Number r) {
327 : int n;
328 3609 : lua_State *L = fs->ls->L;
329 : TValue o;
330 3609 : setnvalue(&o, r);
331 3609 : if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
332 : /* use raw representation as key to avoid numeric problems */
333 738 : setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
334 738 : n = addk(fs, L->top - 1, &o);
335 738 : L->top--;
336 : }
337 : else
338 2871 : n = addk(fs, &o, &o); /* regular case */
339 3609 : return n;
340 : }
341 :
342 :
343 147 : static int boolK (FuncState *fs, int b) {
344 : TValue o;
345 147 : setbvalue(&o, b);
346 147 : return addk(fs, &o, &o);
347 : }
348 :
349 :
350 43 : static int nilK (FuncState *fs) {
351 : TValue k, v;
352 43 : setnilvalue(&v);
353 : /* cannot use nil as key; instead use table itself to represent nil */
354 43 : sethvalue(fs->ls->L, &k, fs->h);
355 43 : return addk(fs, &k, &v);
356 : }
357 :
358 :
359 9389 : void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
360 9389 : if (e->k == VCALL) { /* expression is an open function call? */
361 1134 : SETARG_C(getcode(fs, e), nresults+1);
362 : }
363 8255 : else if (e->k == VVARARG) {
364 19 : SETARG_B(getcode(fs, e), nresults+1);
365 19 : SETARG_A(getcode(fs, e), fs->freereg);
366 19 : luaK_reserveregs(fs, 1);
367 : }
368 9389 : }
369 :
370 :
371 3917 : void luaK_setoneret (FuncState *fs, expdesc *e) {
372 3917 : if (e->k == VCALL) { /* expression is an open function call? */
373 2833 : e->k = VNONRELOC;
374 2833 : e->u.info = GETARG_A(getcode(fs, e));
375 : }
376 1084 : else if (e->k == VVARARG) {
377 1 : SETARG_B(getcode(fs, e), 2);
378 1 : e->k = VRELOCABLE; /* can relocate its simple result */
379 : }
380 3917 : }
381 :
382 :
383 116185 : void luaK_dischargevars (FuncState *fs, expdesc *e) {
384 116185 : switch (e->k) {
385 9811 : case VLOCAL: {
386 9811 : e->k = VNONRELOC;
387 9811 : break;
388 : }
389 2268 : case VUPVAL: {
390 2268 : e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
391 2268 : e->k = VRELOCABLE;
392 2268 : break;
393 : }
394 10402 : case VINDEXED: {
395 10402 : OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
396 10402 : freereg(fs, e->u.ind.idx);
397 10402 : if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
398 2470 : freereg(fs, e->u.ind.t);
399 2470 : op = OP_GETTABLE;
400 : }
401 10402 : e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
402 10402 : e->k = VRELOCABLE;
403 10402 : break;
404 : }
405 2003 : case VVARARG:
406 : case VCALL: {
407 2003 : luaK_setoneret(fs, e);
408 2003 : break;
409 : }
410 91701 : default: break; /* there is one value available (somewhere) */
411 : }
412 116185 : }
413 :
414 :
415 852 : static int code_label (FuncState *fs, int A, int b, int jump) {
416 852 : luaK_getlabel(fs); /* those instructions may be jump targets */
417 852 : return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
418 : }
419 :
420 :
421 36724 : static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
422 36724 : luaK_dischargevars(fs, e);
423 36724 : switch (e->k) {
424 217 : case VNIL: {
425 217 : luaK_nil(fs, reg, 1);
426 217 : break;
427 : }
428 752 : case VFALSE: case VTRUE: {
429 752 : luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
430 752 : break;
431 : }
432 6859 : case VK: {
433 6859 : luaK_codek(fs, reg, e->u.info);
434 6859 : break;
435 : }
436 2432 : case VKNUM: {
437 2432 : luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
438 2432 : break;
439 : }
440 17752 : case VRELOCABLE: {
441 17752 : Instruction *pc = &getcode(fs, e);
442 17752 : SETARG_A(*pc, reg);
443 17752 : break;
444 : }
445 8338 : case VNONRELOC: {
446 8338 : if (reg != e->u.info)
447 5492 : luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
448 8338 : break;
449 : }
450 374 : default: {
451 : lua_assert(e->k == VVOID || e->k == VJMP);
452 374 : return; /* nothing to do... */
453 : }
454 : }
455 36350 : e->u.info = reg;
456 36350 : e->k = VNONRELOC;
457 : }
458 :
459 :
460 1209 : static void discharge2anyreg (FuncState *fs, expdesc *e) {
461 1209 : if (e->k != VNONRELOC) {
462 270 : luaK_reserveregs(fs, 1);
463 270 : discharge2reg(fs, e, fs->freereg-1);
464 : }
465 1209 : }
466 :
467 :
468 36454 : static void exp2reg (FuncState *fs, expdesc *e, int reg) {
469 36454 : discharge2reg(fs, e, reg);
470 36454 : if (e->k == VJMP)
471 374 : luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
472 36454 : if (hasjumps(e)) {
473 : int final; /* position after whole expression */
474 592 : int p_f = NO_JUMP; /* position of an eventual LOAD false */
475 592 : int p_t = NO_JUMP; /* position of an eventual LOAD true */
476 592 : if (need_value(fs, e->t) || need_value(fs, e->f)) {
477 426 : int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
478 426 : p_f = code_label(fs, reg, 0, 1);
479 426 : p_t = code_label(fs, reg, 1, 0);
480 426 : luaK_patchtohere(fs, fj);
481 : }
482 592 : final = luaK_getlabel(fs);
483 592 : patchlistaux(fs, e->f, final, reg, p_f);
484 592 : patchlistaux(fs, e->t, final, reg, p_t);
485 : }
486 36454 : e->f = e->t = NO_JUMP;
487 36454 : e->u.info = reg;
488 36454 : e->k = VNONRELOC;
489 36454 : }
490 :
491 :
492 35595 : void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
493 35595 : luaK_dischargevars(fs, e);
494 35595 : freeexp(fs, e);
495 35595 : luaK_reserveregs(fs, 1);
496 35595 : exp2reg(fs, e, fs->freereg - 1);
497 35595 : }
498 :
499 :
500 14537 : int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
501 14537 : luaK_dischargevars(fs, e);
502 14537 : if (e->k == VNONRELOC) {
503 10623 : if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
504 1 : if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
505 0 : exp2reg(fs, e, e->u.info); /* put value on it */
506 0 : return e->u.info;
507 : }
508 : }
509 3915 : luaK_exp2nextreg(fs, e); /* default */
510 3915 : return e->u.info;
511 : }
512 :
513 :
514 2945 : void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
515 2945 : if (e->k != VUPVAL || hasjumps(e))
516 2845 : luaK_exp2anyreg(fs, e);
517 2945 : }
518 :
519 :
520 26602 : void luaK_exp2val (FuncState *fs, expdesc *e) {
521 26602 : if (hasjumps(e))
522 43 : luaK_exp2anyreg(fs, e);
523 : else
524 26559 : luaK_dischargevars(fs, e);
525 26602 : }
526 :
527 :
528 23759 : int luaK_exp2RK (FuncState *fs, expdesc *e) {
529 23759 : luaK_exp2val(fs, e);
530 23759 : switch (e->k) {
531 190 : case VTRUE:
532 : case VFALSE:
533 : case VNIL: {
534 190 : if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
535 190 : e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
536 190 : e->k = VK;
537 190 : return RKASK(e->u.info);
538 : }
539 0 : else break;
540 : }
541 914 : case VKNUM: {
542 914 : e->u.info = luaK_numberK(fs, e->u.nval);
543 914 : e->k = VK;
544 : /* go through */
545 : }
546 13966 : case VK: {
547 13966 : if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
548 13913 : return RKASK(e->u.info);
549 53 : else break;
550 : }
551 9603 : default: break;
552 : }
553 : /* not a constant in the right range: put it in a register */
554 9656 : return luaK_exp2anyreg(fs, e);
555 : }
556 :
557 :
558 3057 : void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
559 3057 : switch (var->k) {
560 859 : case VLOCAL: {
561 859 : freeexp(fs, ex);
562 859 : exp2reg(fs, ex, var->u.info);
563 859 : return;
564 : }
565 224 : case VUPVAL: {
566 224 : int e = luaK_exp2anyreg(fs, ex);
567 224 : luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
568 224 : break;
569 : }
570 1974 : case VINDEXED: {
571 1974 : OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
572 1974 : int e = luaK_exp2RK(fs, ex);
573 1974 : luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
574 1974 : break;
575 : }
576 0 : default: {
577 : lua_assert(0); /* invalid var kind to store */
578 0 : break;
579 : }
580 : }
581 2198 : freeexp(fs, ex);
582 : }
583 :
584 :
585 520 : void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
586 : int ereg;
587 520 : luaK_exp2anyreg(fs, e);
588 520 : ereg = e->u.info; /* register where 'e' was placed */
589 520 : freeexp(fs, e);
590 520 : e->u.info = fs->freereg; /* base register for op_self */
591 520 : e->k = VNONRELOC;
592 520 : luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
593 520 : luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
594 520 : freeexp(fs, key);
595 520 : }
596 :
597 :
598 577 : static void invertjump (FuncState *fs, expdesc *e) {
599 577 : Instruction *pc = getjumpcontrol(fs, e->u.info);
600 : lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
601 : GET_OPCODE(*pc) != OP_TEST);
602 577 : SETARG_A(*pc, !(GETARG_A(*pc)));
603 577 : }
604 :
605 :
606 1153 : static int jumponcond (FuncState *fs, expdesc *e, int cond) {
607 1153 : if (e->k == VRELOCABLE) {
608 613 : Instruction ie = getcode(fs, e);
609 613 : if (GET_OPCODE(ie) == OP_NOT) {
610 378 : fs->pc--; /* remove previous OP_NOT */
611 378 : return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
612 : }
613 : /* else go through */
614 : }
615 775 : discharge2anyreg(fs, e);
616 775 : freeexp(fs, e);
617 775 : return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
618 : }
619 :
620 :
621 1567 : void luaK_goiftrue (FuncState *fs, expdesc *e) {
622 : int pc; /* pc of last jump */
623 1567 : luaK_dischargevars(fs, e);
624 1567 : switch (e->k) {
625 575 : case VJMP: {
626 575 : invertjump(fs, e);
627 575 : pc = e->u.info;
628 575 : break;
629 : }
630 12 : case VK: case VKNUM: case VTRUE: {
631 12 : pc = NO_JUMP; /* always true; do nothing */
632 12 : break;
633 : }
634 980 : default: {
635 980 : pc = jumponcond(fs, e, 0);
636 980 : break;
637 : }
638 : }
639 1567 : luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
640 1567 : luaK_patchtohere(fs, e->t);
641 1567 : e->t = NO_JUMP;
642 1567 : }
643 :
644 :
645 240 : void luaK_goiffalse (FuncState *fs, expdesc *e) {
646 : int pc; /* pc of last jump */
647 240 : luaK_dischargevars(fs, e);
648 240 : switch (e->k) {
649 63 : case VJMP: {
650 63 : pc = e->u.info;
651 63 : break;
652 : }
653 4 : case VNIL: case VFALSE: {
654 4 : pc = NO_JUMP; /* always false; do nothing */
655 4 : break;
656 : }
657 173 : default: {
658 173 : pc = jumponcond(fs, e, 1);
659 173 : break;
660 : }
661 : }
662 240 : luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
663 240 : luaK_patchtohere(fs, e->f);
664 240 : e->f = NO_JUMP;
665 240 : }
666 :
667 :
668 447 : static void codenot (FuncState *fs, expdesc *e) {
669 447 : luaK_dischargevars(fs, e);
670 447 : switch (e->k) {
671 5 : case VNIL: case VFALSE: {
672 5 : e->k = VTRUE;
673 5 : break;
674 : }
675 6 : case VK: case VKNUM: case VTRUE: {
676 6 : e->k = VFALSE;
677 6 : break;
678 : }
679 2 : case VJMP: {
680 2 : invertjump(fs, e);
681 2 : break;
682 : }
683 434 : case VRELOCABLE:
684 : case VNONRELOC: {
685 434 : discharge2anyreg(fs, e);
686 434 : freeexp(fs, e);
687 434 : e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
688 434 : e->k = VRELOCABLE;
689 434 : break;
690 : }
691 0 : default: {
692 : lua_assert(0); /* cannot happen */
693 0 : break;
694 : }
695 : }
696 : /* interchange true and false lists */
697 447 : { int temp = e->f; e->f = e->t; e->t = temp; }
698 447 : removevalues(fs, e->f);
699 447 : removevalues(fs, e->t);
700 447 : }
701 :
702 :
703 12395 : void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
704 : lua_assert(!hasjumps(t));
705 12395 : t->u.ind.t = t->u.info;
706 12395 : t->u.ind.idx = luaK_exp2RK(fs, k);
707 12395 : t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
708 : : check_exp(vkisinreg(t->k), VLOCAL);
709 12395 : t->k = VINDEXED;
710 12395 : }
711 :
712 :
713 2633 : static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
714 : lua_Number r;
715 2633 : if (!isnumeral(e1) || !isnumeral(e2)) return 0;
716 29 : if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
717 7 : return 0; /* do not attempt to divide by 0 */
718 22 : r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
719 22 : e1->u.nval = r;
720 22 : return 1;
721 : }
722 :
723 :
724 2633 : static void codearith (FuncState *fs, OpCode op,
725 : expdesc *e1, expdesc *e2, int line) {
726 2633 : if (constfolding(op, e1, e2))
727 22 : return;
728 : else {
729 2611 : int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
730 2611 : int o1 = luaK_exp2RK(fs, e1);
731 2611 : if (o1 > o2) {
732 274 : freeexp(fs, e1);
733 274 : freeexp(fs, e2);
734 : }
735 : else {
736 2337 : freeexp(fs, e2);
737 2337 : freeexp(fs, e1);
738 : }
739 2611 : e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
740 2611 : e1->k = VRELOCABLE;
741 2611 : luaK_fixline(fs, line);
742 : }
743 : }
744 :
745 :
746 1012 : static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
747 : expdesc *e2) {
748 1012 : int o1 = luaK_exp2RK(fs, e1);
749 1012 : int o2 = luaK_exp2RK(fs, e2);
750 1012 : freeexp(fs, e2);
751 1012 : freeexp(fs, e1);
752 1012 : if (cond == 0 && op != OP_EQ) {
753 : int temp; /* exchange args to replace by `<' or `<=' */
754 227 : temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
755 227 : cond = 1;
756 : }
757 1012 : e1->u.info = condjump(fs, op, cond, o1, o2);
758 1012 : e1->k = VJMP;
759 1012 : }
760 :
761 :
762 1094 : void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
763 : expdesc e2;
764 1094 : e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
765 1094 : switch (op) {
766 127 : case OPR_MINUS: {
767 127 : if (isnumeral(e)) /* minus constant? */
768 111 : e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
769 : else {
770 16 : luaK_exp2anyreg(fs, e);
771 16 : codearith(fs, OP_UNM, e, &e2, line);
772 : }
773 127 : break;
774 : }
775 447 : case OPR_NOT: codenot(fs, e); break;
776 520 : case OPR_LEN: {
777 520 : luaK_exp2anyreg(fs, e); /* cannot operate on constants */
778 520 : codearith(fs, OP_LEN, e, &e2, line);
779 520 : break;
780 : }
781 1094 : default: lua_assert(0);
782 : }
783 1094 : }
784 :
785 :
786 4214 : void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
787 4214 : switch (op) {
788 145 : case OPR_AND: {
789 145 : luaK_goiftrue(fs, v);
790 145 : break;
791 : }
792 232 : case OPR_OR: {
793 232 : luaK_goiffalse(fs, v);
794 232 : break;
795 : }
796 2099 : case OPR_CONCAT: {
797 2099 : luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
798 2099 : break;
799 : }
800 726 : case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
801 : case OPR_MOD: case OPR_POW: {
802 726 : if (!isnumeral(v)) luaK_exp2RK(fs, v);
803 726 : break;
804 : }
805 1012 : default: {
806 1012 : luaK_exp2RK(fs, v);
807 1012 : break;
808 : }
809 : }
810 4214 : }
811 :
812 :
813 4214 : void luaK_posfix (FuncState *fs, BinOpr op,
814 : expdesc *e1, expdesc *e2, int line) {
815 4214 : switch (op) {
816 145 : case OPR_AND: {
817 : lua_assert(e1->t == NO_JUMP); /* list must be closed */
818 145 : luaK_dischargevars(fs, e2);
819 145 : luaK_concat(fs, &e2->f, e1->f);
820 145 : *e1 = *e2;
821 145 : break;
822 : }
823 232 : case OPR_OR: {
824 : lua_assert(e1->f == NO_JUMP); /* list must be closed */
825 232 : luaK_dischargevars(fs, e2);
826 232 : luaK_concat(fs, &e2->t, e1->t);
827 232 : *e1 = *e2;
828 232 : break;
829 : }
830 2099 : case OPR_CONCAT: {
831 2099 : luaK_exp2val(fs, e2);
832 2099 : if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
833 : lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
834 728 : freeexp(fs, e1);
835 728 : SETARG_B(getcode(fs, e2), e1->u.info);
836 728 : e1->k = VRELOCABLE; e1->u.info = e2->u.info;
837 : }
838 : else {
839 1371 : luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
840 1371 : codearith(fs, OP_CONCAT, e1, e2, line);
841 : }
842 2099 : break;
843 : }
844 726 : case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
845 : case OPR_MOD: case OPR_POW: {
846 726 : codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
847 726 : break;
848 : }
849 552 : case OPR_EQ: case OPR_LT: case OPR_LE: {
850 552 : codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
851 552 : break;
852 : }
853 460 : case OPR_NE: case OPR_GT: case OPR_GE: {
854 460 : codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
855 460 : break;
856 : }
857 4214 : default: lua_assert(0);
858 : }
859 4214 : }
860 :
861 :
862 13166 : void luaK_fixline (FuncState *fs, int line) {
863 13166 : fs->f->lineinfo[fs->pc - 1] = line;
864 13166 : }
865 :
866 :
867 416 : void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
868 416 : int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
869 416 : int b = (tostore == LUA_MULTRET) ? 0 : tostore;
870 : lua_assert(tostore != 0);
871 416 : if (c <= MAXARG_C)
872 416 : luaK_codeABC(fs, OP_SETLIST, base, b, c);
873 0 : else if (c <= MAXARG_Ax) {
874 0 : luaK_codeABC(fs, OP_SETLIST, base, b, 0);
875 0 : codeextraarg(fs, c);
876 : }
877 : else
878 0 : luaX_syntaxerror(fs->ls, "constructor too long");
879 416 : fs->freereg = base + 1; /* free registers with list values */
880 416 : }
881 :
|