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