tools/llvm: Do not build with symbols
[minix3.git] / external / mit / lua / dist / src / lcode.c
blobe697e60be17faa30c98476d8f34f2bb26e839857
1 /* $NetBSD: lcode.c,v 1.1.1.2 2012/03/15 00:08:11 alnsn Exp $ */
3 /*
4 ** $Id: lcode.c,v 1.1.1.2 2012/03/15 00:08:11 alnsn Exp $
5 ** Code generator for Lua
6 ** See Copyright Notice in lua.h
7 */
10 #include <stdlib.h>
12 #define lcode_c
13 #define LUA_CORE
15 #include "lua.h"
17 #include "lcode.h"
18 #include "ldebug.h"
19 #include "ldo.h"
20 #include "lgc.h"
21 #include "llex.h"
22 #include "lmem.h"
23 #include "lobject.h"
24 #include "lopcodes.h"
25 #include "lparser.h"
26 #include "ltable.h"
29 #define hasjumps(e) ((e)->t != (e)->f)
32 static int isnumeral(expdesc *e) {
33 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
37 void luaK_nil (FuncState *fs, int from, int n) {
38 Instruction *previous;
39 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
40 if (fs->pc == 0) { /* function start? */
41 if (from >= fs->nactvar)
42 return; /* positions are already clean */
44 else {
45 previous = &fs->f->code[fs->pc-1];
46 if (GET_OPCODE(*previous) == OP_LOADNIL) {
47 int pfrom = GETARG_A(*previous);
48 int pto = GETARG_B(*previous);
49 if (pfrom <= from && from <= pto+1) { /* can connect both? */
50 if (from+n-1 > pto)
51 SETARG_B(*previous, from+n-1);
52 return;
57 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
61 int luaK_jump (FuncState *fs) {
62 int jpc = fs->jpc; /* save list of jumps to here */
63 int j;
64 fs->jpc = NO_JUMP;
65 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
66 luaK_concat(fs, &j, jpc); /* keep them on hold */
67 return j;
71 void luaK_ret (FuncState *fs, int first, int nret) {
72 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
76 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
77 luaK_codeABC(fs, op, A, B, C);
78 return luaK_jump(fs);
82 static void fixjump (FuncState *fs, int pc, int dest) {
83 Instruction *jmp = &fs->f->code[pc];
84 int offset = dest-(pc+1);
85 lua_assert(dest != NO_JUMP);
86 if (abs(offset) > MAXARG_sBx)
87 luaX_syntaxerror(fs->ls, "control structure too long");
88 SETARG_sBx(*jmp, offset);
93 ** returns current `pc' and marks it as a jump target (to avoid wrong
94 ** optimizations with consecutive instructions not in the same basic block).
96 int luaK_getlabel (FuncState *fs) {
97 fs->lasttarget = fs->pc;
98 return fs->pc;
102 static int getjump (FuncState *fs, int pc) {
103 int offset = GETARG_sBx(fs->f->code[pc]);
104 if (offset == NO_JUMP) /* point to itself represents end of list */
105 return NO_JUMP; /* end of list */
106 else
107 return (pc+1)+offset; /* turn offset into absolute position */
111 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
112 Instruction *pi = &fs->f->code[pc];
113 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
114 return pi-1;
115 else
116 return pi;
121 ** check whether list has any jump that do not produce a value
122 ** (or produce an inverted value)
124 static int need_value (FuncState *fs, int list) {
125 for (; list != NO_JUMP; list = getjump(fs, list)) {
126 Instruction i = *getjumpcontrol(fs, list);
127 if (GET_OPCODE(i) != OP_TESTSET) return 1;
129 return 0; /* not found */
133 static int patchtestreg (FuncState *fs, int node, int reg) {
134 Instruction *i = getjumpcontrol(fs, node);
135 if (GET_OPCODE(*i) != OP_TESTSET)
136 return 0; /* cannot patch other instructions */
137 if (reg != NO_REG && reg != GETARG_B(*i))
138 SETARG_A(*i, reg);
139 else /* no register to put value or register already has the value */
140 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
142 return 1;
146 static void removevalues (FuncState *fs, int list) {
147 for (; list != NO_JUMP; list = getjump(fs, list))
148 patchtestreg(fs, list, NO_REG);
152 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
153 int dtarget) {
154 while (list != NO_JUMP) {
155 int next = getjump(fs, list);
156 if (patchtestreg(fs, list, reg))
157 fixjump(fs, list, vtarget);
158 else
159 fixjump(fs, list, dtarget); /* jump to default target */
160 list = next;
165 static void dischargejpc (FuncState *fs) {
166 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
167 fs->jpc = NO_JUMP;
171 void luaK_patchlist (FuncState *fs, int list, int target) {
172 if (target == fs->pc)
173 luaK_patchtohere(fs, list);
174 else {
175 lua_assert(target < fs->pc);
176 patchlistaux(fs, list, target, NO_REG, target);
181 void luaK_patchtohere (FuncState *fs, int list) {
182 luaK_getlabel(fs);
183 luaK_concat(fs, &fs->jpc, list);
187 void luaK_concat (FuncState *fs, int *l1, int l2) {
188 if (l2 == NO_JUMP) return;
189 else if (*l1 == NO_JUMP)
190 *l1 = l2;
191 else {
192 int list = *l1;
193 int next;
194 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
195 list = next;
196 fixjump(fs, list, l2);
201 void luaK_checkstack (FuncState *fs, int n) {
202 int newstack = fs->freereg + n;
203 if (newstack > fs->f->maxstacksize) {
204 if (newstack >= MAXSTACK)
205 luaX_syntaxerror(fs->ls, "function or expression too complex");
206 fs->f->maxstacksize = cast_byte(newstack);
211 void luaK_reserveregs (FuncState *fs, int n) {
212 luaK_checkstack(fs, n);
213 fs->freereg += n;
217 static void freereg (FuncState *fs, int reg) {
218 if (!ISK(reg) && reg >= fs->nactvar) {
219 fs->freereg--;
220 lua_assert(reg == fs->freereg);
225 static void freeexp (FuncState *fs, expdesc *e) {
226 if (e->k == VNONRELOC)
227 freereg(fs, e->u.s.info);
231 static int addk (FuncState *fs, TValue *k, TValue *v) {
232 lua_State *L = fs->L;
233 TValue *idx = luaH_set(L, fs->h, k);
234 Proto *f = fs->f;
235 int oldsize = f->sizek;
236 if (ttisnumber(idx)) {
237 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
238 return cast_int(nvalue(idx));
240 else { /* constant not found; create a new entry */
241 setnvalue(idx, cast_num(fs->nk));
242 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
243 MAXARG_Bx, "constant table overflow");
244 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
245 setobj(L, &f->k[fs->nk], v);
246 luaC_barrier(L, f, v);
247 return fs->nk++;
252 int luaK_stringK (FuncState *fs, TString *s) {
253 TValue o;
254 setsvalue(fs->L, &o, s);
255 return addk(fs, &o, &o);
259 int luaK_numberK (FuncState *fs, lua_Number r) {
260 TValue o;
261 setnvalue(&o, r);
262 return addk(fs, &o, &o);
266 static int boolK (FuncState *fs, int b) {
267 TValue o;
268 setbvalue(&o, b);
269 return addk(fs, &o, &o);
273 static int nilK (FuncState *fs) {
274 TValue k, v;
275 setnilvalue(&v);
276 /* cannot use nil as key; instead use table itself to represent nil */
277 sethvalue(fs->L, &k, fs->h);
278 return addk(fs, &k, &v);
282 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
283 if (e->k == VCALL) { /* expression is an open function call? */
284 SETARG_C(getcode(fs, e), nresults+1);
286 else if (e->k == VVARARG) {
287 SETARG_B(getcode(fs, e), nresults+1);
288 SETARG_A(getcode(fs, e), fs->freereg);
289 luaK_reserveregs(fs, 1);
294 void luaK_setoneret (FuncState *fs, expdesc *e) {
295 if (e->k == VCALL) { /* expression is an open function call? */
296 e->k = VNONRELOC;
297 e->u.s.info = GETARG_A(getcode(fs, e));
299 else if (e->k == VVARARG) {
300 SETARG_B(getcode(fs, e), 2);
301 e->k = VRELOCABLE; /* can relocate its simple result */
306 void luaK_dischargevars (FuncState *fs, expdesc *e) {
307 switch (e->k) {
308 case VLOCAL: {
309 e->k = VNONRELOC;
310 break;
312 case VUPVAL: {
313 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
314 e->k = VRELOCABLE;
315 break;
317 case VGLOBAL: {
318 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
319 e->k = VRELOCABLE;
320 break;
322 case VINDEXED: {
323 freereg(fs, e->u.s.aux);
324 freereg(fs, e->u.s.info);
325 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
326 e->k = VRELOCABLE;
327 break;
329 case VVARARG:
330 case VCALL: {
331 luaK_setoneret(fs, e);
332 break;
334 default: break; /* there is one value available (somewhere) */
339 static int code_label (FuncState *fs, int A, int b, int jump) {
340 luaK_getlabel(fs); /* those instructions may be jump targets */
341 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
345 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
346 luaK_dischargevars(fs, e);
347 switch (e->k) {
348 case VNIL: {
349 luaK_nil(fs, reg, 1);
350 break;
352 case VFALSE: case VTRUE: {
353 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
354 break;
356 case VK: {
357 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
358 break;
360 case VKNUM: {
361 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
362 break;
364 case VRELOCABLE: {
365 Instruction *pc = &getcode(fs, e);
366 SETARG_A(*pc, reg);
367 break;
369 case VNONRELOC: {
370 if (reg != e->u.s.info)
371 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
372 break;
374 default: {
375 lua_assert(e->k == VVOID || e->k == VJMP);
376 return; /* nothing to do... */
379 e->u.s.info = reg;
380 e->k = VNONRELOC;
384 static void discharge2anyreg (FuncState *fs, expdesc *e) {
385 if (e->k != VNONRELOC) {
386 luaK_reserveregs(fs, 1);
387 discharge2reg(fs, e, fs->freereg-1);
392 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
393 discharge2reg(fs, e, reg);
394 if (e->k == VJMP)
395 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
396 if (hasjumps(e)) {
397 int final; /* position after whole expression */
398 int p_f = NO_JUMP; /* position of an eventual LOAD false */
399 int p_t = NO_JUMP; /* position of an eventual LOAD true */
400 if (need_value(fs, e->t) || need_value(fs, e->f)) {
401 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
402 p_f = code_label(fs, reg, 0, 1);
403 p_t = code_label(fs, reg, 1, 0);
404 luaK_patchtohere(fs, fj);
406 final = luaK_getlabel(fs);
407 patchlistaux(fs, e->f, final, reg, p_f);
408 patchlistaux(fs, e->t, final, reg, p_t);
410 e->f = e->t = NO_JUMP;
411 e->u.s.info = reg;
412 e->k = VNONRELOC;
416 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
417 luaK_dischargevars(fs, e);
418 freeexp(fs, e);
419 luaK_reserveregs(fs, 1);
420 exp2reg(fs, e, fs->freereg - 1);
424 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
425 luaK_dischargevars(fs, e);
426 if (e->k == VNONRELOC) {
427 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
428 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
429 exp2reg(fs, e, e->u.s.info); /* put value on it */
430 return e->u.s.info;
433 luaK_exp2nextreg(fs, e); /* default */
434 return e->u.s.info;
438 void luaK_exp2val (FuncState *fs, expdesc *e) {
439 if (hasjumps(e))
440 luaK_exp2anyreg(fs, e);
441 else
442 luaK_dischargevars(fs, e);
446 int luaK_exp2RK (FuncState *fs, expdesc *e) {
447 luaK_exp2val(fs, e);
448 switch (e->k) {
449 case VKNUM:
450 case VTRUE:
451 case VFALSE:
452 case VNIL: {
453 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
454 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
455 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
456 boolK(fs, (e->k == VTRUE));
457 e->k = VK;
458 return RKASK(e->u.s.info);
460 else break;
462 case VK: {
463 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
464 return RKASK(e->u.s.info);
465 else break;
467 default: break;
469 /* not a constant in the right range: put it in a register */
470 return luaK_exp2anyreg(fs, e);
474 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
475 switch (var->k) {
476 case VLOCAL: {
477 freeexp(fs, ex);
478 exp2reg(fs, ex, var->u.s.info);
479 return;
481 case VUPVAL: {
482 int e = luaK_exp2anyreg(fs, ex);
483 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
484 break;
486 case VGLOBAL: {
487 int e = luaK_exp2anyreg(fs, ex);
488 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
489 break;
491 case VINDEXED: {
492 int e = luaK_exp2RK(fs, ex);
493 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
494 break;
496 default: {
497 lua_assert(0); /* invalid var kind to store */
498 break;
501 freeexp(fs, ex);
505 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
506 int func;
507 luaK_exp2anyreg(fs, e);
508 freeexp(fs, e);
509 func = fs->freereg;
510 luaK_reserveregs(fs, 2);
511 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
512 freeexp(fs, key);
513 e->u.s.info = func;
514 e->k = VNONRELOC;
518 static void invertjump (FuncState *fs, expdesc *e) {
519 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
520 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
521 GET_OPCODE(*pc) != OP_TEST);
522 SETARG_A(*pc, !(GETARG_A(*pc)));
526 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
527 if (e->k == VRELOCABLE) {
528 Instruction ie = getcode(fs, e);
529 if (GET_OPCODE(ie) == OP_NOT) {
530 fs->pc--; /* remove previous OP_NOT */
531 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
533 /* else go through */
535 discharge2anyreg(fs, e);
536 freeexp(fs, e);
537 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
541 void luaK_goiftrue (FuncState *fs, expdesc *e) {
542 int pc; /* pc of last jump */
543 luaK_dischargevars(fs, e);
544 switch (e->k) {
545 case VK: case VKNUM: case VTRUE: {
546 pc = NO_JUMP; /* always true; do nothing */
547 break;
549 case VJMP: {
550 invertjump(fs, e);
551 pc = e->u.s.info;
552 break;
554 default: {
555 pc = jumponcond(fs, e, 0);
556 break;
559 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
560 luaK_patchtohere(fs, e->t);
561 e->t = NO_JUMP;
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;
573 case VJMP: {
574 pc = e->u.s.info;
575 break;
577 default: {
578 pc = jumponcond(fs, e, 1);
579 break;
582 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
583 luaK_patchtohere(fs, e->f);
584 e->f = NO_JUMP;
588 static void codenot (FuncState *fs, expdesc *e) {
589 luaK_dischargevars(fs, e);
590 switch (e->k) {
591 case VNIL: case VFALSE: {
592 e->k = VTRUE;
593 break;
595 case VK: case VKNUM: case VTRUE: {
596 e->k = VFALSE;
597 break;
599 case VJMP: {
600 invertjump(fs, e);
601 break;
603 case VRELOCABLE:
604 case VNONRELOC: {
605 discharge2anyreg(fs, e);
606 freeexp(fs, e);
607 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
608 e->k = VRELOCABLE;
609 break;
611 default: {
612 lua_assert(0); /* cannot happen */
613 break;
616 /* interchange true and false lists */
617 { int temp = e->f; e->f = e->t; e->t = temp; }
618 removevalues(fs, e->f);
619 removevalues(fs, e->t);
623 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
624 t->u.s.aux = luaK_exp2RK(fs, k);
625 t->k = VINDEXED;
629 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
630 lua_Number v1, v2, r;
631 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
632 v1 = e1->u.nval;
633 v2 = e2->u.nval;
634 switch (op) {
635 case OP_ADD: r = luai_numadd(v1, v2); break;
636 case OP_SUB: r = luai_numsub(v1, v2); break;
637 case OP_MUL: r = luai_nummul(v1, v2); break;
638 case OP_DIV:
639 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
640 r = luai_numdiv(v1, v2); break;
641 case OP_MOD:
642 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
643 r = luai_nummod(v1, v2); break;
644 case OP_POW: r = luai_numpow(v1, v2); break;
645 case OP_UNM: r = luai_numunm(v1); break;
646 case OP_LEN: return 0; /* no constant folding for 'len' */
647 default: lua_assert(0); r = 0; break;
649 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
650 e1->u.nval = r;
651 return 1;
655 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
656 if (constfolding(op, e1, e2))
657 return;
658 else {
659 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
660 int o1 = luaK_exp2RK(fs, e1);
661 if (o1 > o2) {
662 freeexp(fs, e1);
663 freeexp(fs, e2);
665 else {
666 freeexp(fs, e2);
667 freeexp(fs, e1);
669 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
670 e1->k = VRELOCABLE;
675 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
676 expdesc *e2) {
677 int o1 = luaK_exp2RK(fs, e1);
678 int o2 = luaK_exp2RK(fs, e2);
679 freeexp(fs, e2);
680 freeexp(fs, e1);
681 if (cond == 0 && op != OP_EQ) {
682 int temp; /* exchange args to replace by `<' or `<=' */
683 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
684 cond = 1;
686 e1->u.s.info = condjump(fs, op, cond, o1, o2);
687 e1->k = VJMP;
691 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
692 expdesc e2;
693 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
694 switch (op) {
695 case OPR_MINUS: {
696 if (!isnumeral(e))
697 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
698 codearith(fs, OP_UNM, e, &e2);
699 break;
701 case OPR_NOT: codenot(fs, e); break;
702 case OPR_LEN: {
703 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
704 codearith(fs, OP_LEN, e, &e2);
705 break;
707 default: lua_assert(0);
712 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
713 switch (op) {
714 case OPR_AND: {
715 luaK_goiftrue(fs, v);
716 break;
718 case OPR_OR: {
719 luaK_goiffalse(fs, v);
720 break;
722 case OPR_CONCAT: {
723 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
724 break;
726 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
727 case OPR_MOD: case OPR_POW: {
728 if (!isnumeral(v)) luaK_exp2RK(fs, v);
729 break;
731 default: {
732 luaK_exp2RK(fs, v);
733 break;
739 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
740 switch (op) {
741 case OPR_AND: {
742 lua_assert(e1->t == NO_JUMP); /* list must be closed */
743 luaK_dischargevars(fs, e2);
744 luaK_concat(fs, &e2->f, e1->f);
745 *e1 = *e2;
746 break;
748 case OPR_OR: {
749 lua_assert(e1->f == NO_JUMP); /* list must be closed */
750 luaK_dischargevars(fs, e2);
751 luaK_concat(fs, &e2->t, e1->t);
752 *e1 = *e2;
753 break;
755 case OPR_CONCAT: {
756 luaK_exp2val(fs, e2);
757 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
758 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
759 freeexp(fs, e1);
760 SETARG_B(getcode(fs, e2), e1->u.s.info);
761 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
763 else {
764 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
765 codearith(fs, OP_CONCAT, e1, e2);
767 break;
769 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
770 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
771 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
772 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
773 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
774 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
775 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
776 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
777 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
778 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
779 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
780 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
781 default: lua_assert(0);
786 void luaK_fixline (FuncState *fs, int line) {
787 fs->f->lineinfo[fs->pc - 1] = line;
791 static int luaK_code (FuncState *fs, Instruction i, int line) {
792 Proto *f = fs->f;
793 dischargejpc(fs); /* `pc' will change */
794 /* put new instruction in code array */
795 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
796 MAX_INT, "code size overflow");
797 f->code[fs->pc] = i;
798 /* save corresponding line information */
799 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
800 MAX_INT, "code size overflow");
801 f->lineinfo[fs->pc] = line;
802 return fs->pc++;
806 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
807 lua_assert(getOpMode(o) == iABC);
808 lua_assert(getBMode(o) != OpArgN || b == 0);
809 lua_assert(getCMode(o) != OpArgN || c == 0);
810 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
814 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
815 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
816 lua_assert(getCMode(o) == OpArgN);
817 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
821 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
822 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
823 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
824 lua_assert(tostore != 0);
825 if (c <= MAXARG_C)
826 luaK_codeABC(fs, OP_SETLIST, base, b, c);
827 else {
828 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
829 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
831 fs->freereg = base + 1; /* free registers with list values */