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