Fix hang/crash when requesting ZPOOL with incorrect backing device
[grub2/phcoder.git] / script / lua / lcode.c
blob64f726b481a7ec904f2ecfc71094e9cabc8b2458
1 /*
2 ** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
3 ** Code generator for Lua
4 ** See Copyright Notice in lua.h
5 */
7 #if 0
8 #include <stdlib.h>
9 #endif
11 #define lcode_c
12 #define LUA_CORE
14 #include "lua.h"
16 #include "lcode.h"
17 #include "ldebug.h"
18 #include "ldo.h"
19 #include "lgc.h"
20 #include "llex.h"
21 #include "lmem.h"
22 #include "lobject.h"
23 #include "lopcodes.h"
24 #include "lparser.h"
25 #include "ltable.h"
28 #define hasjumps(e) ((e)->t != (e)->f)
31 static int isnumeral(expdesc *e) {
32 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
36 void luaK_nil (FuncState *fs, int from, int n) {
37 Instruction *previous;
38 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
39 if (fs->pc == 0) { /* function start? */
40 if (from >= fs->nactvar)
41 return; /* positions are already clean */
43 else {
44 previous = &fs->f->code[fs->pc-1];
45 if (GET_OPCODE(*previous) == OP_LOADNIL) {
46 int pfrom = GETARG_A(*previous);
47 int pto = GETARG_B(*previous);
48 if (pfrom <= from && from <= pto+1) { /* can connect both? */
49 if (from+n-1 > pto)
50 SETARG_B(*previous, from+n-1);
51 return;
56 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
60 int luaK_jump (FuncState *fs) {
61 int jpc = fs->jpc; /* save list of jumps to here */
62 int j;
63 fs->jpc = NO_JUMP;
64 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
65 luaK_concat(fs, &j, jpc); /* keep them on hold */
66 return j;
70 void luaK_ret (FuncState *fs, int first, int nret) {
71 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
75 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
76 luaK_codeABC(fs, op, A, B, C);
77 return luaK_jump(fs);
81 static void fixjump (FuncState *fs, int pc, int dest) {
82 Instruction *jmp = &fs->f->code[pc];
83 int offset = dest-(pc+1);
84 lua_assert(dest != NO_JUMP);
85 if (abs(offset) > MAXARG_sBx)
86 luaX_syntaxerror(fs->ls, "control structure too long");
87 SETARG_sBx(*jmp, offset);
92 ** returns current `pc' and marks it as a jump target (to avoid wrong
93 ** optimizations with consecutive instructions not in the same basic block).
95 int luaK_getlabel (FuncState *fs) {
96 fs->lasttarget = fs->pc;
97 return fs->pc;
101 static int getjump (FuncState *fs, int pc) {
102 int offset = GETARG_sBx(fs->f->code[pc]);
103 if (offset == NO_JUMP) /* point to itself represents end of list */
104 return NO_JUMP; /* end of list */
105 else
106 return (pc+1)+offset; /* turn offset into absolute position */
110 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
111 Instruction *pi = &fs->f->code[pc];
112 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
113 return pi-1;
114 else
115 return pi;
120 ** check whether list has any jump that do not produce a value
121 ** (or produce an inverted value)
123 static int need_value (FuncState *fs, int list) {
124 for (; list != NO_JUMP; list = getjump(fs, list)) {
125 Instruction i = *getjumpcontrol(fs, list);
126 if (GET_OPCODE(i) != OP_TESTSET) return 1;
128 return 0; /* not found */
132 static int patchtestreg (FuncState *fs, int node, int reg) {
133 Instruction *i = getjumpcontrol(fs, node);
134 if (GET_OPCODE(*i) != OP_TESTSET)
135 return 0; /* cannot patch other instructions */
136 if (reg != NO_REG && reg != GETARG_B(*i))
137 SETARG_A(*i, reg);
138 else /* no register to put value or register already has the value */
139 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
141 return 1;
145 static void removevalues (FuncState *fs, int list) {
146 for (; list != NO_JUMP; list = getjump(fs, list))
147 patchtestreg(fs, list, NO_REG);
151 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
152 int dtarget) {
153 while (list != NO_JUMP) {
154 int next = getjump(fs, list);
155 if (patchtestreg(fs, list, reg))
156 fixjump(fs, list, vtarget);
157 else
158 fixjump(fs, list, dtarget); /* jump to default target */
159 list = next;
164 static void dischargejpc (FuncState *fs) {
165 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
166 fs->jpc = NO_JUMP;
170 void luaK_patchlist (FuncState *fs, int list, int target) {
171 if (target == fs->pc)
172 luaK_patchtohere(fs, list);
173 else {
174 lua_assert(target < fs->pc);
175 patchlistaux(fs, list, target, NO_REG, target);
180 void luaK_patchtohere (FuncState *fs, int list) {
181 luaK_getlabel(fs);
182 luaK_concat(fs, &fs->jpc, list);
186 void luaK_concat (FuncState *fs, int *l1, int l2) {
187 if (l2 == NO_JUMP) return;
188 else if (*l1 == NO_JUMP)
189 *l1 = l2;
190 else {
191 int list = *l1;
192 int next;
193 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
194 list = next;
195 fixjump(fs, list, l2);
200 void luaK_checkstack (FuncState *fs, int n) {
201 int newstack = fs->freereg + n;
202 if (newstack > fs->f->maxstacksize) {
203 if (newstack >= MAXSTACK)
204 luaX_syntaxerror(fs->ls, "function or expression too complex");
205 fs->f->maxstacksize = cast_byte(newstack);
210 void luaK_reserveregs (FuncState *fs, int n) {
211 luaK_checkstack(fs, n);
212 fs->freereg += n;
216 static void freereg (FuncState *fs, int reg) {
217 if (!ISK(reg) && reg >= fs->nactvar) {
218 fs->freereg--;
219 lua_assert(reg == fs->freereg);
224 static void freeexp (FuncState *fs, expdesc *e) {
225 if (e->k == VNONRELOC)
226 freereg(fs, e->u.s.info);
230 static int addk (FuncState *fs, TValue *k, TValue *v) {
231 lua_State *L = fs->L;
232 TValue *idx = luaH_set(L, fs->h, k);
233 Proto *f = fs->f;
234 int oldsize = f->sizek;
235 if (ttisnumber(idx)) {
236 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
237 return cast_int(nvalue(idx));
239 else { /* constant not found; create a new entry */
240 setnvalue(idx, cast_num(fs->nk));
241 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
242 MAXARG_Bx, "constant table overflow");
243 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
244 setobj(L, &f->k[fs->nk], v);
245 luaC_barrier(L, f, v);
246 return fs->nk++;
251 int luaK_stringK (FuncState *fs, TString *s) {
252 TValue o;
253 setsvalue(fs->L, &o, s);
254 return addk(fs, &o, &o);
258 int luaK_numberK (FuncState *fs, lua_Number r) {
259 TValue o;
260 setnvalue(&o, r);
261 return addk(fs, &o, &o);
265 static int boolK (FuncState *fs, int b) {
266 TValue o;
267 setbvalue(&o, b);
268 return addk(fs, &o, &o);
272 static int nilK (FuncState *fs) {
273 TValue k, v;
274 setnilvalue(&v);
275 /* cannot use nil as key; instead use table itself to represent nil */
276 sethvalue(fs->L, &k, fs->h);
277 return addk(fs, &k, &v);
281 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
282 if (e->k == VCALL) { /* expression is an open function call? */
283 SETARG_C(getcode(fs, e), nresults+1);
285 else if (e->k == VVARARG) {
286 SETARG_B(getcode(fs, e), nresults+1);
287 SETARG_A(getcode(fs, e), fs->freereg);
288 luaK_reserveregs(fs, 1);
293 void luaK_setoneret (FuncState *fs, expdesc *e) {
294 if (e->k == VCALL) { /* expression is an open function call? */
295 e->k = VNONRELOC;
296 e->u.s.info = GETARG_A(getcode(fs, e));
298 else if (e->k == VVARARG) {
299 SETARG_B(getcode(fs, e), 2);
300 e->k = VRELOCABLE; /* can relocate its simple result */
305 void luaK_dischargevars (FuncState *fs, expdesc *e) {
306 switch (e->k) {
307 case VLOCAL: {
308 e->k = VNONRELOC;
309 break;
311 case VUPVAL: {
312 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
313 e->k = VRELOCABLE;
314 break;
316 case VGLOBAL: {
317 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
318 e->k = VRELOCABLE;
319 break;
321 case VINDEXED: {
322 freereg(fs, e->u.s.aux);
323 freereg(fs, e->u.s.info);
324 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
325 e->k = VRELOCABLE;
326 break;
328 case VVARARG:
329 case VCALL: {
330 luaK_setoneret(fs, e);
331 break;
333 default: break; /* there is one value available (somewhere) */
338 static int code_label (FuncState *fs, int A, int b, int jump) {
339 luaK_getlabel(fs); /* those instructions may be jump targets */
340 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
344 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
345 luaK_dischargevars(fs, e);
346 switch (e->k) {
347 case VNIL: {
348 luaK_nil(fs, reg, 1);
349 break;
351 case VFALSE: case VTRUE: {
352 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
353 break;
355 case VK: {
356 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
357 break;
359 case VKNUM: {
360 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
361 break;
363 case VRELOCABLE: {
364 Instruction *pc = &getcode(fs, e);
365 SETARG_A(*pc, reg);
366 break;
368 case VNONRELOC: {
369 if (reg != e->u.s.info)
370 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
371 break;
373 default: {
374 lua_assert(e->k == VVOID || e->k == VJMP);
375 return; /* nothing to do... */
378 e->u.s.info = reg;
379 e->k = VNONRELOC;
383 static void discharge2anyreg (FuncState *fs, expdesc *e) {
384 if (e->k != VNONRELOC) {
385 luaK_reserveregs(fs, 1);
386 discharge2reg(fs, e, fs->freereg-1);
391 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
392 discharge2reg(fs, e, reg);
393 if (e->k == VJMP)
394 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
395 if (hasjumps(e)) {
396 int final; /* position after whole expression */
397 int p_f = NO_JUMP; /* position of an eventual LOAD false */
398 int p_t = NO_JUMP; /* position of an eventual LOAD true */
399 if (need_value(fs, e->t) || need_value(fs, e->f)) {
400 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
401 p_f = code_label(fs, reg, 0, 1);
402 p_t = code_label(fs, reg, 1, 0);
403 luaK_patchtohere(fs, fj);
405 final = luaK_getlabel(fs);
406 patchlistaux(fs, e->f, final, reg, p_f);
407 patchlistaux(fs, e->t, final, reg, p_t);
409 e->f = e->t = NO_JUMP;
410 e->u.s.info = reg;
411 e->k = VNONRELOC;
415 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
416 luaK_dischargevars(fs, e);
417 freeexp(fs, e);
418 luaK_reserveregs(fs, 1);
419 exp2reg(fs, e, fs->freereg - 1);
423 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
424 luaK_dischargevars(fs, e);
425 if (e->k == VNONRELOC) {
426 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
427 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
428 exp2reg(fs, e, e->u.s.info); /* put value on it */
429 return e->u.s.info;
432 luaK_exp2nextreg(fs, e); /* default */
433 return e->u.s.info;
437 void luaK_exp2val (FuncState *fs, expdesc *e) {
438 if (hasjumps(e))
439 luaK_exp2anyreg(fs, e);
440 else
441 luaK_dischargevars(fs, e);
445 int luaK_exp2RK (FuncState *fs, expdesc *e) {
446 luaK_exp2val(fs, e);
447 switch (e->k) {
448 case VKNUM:
449 case VTRUE:
450 case VFALSE:
451 case VNIL: {
452 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
453 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
454 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
455 boolK(fs, (e->k == VTRUE));
456 e->k = VK;
457 return RKASK(e->u.s.info);
459 else break;
461 case VK: {
462 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
463 return RKASK(e->u.s.info);
464 else break;
466 default: break;
468 /* not a constant in the right range: put it in a register */
469 return luaK_exp2anyreg(fs, e);
473 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
474 switch (var->k) {
475 case VLOCAL: {
476 freeexp(fs, ex);
477 exp2reg(fs, ex, var->u.s.info);
478 return;
480 case VUPVAL: {
481 int e = luaK_exp2anyreg(fs, ex);
482 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
483 break;
485 case VGLOBAL: {
486 int e = luaK_exp2anyreg(fs, ex);
487 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
488 break;
490 case VINDEXED: {
491 int e = luaK_exp2RK(fs, ex);
492 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
493 break;
495 default: {
496 lua_assert(0); /* invalid var kind to store */
497 break;
500 freeexp(fs, ex);
504 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
505 int func;
506 luaK_exp2anyreg(fs, e);
507 freeexp(fs, e);
508 func = fs->freereg;
509 luaK_reserveregs(fs, 2);
510 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
511 freeexp(fs, key);
512 e->u.s.info = func;
513 e->k = VNONRELOC;
517 static void invertjump (FuncState *fs, expdesc *e) {
518 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
519 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
520 GET_OPCODE(*pc) != OP_TEST);
521 SETARG_A(*pc, !(GETARG_A(*pc)));
525 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
526 if (e->k == VRELOCABLE) {
527 Instruction ie = getcode(fs, e);
528 if (GET_OPCODE(ie) == OP_NOT) {
529 fs->pc--; /* remove previous OP_NOT */
530 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
532 /* else go through */
534 discharge2anyreg(fs, e);
535 freeexp(fs, e);
536 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
540 void luaK_goiftrue (FuncState *fs, expdesc *e) {
541 int pc; /* pc of last jump */
542 luaK_dischargevars(fs, e);
543 switch (e->k) {
544 case VK: case VKNUM: case VTRUE: {
545 pc = NO_JUMP; /* always true; do nothing */
546 break;
548 case VFALSE: {
549 pc = luaK_jump(fs); /* always jump */
550 break;
552 case VJMP: {
553 invertjump(fs, e);
554 pc = e->u.s.info;
555 break;
557 default: {
558 pc = jumponcond(fs, e, 0);
559 break;
562 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
563 luaK_patchtohere(fs, e->t);
564 e->t = NO_JUMP;
568 static void luaK_goiffalse (FuncState *fs, expdesc *e) {
569 int pc; /* pc of last jump */
570 luaK_dischargevars(fs, e);
571 switch (e->k) {
572 case VNIL: case VFALSE: {
573 pc = NO_JUMP; /* always false; do nothing */
574 break;
576 case VTRUE: {
577 pc = luaK_jump(fs); /* always jump */
578 break;
580 case VJMP: {
581 pc = e->u.s.info;
582 break;
584 default: {
585 pc = jumponcond(fs, e, 1);
586 break;
589 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
590 luaK_patchtohere(fs, e->f);
591 e->f = NO_JUMP;
595 static void codenot (FuncState *fs, expdesc *e) {
596 luaK_dischargevars(fs, e);
597 switch (e->k) {
598 case VNIL: case VFALSE: {
599 e->k = VTRUE;
600 break;
602 case VK: case VKNUM: case VTRUE: {
603 e->k = VFALSE;
604 break;
606 case VJMP: {
607 invertjump(fs, e);
608 break;
610 case VRELOCABLE:
611 case VNONRELOC: {
612 discharge2anyreg(fs, e);
613 freeexp(fs, e);
614 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
615 e->k = VRELOCABLE;
616 break;
618 default: {
619 lua_assert(0); /* cannot happen */
620 break;
623 /* interchange true and false lists */
624 { int temp = e->f; e->f = e->t; e->t = temp; }
625 removevalues(fs, e->f);
626 removevalues(fs, e->t);
630 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
631 t->u.s.aux = luaK_exp2RK(fs, k);
632 t->k = VINDEXED;
636 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
637 lua_Number v1, v2, r;
638 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
639 v1 = e1->u.nval;
640 v2 = e2->u.nval;
641 switch (op) {
642 case OP_ADD: r = luai_numadd(v1, v2); break;
643 case OP_SUB: r = luai_numsub(v1, v2); break;
644 case OP_MUL: r = luai_nummul(v1, v2); break;
645 case OP_DIV:
646 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
647 r = luai_numdiv(v1, v2); break;
648 case OP_MOD:
649 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
650 r = luai_nummod(v1, v2); break;
651 case OP_POW: r = luai_numpow(v1, v2); break;
652 case OP_UNM: r = luai_numunm(v1); break;
653 case OP_LEN: return 0; /* no constant folding for 'len' */
654 default: lua_assert(0); r = 0; break;
656 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
657 e1->u.nval = r;
658 return 1;
662 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
663 if (constfolding(op, e1, e2))
664 return;
665 else {
666 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
667 int o1 = luaK_exp2RK(fs, e1);
668 if (o1 > o2) {
669 freeexp(fs, e1);
670 freeexp(fs, e2);
672 else {
673 freeexp(fs, e2);
674 freeexp(fs, e1);
676 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
677 e1->k = VRELOCABLE;
682 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
683 expdesc *e2) {
684 int o1 = luaK_exp2RK(fs, e1);
685 int o2 = luaK_exp2RK(fs, e2);
686 freeexp(fs, e2);
687 freeexp(fs, e1);
688 if (cond == 0 && op != OP_EQ) {
689 int temp; /* exchange args to replace by `<' or `<=' */
690 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
691 cond = 1;
693 e1->u.s.info = condjump(fs, op, cond, o1, o2);
694 e1->k = VJMP;
698 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
699 expdesc e2;
700 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
701 switch (op) {
702 case OPR_MINUS: {
703 if (!isnumeral(e))
704 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
705 codearith(fs, OP_UNM, e, &e2);
706 break;
708 case OPR_NOT: codenot(fs, e); break;
709 case OPR_LEN: {
710 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
711 codearith(fs, OP_LEN, e, &e2);
712 break;
714 default: lua_assert(0);
719 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
720 switch (op) {
721 case OPR_AND: {
722 luaK_goiftrue(fs, v);
723 break;
725 case OPR_OR: {
726 luaK_goiffalse(fs, v);
727 break;
729 case OPR_CONCAT: {
730 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
731 break;
733 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
734 case OPR_MOD: case OPR_POW: {
735 if (!isnumeral(v)) luaK_exp2RK(fs, v);
736 break;
738 default: {
739 luaK_exp2RK(fs, v);
740 break;
746 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
747 switch (op) {
748 case OPR_AND: {
749 lua_assert(e1->t == NO_JUMP); /* list must be closed */
750 luaK_dischargevars(fs, e2);
751 luaK_concat(fs, &e2->f, e1->f);
752 #if 0
753 *e1 = *e2;
754 #else
755 memcpy (e1, e2, sizeof (*e1));
756 #endif
757 break;
759 case OPR_OR: {
760 lua_assert(e1->f == NO_JUMP); /* list must be closed */
761 luaK_dischargevars(fs, e2);
762 luaK_concat(fs, &e2->t, e1->t);
763 #if 0
764 *e1 = *e2;
765 #else
766 memcpy (e1, e2, sizeof (*e1));
767 #endif
768 break;
770 case OPR_CONCAT: {
771 luaK_exp2val(fs, e2);
772 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
773 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
774 freeexp(fs, e1);
775 SETARG_B(getcode(fs, e2), e1->u.s.info);
776 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
778 else {
779 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
780 codearith(fs, OP_CONCAT, e1, e2);
782 break;
784 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
785 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
786 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
787 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
788 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
789 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
790 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
791 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
792 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
793 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
794 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
795 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
796 default: lua_assert(0);
801 void luaK_fixline (FuncState *fs, int line) {
802 fs->f->lineinfo[fs->pc - 1] = line;
806 static int luaK_code (FuncState *fs, Instruction i, int line) {
807 Proto *f = fs->f;
808 dischargejpc(fs); /* `pc' will change */
809 /* put new instruction in code array */
810 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
811 MAX_INT, "code size overflow");
812 f->code[fs->pc] = i;
813 /* save corresponding line information */
814 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
815 MAX_INT, "code size overflow");
816 f->lineinfo[fs->pc] = line;
817 return fs->pc++;
821 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
822 lua_assert(getOpMode(o) == iABC);
823 lua_assert(getBMode(o) != OpArgN || b == 0);
824 lua_assert(getCMode(o) != OpArgN || c == 0);
825 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
829 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
830 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
831 lua_assert(getCMode(o) == OpArgN);
832 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
836 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
837 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
838 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
839 lua_assert(tostore != 0);
840 if (c <= MAXARG_C)
841 luaK_codeABC(fs, OP_SETLIST, base, b, c);
842 else {
843 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
844 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
846 fs->freereg = base + 1; /* free registers with list values */