Committed lnum patch 031007
[lua.git] / src / lcode.c
bloba2d4f450f25d06eaae304d40df0937bab94543a1
1 /*
2 ** $Id: lcode.c,v 2.25a 2006/03/21 19:28:49 roberto Exp $
3 ** Code generator for Lua
4 ** See Copyright Notice in lua.h
5 */
8 #include <stdlib.h>
10 #define lcode_c
11 #define LUA_CORE
13 #include "lua.h"
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 "ltable.h"
25 #include "lnum.h"
28 #define hasjumps(e) ((e)->t != (e)->f)
30 static lu_bool isnumeral(expdesc *e) {
31 lu_bool ek=
32 #ifdef LUA_TINT
33 (e->k == VKINT) ||
34 #endif
35 #ifdef LNUM_COMPLEX
36 (e->k == VKNUM2) ||
37 #endif
38 (e->k == VKNUM);
39 return (ek && e->t == NO_JUMP && e->f == NO_JUMP);
43 void luaK_nil (FuncState *fs, int from, int n) {
44 Instruction *previous;
45 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
46 if (fs->pc == 0) { /* function start? */
47 if (from >= fs->nactvar)
48 return; /* positions are already clean */
50 else {
51 previous = &fs->f->code[fs->pc-1];
52 if (GET_OPCODE(*previous) == OP_LOADNIL) {
53 int pfrom = GETARG_A(*previous);
54 int pto = GETARG_B(*previous);
55 if (pfrom <= from && from <= pto+1) { /* can connect both? */
56 if (from+n-1 > pto)
57 SETARG_B(*previous, from+n-1);
58 return;
63 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
67 int luaK_jump (FuncState *fs) {
68 int jpc = fs->jpc; /* save list of jumps to here */
69 int j;
70 fs->jpc = NO_JUMP;
71 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
72 luaK_concat(fs, &j, jpc); /* keep them on hold */
73 return j;
77 void luaK_ret (FuncState *fs, int first, int nret) {
78 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
82 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
83 luaK_codeABC(fs, op, A, B, C);
84 return luaK_jump(fs);
88 static void fixjump (FuncState *fs, int pc, int dest) {
89 Instruction *jmp = &fs->f->code[pc];
90 int offset = dest-(pc+1);
91 lua_assert(dest != NO_JUMP);
92 if (abs(offset) > MAXARG_sBx)
93 luaX_syntaxerror(fs->ls, "control structure too long");
94 SETARG_sBx(*jmp, offset);
99 ** returns current `pc' and marks it as a jump target (to avoid wrong
100 ** optimizations with consecutive instructions not in the same basic block).
102 int luaK_getlabel (FuncState *fs) {
103 fs->lasttarget = fs->pc;
104 return fs->pc;
108 static int getjump (FuncState *fs, int pc) {
109 int offset = GETARG_sBx(fs->f->code[pc]);
110 if (offset == NO_JUMP) /* point to itself represents end of list */
111 return NO_JUMP; /* end of list */
112 else
113 return (pc+1)+offset; /* turn offset into absolute position */
117 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
118 Instruction *pi = &fs->f->code[pc];
119 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
120 return pi-1;
121 else
122 return pi;
127 ** check whether list has any jump that do not produce a value
128 ** (or produce an inverted value)
130 static lu_bool need_value (FuncState *fs, int list) {
131 for (; list != NO_JUMP; list = getjump(fs, list)) {
132 Instruction i = *getjumpcontrol(fs, list);
133 if (GET_OPCODE(i) != OP_TESTSET) return 1;
135 return 0; /* not found */
139 static lu_bool patchtestreg (FuncState *fs, int node, int reg) {
140 Instruction *i = getjumpcontrol(fs, node);
141 if (GET_OPCODE(*i) != OP_TESTSET)
142 return 0; /* cannot patch other instructions */
143 if (reg != NO_REG && reg != GETARG_B(*i))
144 SETARG_A(*i, reg);
145 else /* no register to put value or register already has the value */
146 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
148 return 1;
152 static void removevalues (FuncState *fs, int list) {
153 for (; list != NO_JUMP; list = getjump(fs, list))
154 patchtestreg(fs, list, NO_REG);
158 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
159 int dtarget) {
160 while (list != NO_JUMP) {
161 int next = getjump(fs, list);
162 if (patchtestreg(fs, list, reg))
163 fixjump(fs, list, vtarget);
164 else
165 fixjump(fs, list, dtarget); /* jump to default target */
166 list = next;
171 static void dischargejpc (FuncState *fs) {
172 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
173 fs->jpc = NO_JUMP;
177 void luaK_patchlist (FuncState *fs, int list, int target) {
178 if (target == fs->pc)
179 luaK_patchtohere(fs, list);
180 else {
181 lua_assert(target < fs->pc);
182 patchlistaux(fs, list, target, NO_REG, target);
187 void luaK_patchtohere (FuncState *fs, int list) {
188 luaK_getlabel(fs);
189 luaK_concat(fs, &fs->jpc, list);
193 void luaK_concat (FuncState *fs, int *l1, int l2) {
194 if (l2 == NO_JUMP) return;
195 else if (*l1 == NO_JUMP)
196 *l1 = l2;
197 else {
198 int list = *l1;
199 int next;
200 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
201 list = next;
202 fixjump(fs, list, l2);
207 void luaK_checkstack (FuncState *fs, int n) {
208 int newstack = fs->freereg + n;
209 if (newstack > fs->f->maxstacksize) {
210 if (newstack >= MAXSTACK)
211 luaX_syntaxerror(fs->ls, "function or expression too complex");
212 fs->f->maxstacksize = cast_byte(newstack);
217 void luaK_reserveregs (FuncState *fs, int n) {
218 luaK_checkstack(fs, n);
219 fs->freereg += n;
223 static void freereg (FuncState *fs, int reg) {
224 if (!ISK(reg) && reg >= fs->nactvar) {
225 fs->freereg--;
226 lua_assert(reg == fs->freereg);
231 static void freeexp (FuncState *fs, expdesc *e) {
232 if (e->k == VNONRELOC)
233 freereg(fs, e->u.s.info);
237 static int addk (FuncState *fs, TValue *k, TValue *v) {
238 lua_State *L = fs->L;
239 TValue *idx = luaH_set(L, fs->h, k);
240 Proto *f = fs->f;
241 int oldsize = f->sizek;
242 #ifdef LUA_TINT
243 lua_assert( !ttisnumber_raw(idx) );
244 if (ttisinteger(idx)) {
245 lua_assert(luaO_rawequalObj(&fs->f->k[ (int) ivalue(idx) ], v));
246 return ivalue(idx);
248 #else
249 if (ttisnumber(idx)) {
250 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
251 return cast_int(nvalue(idx));
253 #endif
254 else { /* constant not found; create a new entry */
255 setivalue(idx, fs->nk);
256 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
257 MAXARG_Bx, "constant table overflow");
258 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
259 setobj(L, &f->k[fs->nk], v);
260 luaC_barrier(L, f, v);
261 return fs->nk++;
266 int luaK_stringK (FuncState *fs, TString *s) {
267 TValue o;
268 setsvalue(fs->L, &o, s);
269 return addk(fs, &o, &o);
273 int luaK_numberK (FuncState *fs, lua_Number r) {
274 TValue o;
275 setnvalue(&o, r);
276 return addk(fs, &o, &o);
280 #ifdef LUA_TINT
281 int luaK_integerK (FuncState *fs, lua_Integer r) {
282 TValue o;
283 setivalue(&o, r);
284 return addk(fs, &o, &o);
286 #endif
289 #ifdef LNUM_COMPLEX
290 static int luaK_imagK (FuncState *fs, lua_Number r) {
291 TValue o;
292 setnvalue_complex(&o, r*I);
293 return addk(fs, &o, &o);
295 #endif
297 static int boolK (FuncState *fs, int b) {
298 TValue o;
299 setbvalue(&o, b);
300 return addk(fs, &o, &o);
304 static int nilK (FuncState *fs) {
305 TValue k, v;
306 setnilvalue(&v);
307 /* cannot use nil as key; instead use table itself to represent nil */
308 sethvalue(fs->L, &k, fs->h);
309 return addk(fs, &k, &v);
313 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
314 if (e->k == VCALL) { /* expression is an open function call? */
315 SETARG_C(getcode(fs, e), nresults+1);
317 else if (e->k == VVARARG) {
318 SETARG_B(getcode(fs, e), nresults+1);
319 SETARG_A(getcode(fs, e), fs->freereg);
320 luaK_reserveregs(fs, 1);
325 void luaK_setoneret (FuncState *fs, expdesc *e) {
326 if (e->k == VCALL) { /* expression is an open function call? */
327 e->k = VNONRELOC;
328 e->u.s.info = GETARG_A(getcode(fs, e));
330 else if (e->k == VVARARG) {
331 SETARG_B(getcode(fs, e), 2);
332 e->k = VRELOCABLE; /* can relocate its simple result */
337 void luaK_dischargevars (FuncState *fs, expdesc *e) {
338 switch (e->k) {
339 case VLOCAL: {
340 e->k = VNONRELOC;
341 break;
343 case VUPVAL: {
344 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
345 e->k = VRELOCABLE;
346 break;
348 case VGLOBAL: {
349 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
350 e->k = VRELOCABLE;
351 break;
353 case VINDEXED: {
354 freereg(fs, e->u.s.aux);
355 freereg(fs, e->u.s.info);
356 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
357 e->k = VRELOCABLE;
358 break;
360 case VVARARG:
361 case VCALL: {
362 luaK_setoneret(fs, e);
363 break;
365 default: break; /* there is one value available (somewhere) */
370 static int code_label (FuncState *fs, int A, int b, int jump) {
371 luaK_getlabel(fs); /* those instructions may be jump targets */
372 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
376 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
377 luaK_dischargevars(fs, e);
378 switch (e->k) {
379 case VNIL: {
380 luaK_nil(fs, reg, 1);
381 break;
383 case VFALSE: case VTRUE: {
384 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
385 break;
387 case VK: {
388 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
389 break;
391 case VKNUM: {
392 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
393 break;
395 #ifdef LUA_TINT
396 case VKINT: {
397 luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival));
398 break;
400 #endif
401 #ifdef LNUM_COMPLEX
402 case VKNUM2: {
403 luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval));
404 break;
406 #endif
407 case VRELOCABLE: {
408 Instruction *pc = &getcode(fs, e);
409 SETARG_A(*pc, reg);
410 break;
412 case VNONRELOC: {
413 if (reg != e->u.s.info)
414 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
415 break;
417 default: {
418 lua_assert(e->k == VVOID || e->k == VJMP);
419 return; /* nothing to do... */
422 e->u.s.info = reg;
423 e->k = VNONRELOC;
427 static void discharge2anyreg (FuncState *fs, expdesc *e) {
428 if (e->k != VNONRELOC) {
429 luaK_reserveregs(fs, 1);
430 discharge2reg(fs, e, fs->freereg-1);
435 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
436 discharge2reg(fs, e, reg);
437 if (e->k == VJMP)
438 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
439 if (hasjumps(e)) {
440 int final; /* position after whole expression */
441 int p_f = NO_JUMP; /* position of an eventual LOAD false */
442 int p_t = NO_JUMP; /* position of an eventual LOAD true */
443 if (need_value(fs, e->t) || need_value(fs, e->f)) {
444 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
445 p_f = code_label(fs, reg, 0, 1);
446 p_t = code_label(fs, reg, 1, 0);
447 luaK_patchtohere(fs, fj);
449 final = luaK_getlabel(fs);
450 patchlistaux(fs, e->f, final, reg, p_f);
451 patchlistaux(fs, e->t, final, reg, p_t);
453 e->f = e->t = NO_JUMP;
454 e->u.s.info = reg;
455 e->k = VNONRELOC;
459 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
460 luaK_dischargevars(fs, e);
461 freeexp(fs, e);
462 luaK_reserveregs(fs, 1);
463 exp2reg(fs, e, fs->freereg - 1);
467 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
468 luaK_dischargevars(fs, e);
469 if (e->k == VNONRELOC) {
470 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
471 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
472 exp2reg(fs, e, e->u.s.info); /* put value on it */
473 return e->u.s.info;
476 luaK_exp2nextreg(fs, e); /* default */
477 return e->u.s.info;
481 void luaK_exp2val (FuncState *fs, expdesc *e) {
482 if (hasjumps(e))
483 luaK_exp2anyreg(fs, e);
484 else
485 luaK_dischargevars(fs, e);
489 int luaK_exp2RK (FuncState *fs, expdesc *e) {
490 luaK_exp2val(fs, e);
491 switch (e->k) {
492 #ifdef LUA_TINT
493 case VKINT:
494 #endif
495 #ifdef LNUM_COMPLEX
496 case VKNUM2:
497 #endif
498 case VKNUM:
499 case VTRUE:
500 case VFALSE:
501 case VNIL: {
502 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
503 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
504 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
505 #ifdef LUA_TINT
506 (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) :
507 #endif
508 #ifdef LNUM_COMPLEX
509 (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) :
510 #endif
511 boolK(fs, (e->k == VTRUE));
512 e->k = VK;
513 return RKASK(e->u.s.info);
515 else break;
517 case VK: {
518 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
519 return RKASK(e->u.s.info);
520 else break;
522 default: break;
524 /* not a constant in the right range: put it in a register */
525 return luaK_exp2anyreg(fs, e);
529 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
530 switch (var->k) {
531 case VLOCAL: {
532 freeexp(fs, ex);
533 exp2reg(fs, ex, var->u.s.info);
534 return;
536 case VUPVAL: {
537 int e = luaK_exp2anyreg(fs, ex);
538 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
539 break;
541 case VGLOBAL: {
542 int e = luaK_exp2anyreg(fs, ex);
543 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
544 break;
546 case VINDEXED: {
547 int e = luaK_exp2RK(fs, ex);
548 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
549 break;
551 default: {
552 lua_assert(0); /* invalid var kind to store */
553 break;
556 freeexp(fs, ex);
560 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
561 int func;
562 luaK_exp2anyreg(fs, e);
563 freeexp(fs, e);
564 func = fs->freereg;
565 luaK_reserveregs(fs, 2);
566 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
567 freeexp(fs, key);
568 e->u.s.info = func;
569 e->k = VNONRELOC;
573 static void invertjump (FuncState *fs, expdesc *e) {
574 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
575 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
576 GET_OPCODE(*pc) != OP_TEST);
577 SETARG_A(*pc, !(GETARG_A(*pc)));
581 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
582 if (e->k == VRELOCABLE) {
583 Instruction ie = getcode(fs, e);
584 if (GET_OPCODE(ie) == OP_NOT) {
585 fs->pc--; /* remove previous OP_NOT */
586 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
588 /* else go through */
590 discharge2anyreg(fs, e);
591 freeexp(fs, e);
592 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
596 void luaK_goiftrue (FuncState *fs, expdesc *e) {
597 int pc; /* pc of last jump */
598 luaK_dischargevars(fs, e);
599 switch (e->k) {
600 #ifdef LNUM_COMPLEX
601 case VKNUM2:
602 #endif
603 #ifdef LUA_TINT
604 case VKINT:
605 #endif
606 case VK: case VKNUM: case VTRUE: {
607 pc = NO_JUMP; /* always true; do nothing */
608 break;
610 case VFALSE: {
611 pc = luaK_jump(fs); /* always jump */
612 break;
614 case VJMP: {
615 invertjump(fs, e);
616 pc = e->u.s.info;
617 break;
619 default: {
620 pc = jumponcond(fs, e, 0);
621 break;
624 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
625 luaK_patchtohere(fs, e->t);
626 e->t = NO_JUMP;
630 static void luaK_goiffalse (FuncState *fs, expdesc *e) {
631 int pc; /* pc of last jump */
632 luaK_dischargevars(fs, e);
633 switch (e->k) {
634 case VNIL: case VFALSE: {
635 pc = NO_JUMP; /* always false; do nothing */
636 break;
638 case VTRUE: {
639 pc = luaK_jump(fs); /* always jump */
640 break;
642 case VJMP: {
643 pc = e->u.s.info;
644 break;
646 default: {
647 pc = jumponcond(fs, e, 1);
648 break;
651 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
652 luaK_patchtohere(fs, e->f);
653 e->f = NO_JUMP;
657 static void codenot (FuncState *fs, expdesc *e) {
658 luaK_dischargevars(fs, e);
659 switch (e->k) {
660 case VNIL: case VFALSE: {
661 e->k = VTRUE;
662 break;
664 #ifdef LNUM_COMPLEX
665 case VKNUM2:
666 #endif
667 #ifdef LUA_TINT
668 case VKINT:
669 #endif
670 case VK: case VKNUM: case VTRUE: {
671 e->k = VFALSE;
672 break;
674 case VJMP: {
675 invertjump(fs, e);
676 break;
678 case VRELOCABLE:
679 case VNONRELOC: {
680 discharge2anyreg(fs, e);
681 freeexp(fs, e);
682 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
683 e->k = VRELOCABLE;
684 break;
686 default: {
687 lua_assert(0); /* cannot happen */
688 break;
691 /* interchange true and false lists */
692 { int temp = e->f; e->f = e->t; e->t = temp; }
693 removevalues(fs, e->f);
694 removevalues(fs, e->t);
698 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
699 t->u.s.aux = luaK_exp2RK(fs, k);
700 t->k = VINDEXED;
704 static lu_bool constfolding (OpCode op, expdesc *e1, expdesc *e2) {
705 lua_Number v1, v2, r;
706 int vkres= VKNUM;
707 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
709 /* real and imaginary parts don't mix. */
710 #ifdef LNUM_COMPLEX
711 if (e1->k == VKNUM2) {
712 if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0;
713 vkres= VKNUM2; }
714 else if (e2->k == VKNUM2) { return 0; }
715 #endif
716 #ifdef LUA_TINT
717 if ((e1->k == VKINT) && (e2->k == VKINT)) {
718 lua_Integer i1= e1->u.ival, i2= e2->u.ival;
719 lua_Integer rr;
720 lu_bool done= 0;
721 /* Integer/integer calculations (maybe end up producing floating point) */
722 switch (op) {
723 case OP_ADD: done= try_addint( &rr, i1, i2 ); break;
724 case OP_SUB: done= try_subint( &rr, i1, i2 ); break;
725 case OP_MUL: done= try_mulint( &rr, i1, i2 ); break;
726 case OP_DIV: done= try_divint( &rr, i1, i2 ); break;
727 case OP_MOD: done= try_modint( &rr, i1, i2 ); break;
728 case OP_POW: done= try_powint( &rr, i1, i2 ); break;
729 case OP_UNM: done= try_unmint( &rr, i1 ); break;
730 default: done= 0; break;
732 if (done) {
733 e1->u.ival = rr; /* We remained within integer range, and accuracy! */
734 return 1;
737 v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval;
738 v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval;
739 #else
740 v1 = e1->u.nval;
741 v2 = e2->u.nval;
742 #endif
743 switch (op) {
744 case OP_ADD: r = luai_numadd(v1, v2); break;
745 case OP_SUB: r = luai_numsub(v1, v2); break;
746 case OP_MUL:
747 #ifdef LNUM_COMPLEX
748 if (vkres==VKNUM2) return 0; /* leave to runtime (could do here, but not worth it?) */
749 #endif
750 r = luai_nummul(v1, v2); break;
751 case OP_DIV:
752 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
753 #ifdef LNUM_COMPLEX
754 if (vkres==VKNUM2) return 0; /* leave to runtime */
755 #endif
756 r = luai_numdiv(v1, v2); break;
757 case OP_MOD:
758 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
759 #ifdef LNUM_COMPLEX
760 if (vkres==VKNUM2) return 0; /* leave to runtime */
761 #endif
762 r = luai_nummod(v1, v2); break;
763 case OP_POW:
764 #ifdef LNUM_COMPLEX
765 if (vkres==VKNUM2) return 0; /* leave to runtime */
766 #endif
767 r = luai_numpow(v1, v2); break;
768 case OP_UNM: r = luai_numunm(v1); break;
769 case OP_LEN: return 0; /* no constant folding for 'len' */
770 default: lua_assert(0); r = 0; break;
772 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
773 e1->k = (expkind) vkres; // (Visual C++ 2005 needs the cast, on 64-bit ints)
774 e1->u.nval = r;
775 return 1;
779 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
780 if (constfolding(op, e1, e2))
781 return;
782 else {
783 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
784 int o1 = luaK_exp2RK(fs, e1);
785 if (o1 > o2) {
786 freeexp(fs, e1);
787 freeexp(fs, e2);
789 else {
790 freeexp(fs, e2);
791 freeexp(fs, e1);
793 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
794 e1->k = VRELOCABLE;
799 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
800 expdesc *e2) {
801 int o1 = luaK_exp2RK(fs, e1);
802 int o2 = luaK_exp2RK(fs, e2);
803 freeexp(fs, e2);
804 freeexp(fs, e1);
805 if (cond == 0 && op != OP_EQ) {
806 int temp; /* exchange args to replace by `<' or `<=' */
807 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
808 cond = 1;
810 e1->u.s.info = condjump(fs, op, cond, o1, o2);
811 e1->k = VJMP;
815 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
816 /* Q: is the 'e2' really needed; couldn't we use 'e' for both params like
817 * when calling 'Arith()' at lvm.c */
818 expdesc e2;
819 e2.t = e2.f = NO_JUMP;
820 #ifdef LUA_TINT
821 e2.k = VKINT; e2.u.ival = 0;
822 #else
823 e2.k = VKNUM; e2.u.nval = 0;
824 #endif
825 switch (op) {
826 case OPR_MINUS: {
827 if (e->k == VK)
828 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
829 codearith(fs, OP_UNM, e, &e2);
830 break;
832 case OPR_NOT: codenot(fs, e); break;
833 case OPR_LEN: {
834 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
835 codearith(fs, OP_LEN, e, &e2);
836 break;
838 default: lua_assert(0);
843 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
844 switch (op) {
845 case OPR_AND: {
846 luaK_goiftrue(fs, v);
847 break;
849 case OPR_OR: {
850 luaK_goiffalse(fs, v);
851 break;
853 case OPR_CONCAT: {
854 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
855 break;
857 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
858 case OPR_MOD: case OPR_POW: {
859 if (!isnumeral(v)) luaK_exp2RK(fs, v);
860 break;
862 default: {
863 luaK_exp2RK(fs, v);
864 break;
870 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
871 switch (op) {
872 case OPR_AND: {
873 lua_assert(e1->t == NO_JUMP); /* list must be closed */
874 luaK_dischargevars(fs, e2);
875 luaK_concat(fs, &e2->f, e1->f);
876 *e1 = *e2;
877 break;
879 case OPR_OR: {
880 lua_assert(e1->f == NO_JUMP); /* list must be closed */
881 luaK_dischargevars(fs, e2);
882 luaK_concat(fs, &e2->t, e1->t);
883 *e1 = *e2;
884 break;
886 case OPR_CONCAT: {
887 luaK_exp2val(fs, e2);
888 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
889 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
890 freeexp(fs, e1);
891 SETARG_B(getcode(fs, e2), e1->u.s.info);
892 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
894 else {
895 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
896 codearith(fs, OP_CONCAT, e1, e2);
898 break;
900 case OPR_ADD:
901 codearith(fs, OP_ADD, e1, e2); break;
902 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
903 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
904 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
905 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
906 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
907 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
908 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
909 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
910 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
911 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
912 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
913 default: lua_assert(0);
918 void luaK_fixline (FuncState *fs, int line) {
919 fs->f->lineinfo[fs->pc - 1] = line;
923 static int luaK_code (FuncState *fs, Instruction i, int line) {
924 Proto *f = fs->f;
925 dischargejpc(fs); /* `pc' will change */
926 /* put new instruction in code array */
927 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
928 MAX_INT, "code size overflow");
929 f->code[fs->pc] = i;
930 /* save corresponding line information */
931 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
932 MAX_INT, "code size overflow");
933 f->lineinfo[fs->pc] = line;
934 return fs->pc++;
938 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
939 lua_assert(getOpMode(o) == iABC);
940 lua_assert(getBMode(o) != OpArgN || b == 0);
941 lua_assert(getCMode(o) != OpArgN || c == 0);
942 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
946 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
947 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
948 lua_assert(getCMode(o) == OpArgN);
949 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
953 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
954 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
955 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
956 lua_assert(tostore != 0);
957 if (c <= MAXARG_C)
958 luaK_codeABC(fs, OP_SETLIST, base, b, c);
959 else {
960 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
961 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
963 fs->freereg = base + 1; /* free registers with list values */