Remove building with NOCRYPTO option
[minix.git] / external / mit / lua / dist / src / lcode.c
blob06a014ac9dc4f6468a5eb1e072536a70cc762a5e
1 /* $NetBSD: lcode.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $ */
3 /*
4 ** Id: lcode.c,v 2.101 2015/04/29 18:24:11 roberto Exp
5 ** Code generator for Lua
6 ** See Copyright Notice in lua.h
7 */
9 #define lcode_c
10 #define LUA_CORE
12 #include "lprefix.h"
15 #ifndef _KERNEL
16 #include <math.h>
17 #include <stdlib.h>
18 #endif
20 #include "lua.h"
22 #include "lcode.h"
23 #include "ldebug.h"
24 #include "ldo.h"
25 #include "lgc.h"
26 #include "llex.h"
27 #include "lmem.h"
28 #include "lobject.h"
29 #include "lopcodes.h"
30 #include "lparser.h"
31 #include "lstring.h"
32 #include "ltable.h"
33 #include "lvm.h"
36 /* Maximum number of registers in a Lua function (must fit in 8 bits) */
37 #define MAXREGS 255
40 #define hasjumps(e) ((e)->t != (e)->f)
43 static int tonumeral(expdesc *e, TValue *v) {
44 if (e->t != NO_JUMP || e->f != NO_JUMP)
45 return 0; /* not a numeral */
46 switch (e->k) {
47 case VKINT:
48 if (v) setivalue(v, e->u.ival);
49 return 1;
50 #ifndef _KERNEL
51 case VKFLT:
52 if (v) setfltvalue(v, e->u.nval);
53 return 1;
54 #endif
55 default: return 0;
60 void luaK_nil (FuncState *fs, int from, int n) {
61 Instruction *previous;
62 int l = from + n - 1; /* last register to set nil */
63 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
64 previous = &fs->f->code[fs->pc-1];
65 if (GET_OPCODE(*previous) == OP_LOADNIL) {
66 int pfrom = GETARG_A(*previous);
67 int pl = pfrom + GETARG_B(*previous);
68 if ((pfrom <= from && from <= pl + 1) ||
69 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
70 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
71 if (pl > l) l = pl; /* l = max(l, pl) */
72 SETARG_A(*previous, from);
73 SETARG_B(*previous, l - from);
74 return;
76 } /* else go through */
78 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
82 int luaK_jump (FuncState *fs) {
83 int jpc = fs->jpc; /* save list of jumps to here */
84 int j;
85 fs->jpc = NO_JUMP;
86 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
87 luaK_concat(fs, &j, jpc); /* keep them on hold */
88 return j;
92 void luaK_ret (FuncState *fs, int first, int nret) {
93 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
97 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
98 luaK_codeABC(fs, op, A, B, C);
99 return luaK_jump(fs);
103 static void fixjump (FuncState *fs, int pc, int dest) {
104 Instruction *jmp = &fs->f->code[pc];
105 int offset = dest-(pc+1);
106 lua_assert(dest != NO_JUMP);
107 if (abs(offset) > MAXARG_sBx)
108 luaX_syntaxerror(fs->ls, "control structure too long");
109 SETARG_sBx(*jmp, offset);
114 ** returns current 'pc' and marks it as a jump target (to avoid wrong
115 ** optimizations with consecutive instructions not in the same basic block).
117 int luaK_getlabel (FuncState *fs) {
118 fs->lasttarget = fs->pc;
119 return fs->pc;
123 static int getjump (FuncState *fs, int pc) {
124 int offset = GETARG_sBx(fs->f->code[pc]);
125 if (offset == NO_JUMP) /* point to itself represents end of list */
126 return NO_JUMP; /* end of list */
127 else
128 return (pc+1)+offset; /* turn offset into absolute position */
132 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
133 Instruction *pi = &fs->f->code[pc];
134 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
135 return pi-1;
136 else
137 return pi;
142 ** check whether list has any jump that do not produce a value
143 ** (or produce an inverted value)
145 static int need_value (FuncState *fs, int list) {
146 for (; list != NO_JUMP; list = getjump(fs, list)) {
147 Instruction i = *getjumpcontrol(fs, list);
148 if (GET_OPCODE(i) != OP_TESTSET) return 1;
150 return 0; /* not found */
154 static int patchtestreg (FuncState *fs, int node, int reg) {
155 Instruction *i = getjumpcontrol(fs, node);
156 if (GET_OPCODE(*i) != OP_TESTSET)
157 return 0; /* cannot patch other instructions */
158 if (reg != NO_REG && reg != GETARG_B(*i))
159 SETARG_A(*i, reg);
160 else /* no register to put value or register already has the value */
161 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
163 return 1;
167 static void removevalues (FuncState *fs, int list) {
168 for (; list != NO_JUMP; list = getjump(fs, list))
169 patchtestreg(fs, list, NO_REG);
173 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
174 int dtarget) {
175 while (list != NO_JUMP) {
176 int next = getjump(fs, list);
177 if (patchtestreg(fs, list, reg))
178 fixjump(fs, list, vtarget);
179 else
180 fixjump(fs, list, dtarget); /* jump to default target */
181 list = next;
186 static void dischargejpc (FuncState *fs) {
187 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
188 fs->jpc = NO_JUMP;
192 void luaK_patchlist (FuncState *fs, int list, int target) {
193 if (target == fs->pc)
194 luaK_patchtohere(fs, list);
195 else {
196 lua_assert(target < fs->pc);
197 patchlistaux(fs, list, target, NO_REG, target);
202 void luaK_patchclose (FuncState *fs, int list, int level) {
203 level++; /* argument is +1 to reserve 0 as non-op */
204 while (list != NO_JUMP) {
205 int next = getjump(fs, list);
206 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
207 (GETARG_A(fs->f->code[list]) == 0 ||
208 GETARG_A(fs->f->code[list]) >= level));
209 SETARG_A(fs->f->code[list], level);
210 list = next;
215 void luaK_patchtohere (FuncState *fs, int list) {
216 luaK_getlabel(fs);
217 luaK_concat(fs, &fs->jpc, list);
221 void luaK_concat (FuncState *fs, int *l1, int l2) {
222 if (l2 == NO_JUMP) return;
223 else if (*l1 == NO_JUMP)
224 *l1 = l2;
225 else {
226 int list = *l1;
227 int next;
228 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
229 list = next;
230 fixjump(fs, list, l2);
235 static int luaK_code (FuncState *fs, Instruction i) {
236 Proto *f = fs->f;
237 dischargejpc(fs); /* 'pc' will change */
238 /* put new instruction in code array */
239 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
240 MAX_INT, "opcodes");
241 f->code[fs->pc] = i;
242 /* save corresponding line information */
243 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
244 MAX_INT, "opcodes");
245 f->lineinfo[fs->pc] = fs->ls->lastline;
246 return fs->pc++;
250 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
251 lua_assert(getOpMode(o) == iABC);
252 lua_assert(getBMode(o) != OpArgN || b == 0);
253 lua_assert(getCMode(o) != OpArgN || c == 0);
254 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
255 return luaK_code(fs, CREATE_ABC(o, a, b, c));
259 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
260 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
261 lua_assert(getCMode(o) == OpArgN);
262 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
263 return luaK_code(fs, CREATE_ABx(o, a, bc));
267 static int codeextraarg (FuncState *fs, int a) {
268 lua_assert(a <= MAXARG_Ax);
269 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
273 int luaK_codek (FuncState *fs, int reg, int k) {
274 if (k <= MAXARG_Bx)
275 return luaK_codeABx(fs, OP_LOADK, reg, k);
276 else {
277 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
278 codeextraarg(fs, k);
279 return p;
284 void luaK_checkstack (FuncState *fs, int n) {
285 int newstack = fs->freereg + n;
286 if (newstack > fs->f->maxstacksize) {
287 if (newstack >= MAXREGS)
288 luaX_syntaxerror(fs->ls,
289 "function or expression needs too many registers");
290 fs->f->maxstacksize = cast_byte(newstack);
295 void luaK_reserveregs (FuncState *fs, int n) {
296 luaK_checkstack(fs, n);
297 fs->freereg += n;
301 static void freereg (FuncState *fs, int reg) {
302 if (!ISK(reg) && reg >= fs->nactvar) {
303 fs->freereg--;
304 lua_assert(reg == fs->freereg);
309 static void freeexp (FuncState *fs, expdesc *e) {
310 if (e->k == VNONRELOC)
311 freereg(fs, e->u.info);
316 ** Use scanner's table to cache position of constants in constant list
317 ** and try to reuse constants
319 static int addk (FuncState *fs, TValue *key, TValue *v) {
320 lua_State *L = fs->ls->L;
321 Proto *f = fs->f;
322 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
323 int k, oldsize;
324 if (ttisinteger(idx)) { /* is there an index there? */
325 k = cast_int(ivalue(idx));
326 /* correct value? (warning: must distinguish floats from integers!) */
327 if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
328 luaV_rawequalobj(&f->k[k], v))
329 return k; /* reuse index */
331 /* constant not found; create a new entry */
332 oldsize = f->sizek;
333 k = fs->nk;
334 /* numerical value does not need GC barrier;
335 table has no metatable, so it does not need to invalidate cache */
336 setivalue(idx, k);
337 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
338 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
339 setobj(L, &f->k[k], v);
340 fs->nk++;
341 luaC_barrier(L, f, v);
342 return k;
346 int luaK_stringK (FuncState *fs, TString *s) {
347 TValue o;
348 setsvalue(fs->ls->L, &o, s);
349 return addk(fs, &o, &o);
354 ** Integers use userdata as keys to avoid collision with floats with same
355 ** value; conversion to 'void*' used only for hashing, no "precision"
356 ** problems
358 int luaK_intK (FuncState *fs, lua_Integer n) {
359 TValue k, o;
360 setpvalue(&k, cast(void*, cast(size_t, n)));
361 setivalue(&o, n);
362 return addk(fs, &k, &o);
366 #ifndef _KERNEL
367 static int luaK_numberK (FuncState *fs, lua_Number r) {
368 TValue o;
369 setfltvalue(&o, r);
370 return addk(fs, &o, &o);
372 #endif
375 static int boolK (FuncState *fs, int b) {
376 TValue o;
377 setbvalue(&o, b);
378 return addk(fs, &o, &o);
382 static int nilK (FuncState *fs) {
383 TValue k, v;
384 setnilvalue(&v);
385 /* cannot use nil as key; instead use table itself to represent nil */
386 sethvalue(fs->ls->L, &k, fs->ls->h);
387 return addk(fs, &k, &v);
391 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
392 if (e->k == VCALL) { /* expression is an open function call? */
393 SETARG_C(getcode(fs, e), nresults+1);
395 else if (e->k == VVARARG) {
396 SETARG_B(getcode(fs, e), nresults+1);
397 SETARG_A(getcode(fs, e), fs->freereg);
398 luaK_reserveregs(fs, 1);
403 void luaK_setoneret (FuncState *fs, expdesc *e) {
404 if (e->k == VCALL) { /* expression is an open function call? */
405 e->k = VNONRELOC;
406 e->u.info = GETARG_A(getcode(fs, e));
408 else if (e->k == VVARARG) {
409 SETARG_B(getcode(fs, e), 2);
410 e->k = VRELOCABLE; /* can relocate its simple result */
415 void luaK_dischargevars (FuncState *fs, expdesc *e) {
416 switch (e->k) {
417 case VLOCAL: {
418 e->k = VNONRELOC;
419 break;
421 case VUPVAL: {
422 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
423 e->k = VRELOCABLE;
424 break;
426 case VINDEXED: {
427 OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
428 freereg(fs, e->u.ind.idx);
429 if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
430 freereg(fs, e->u.ind.t);
431 op = OP_GETTABLE;
433 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
434 e->k = VRELOCABLE;
435 break;
437 case VVARARG:
438 case VCALL: {
439 luaK_setoneret(fs, e);
440 break;
442 default: break; /* there is one value available (somewhere) */
447 static int code_label (FuncState *fs, int A, int b, int jump) {
448 luaK_getlabel(fs); /* those instructions may be jump targets */
449 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
453 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
454 luaK_dischargevars(fs, e);
455 switch (e->k) {
456 case VNIL: {
457 luaK_nil(fs, reg, 1);
458 break;
460 case VFALSE: case VTRUE: {
461 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
462 break;
464 case VK: {
465 luaK_codek(fs, reg, e->u.info);
466 break;
468 #ifndef _KERNEL
469 case VKFLT: {
470 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
471 break;
473 #endif
474 case VKINT: {
475 luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
476 break;
478 case VRELOCABLE: {
479 Instruction *pc = &getcode(fs, e);
480 SETARG_A(*pc, reg);
481 break;
483 case VNONRELOC: {
484 if (reg != e->u.info)
485 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
486 break;
488 default: {
489 lua_assert(e->k == VVOID || e->k == VJMP);
490 return; /* nothing to do... */
493 e->u.info = reg;
494 e->k = VNONRELOC;
498 static void discharge2anyreg (FuncState *fs, expdesc *e) {
499 if (e->k != VNONRELOC) {
500 luaK_reserveregs(fs, 1);
501 discharge2reg(fs, e, fs->freereg-1);
506 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
507 discharge2reg(fs, e, reg);
508 if (e->k == VJMP)
509 luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
510 if (hasjumps(e)) {
511 int final; /* position after whole expression */
512 int p_f = NO_JUMP; /* position of an eventual LOAD false */
513 int p_t = NO_JUMP; /* position of an eventual LOAD true */
514 if (need_value(fs, e->t) || need_value(fs, e->f)) {
515 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
516 p_f = code_label(fs, reg, 0, 1);
517 p_t = code_label(fs, reg, 1, 0);
518 luaK_patchtohere(fs, fj);
520 final = luaK_getlabel(fs);
521 patchlistaux(fs, e->f, final, reg, p_f);
522 patchlistaux(fs, e->t, final, reg, p_t);
524 e->f = e->t = NO_JUMP;
525 e->u.info = reg;
526 e->k = VNONRELOC;
530 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
531 luaK_dischargevars(fs, e);
532 freeexp(fs, e);
533 luaK_reserveregs(fs, 1);
534 exp2reg(fs, e, fs->freereg - 1);
538 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
539 luaK_dischargevars(fs, e);
540 if (e->k == VNONRELOC) {
541 if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
542 if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
543 exp2reg(fs, e, e->u.info); /* put value on it */
544 return e->u.info;
547 luaK_exp2nextreg(fs, e); /* default */
548 return e->u.info;
552 void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
553 if (e->k != VUPVAL || hasjumps(e))
554 luaK_exp2anyreg(fs, e);
558 void luaK_exp2val (FuncState *fs, expdesc *e) {
559 if (hasjumps(e))
560 luaK_exp2anyreg(fs, e);
561 else
562 luaK_dischargevars(fs, e);
566 int luaK_exp2RK (FuncState *fs, expdesc *e) {
567 luaK_exp2val(fs, e);
568 switch (e->k) {
569 case VTRUE:
570 case VFALSE:
571 case VNIL: {
572 if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
573 e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
574 e->k = VK;
575 return RKASK(e->u.info);
577 else break;
579 case VKINT: {
580 e->u.info = luaK_intK(fs, e->u.ival);
581 e->k = VK;
582 goto vk;
584 #ifndef _KERNEL
585 case VKFLT: {
586 e->u.info = luaK_numberK(fs, e->u.nval);
587 e->k = VK;
589 #endif
590 /* FALLTHROUGH */
591 case VK: {
593 if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
594 return RKASK(e->u.info);
595 else break;
597 default: break;
599 /* not a constant in the right range: put it in a register */
600 return luaK_exp2anyreg(fs, e);
604 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
605 switch (var->k) {
606 case VLOCAL: {
607 freeexp(fs, ex);
608 exp2reg(fs, ex, var->u.info);
609 return;
611 case VUPVAL: {
612 int e = luaK_exp2anyreg(fs, ex);
613 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
614 break;
616 case VINDEXED: {
617 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
618 int e = luaK_exp2RK(fs, ex);
619 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
620 break;
622 default: {
623 lua_assert(0); /* invalid var kind to store */
624 break;
627 freeexp(fs, ex);
631 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
632 int ereg;
633 luaK_exp2anyreg(fs, e);
634 ereg = e->u.info; /* register where 'e' was placed */
635 freeexp(fs, e);
636 e->u.info = fs->freereg; /* base register for op_self */
637 e->k = VNONRELOC;
638 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
639 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
640 freeexp(fs, key);
644 static void invertjump (FuncState *fs, expdesc *e) {
645 Instruction *pc = getjumpcontrol(fs, e->u.info);
646 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
647 GET_OPCODE(*pc) != OP_TEST);
648 SETARG_A(*pc, !(GETARG_A(*pc)));
652 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
653 if (e->k == VRELOCABLE) {
654 Instruction ie = getcode(fs, e);
655 if (GET_OPCODE(ie) == OP_NOT) {
656 fs->pc--; /* remove previous OP_NOT */
657 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
659 /* else go through */
661 discharge2anyreg(fs, e);
662 freeexp(fs, e);
663 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
667 void luaK_goiftrue (FuncState *fs, expdesc *e) {
668 int pc; /* pc of last jump */
669 luaK_dischargevars(fs, e);
670 switch (e->k) {
671 case VJMP: {
672 invertjump(fs, e);
673 pc = e->u.info;
674 break;
676 #ifndef _KERNEL
677 case VK: case VKFLT: case VKINT: case VTRUE: {
678 #else
679 case VK: case VKINT: case VTRUE: {
680 #endif
681 pc = NO_JUMP; /* always true; do nothing */
682 break;
684 default: {
685 pc = jumponcond(fs, e, 0);
686 break;
689 luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */
690 luaK_patchtohere(fs, e->t);
691 e->t = NO_JUMP;
695 void luaK_goiffalse (FuncState *fs, expdesc *e) {
696 int pc; /* pc of last jump */
697 luaK_dischargevars(fs, e);
698 switch (e->k) {
699 case VJMP: {
700 pc = e->u.info;
701 break;
703 case VNIL: case VFALSE: {
704 pc = NO_JUMP; /* always false; do nothing */
705 break;
707 default: {
708 pc = jumponcond(fs, e, 1);
709 break;
712 luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */
713 luaK_patchtohere(fs, e->f);
714 e->f = NO_JUMP;
718 static void codenot (FuncState *fs, expdesc *e) {
719 luaK_dischargevars(fs, e);
720 switch (e->k) {
721 case VNIL: case VFALSE: {
722 e->k = VTRUE;
723 break;
725 #ifndef _KERNEL
726 case VK: case VKFLT: case VKINT: case VTRUE: {
727 #else
728 case VK: case VKINT: case VTRUE: {
729 #endif
730 e->k = VFALSE;
731 break;
733 case VJMP: {
734 invertjump(fs, e);
735 break;
737 case VRELOCABLE:
738 case VNONRELOC: {
739 discharge2anyreg(fs, e);
740 freeexp(fs, e);
741 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
742 e->k = VRELOCABLE;
743 break;
745 default: {
746 lua_assert(0); /* cannot happen */
747 break;
750 /* interchange true and false lists */
751 { int temp = e->f; e->f = e->t; e->t = temp; }
752 removevalues(fs, e->f);
753 removevalues(fs, e->t);
757 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
758 lua_assert(!hasjumps(t));
759 t->u.ind.t = t->u.info;
760 t->u.ind.idx = luaK_exp2RK(fs, k);
761 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
762 : check_exp(vkisinreg(t->k), VLOCAL);
763 t->k = VINDEXED;
768 ** return false if folding can raise an error
770 static int validop (int op, TValue *v1, TValue *v2) {
771 switch (op) {
772 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
773 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
774 lua_Integer i;
775 return (tointeger(v1, &i) && tointeger(v2, &i));
777 #ifndef _KERNEL
778 case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
779 #else /* _KERNEL */
780 case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
781 #endif
782 return (nvalue(v2) != 0);
783 default: return 1; /* everything else is valid */
789 ** Try to "constant-fold" an operation; return 1 iff successful
791 static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
792 TValue v1, v2, res;
793 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
794 return 0; /* non-numeric operands or not safe to fold */
795 luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */
796 if (ttisinteger(&res)) {
797 e1->k = VKINT;
798 e1->u.ival = ivalue(&res);
800 else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */
801 #ifndef _KERNEL
802 lua_Number n = fltvalue(&res);
803 if (luai_numisnan(n) || n == 0)
804 return 0;
805 e1->k = VKFLT;
806 e1->u.nval = n;
807 #else /* _KERNEL */
808 return 0; /* if it is not integer, we must fail */
809 #endif
811 return 1;
816 ** Code for binary and unary expressions that "produce values"
817 ** (arithmetic operations, bitwise operations, concat, length). First
818 ** try to do constant folding (only for numeric [arithmetic and
819 ** bitwise] operations, which is what 'lua_arith' accepts).
820 ** Expression to produce final result will be encoded in 'e1'.
822 static void codeexpval (FuncState *fs, OpCode op,
823 expdesc *e1, expdesc *e2, int line) {
824 lua_assert(op >= OP_ADD);
825 if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
826 return; /* result has been folded */
827 else {
828 int o1, o2;
829 /* move operands to registers (if needed) */
830 if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
831 o2 = 0; /* no second expression */
832 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
834 else { /* regular case (binary operators) */
835 o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
836 o1 = luaK_exp2RK(fs, e1);
838 if (o1 > o2) { /* free registers in proper order */
839 freeexp(fs, e1);
840 freeexp(fs, e2);
842 else {
843 freeexp(fs, e2);
844 freeexp(fs, e1);
846 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
847 e1->k = VRELOCABLE; /* all those operations are relocable */
848 luaK_fixline(fs, line);
853 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
854 expdesc *e2) {
855 int o1 = luaK_exp2RK(fs, e1);
856 int o2 = luaK_exp2RK(fs, e2);
857 freeexp(fs, e2);
858 freeexp(fs, e1);
859 if (cond == 0 && op != OP_EQ) {
860 int temp; /* exchange args to replace by '<' or '<=' */
861 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
862 cond = 1;
864 e1->u.info = condjump(fs, op, cond, o1, o2);
865 e1->k = VJMP;
869 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
870 expdesc e2;
871 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
872 switch (op) {
873 case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
874 codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
875 break;
877 case OPR_NOT: codenot(fs, e); break;
878 default: lua_assert(0);
883 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
884 switch (op) {
885 case OPR_AND: {
886 luaK_goiftrue(fs, v);
887 break;
889 case OPR_OR: {
890 luaK_goiffalse(fs, v);
891 break;
893 case OPR_CONCAT: {
894 luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */
895 break;
897 case OPR_ADD: case OPR_SUB:
898 #ifndef _KERNEL
899 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
900 case OPR_MOD: case OPR_POW:
901 #else
902 case OPR_MUL: case OPR_IDIV:
903 case OPR_MOD:
904 #endif
905 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
906 case OPR_SHL: case OPR_SHR: {
907 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
908 break;
910 default: {
911 luaK_exp2RK(fs, v);
912 break;
918 void luaK_posfix (FuncState *fs, BinOpr op,
919 expdesc *e1, expdesc *e2, int line) {
920 switch (op) {
921 case OPR_AND: {
922 lua_assert(e1->t == NO_JUMP); /* list must be closed */
923 luaK_dischargevars(fs, e2);
924 luaK_concat(fs, &e2->f, e1->f);
925 *e1 = *e2;
926 break;
928 case OPR_OR: {
929 lua_assert(e1->f == NO_JUMP); /* list must be closed */
930 luaK_dischargevars(fs, e2);
931 luaK_concat(fs, &e2->t, e1->t);
932 *e1 = *e2;
933 break;
935 case OPR_CONCAT: {
936 luaK_exp2val(fs, e2);
937 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
938 lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
939 freeexp(fs, e1);
940 SETARG_B(getcode(fs, e2), e1->u.info);
941 e1->k = VRELOCABLE; e1->u.info = e2->u.info;
943 else {
944 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
945 codeexpval(fs, OP_CONCAT, e1, e2, line);
947 break;
949 #ifndef _KERNEL
950 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
951 case OPR_IDIV: case OPR_MOD: case OPR_POW:
952 #else
953 case OPR_ADD: case OPR_SUB: case OPR_MUL:
954 case OPR_IDIV: case OPR_MOD:
955 #endif
956 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
957 case OPR_SHL: case OPR_SHR: {
958 codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
959 break;
961 case OPR_EQ: case OPR_LT: case OPR_LE: {
962 codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
963 break;
965 case OPR_NE: case OPR_GT: case OPR_GE: {
966 codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
967 break;
969 default: lua_assert(0);
974 void luaK_fixline (FuncState *fs, int line) {
975 fs->f->lineinfo[fs->pc - 1] = line;
979 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
980 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
981 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
982 lua_assert(tostore != 0);
983 if (c <= MAXARG_C)
984 luaK_codeABC(fs, OP_SETLIST, base, b, c);
985 else if (c <= MAXARG_Ax) {
986 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
987 codeextraarg(fs, c);
989 else
990 luaX_syntaxerror(fs->ls, "constructor too long");
991 fs->freereg = base + 1; /* free registers with list values */