- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# lua/lcode.c

Go to the documentation of this file.

    00001 /*
    00002 ** $Id: lcode.c,v 1.3 2007/07/15 17:56:10 rse Exp $
    00003 ** Code generator for Lua
    00004 ** See Copyright Notice in lua.h
    00005 */
    00006
    00007
    00008 #include <stdlib.h>
    00009
    00010 #define lcode_c
    00011 #define LUA_CORE
    00012
    00013 #include "lua.h"
    00014
    00015 #include "lcode.h"
    00016 #include "ldebug.h"
    00017 #include "ldo.h"
    00018 #include "lgc.h"
    00019 #include "llex.h"
    00020 #include "lmem.h"
    00021 #include "lobject.h"
    00022 #include "lopcodes.h"
    00023 #include "lparser.h"
    00024 #include "ltable.h"
    00025
    00026
    00027 #define hasjumps(e)     ((e)->t != (e)->f)
    00028
    00029
    00030 static int isnumeral(expdesc *e) {
    00031   return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
    00032 }
    00033
    00034
    00035 void luaK_nil (FuncState *fs, int from, int n) {
    00036   Instruction *previous;
    00037   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
    00038     if (fs->pc == 0) {  /* function start? */
    00039       if (from >= fs->nactvar)
    00040         return;  /* positions are already clean */
    00041     }
    00042     else {
    00043       previous = &fs->f->code[fs->pc-1];
    00044       if (GET_OPCODE(*previous) == OP_LOADNIL) {
    00045         int pfrom = GETARG_A(*previous);
    00046         int pto = GETARG_B(*previous);
    00047         if (pfrom <= from && from <= pto+1) {  /* can connect both? */
    00048           if (from+n-1 > pto)
    00049             SETARG_B(*previous, from+n-1);
    00050           return;
    00051         }
    00052       }
    00053     }
    00054   }
    00055   luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0);  /* else no optimization */
    00056 }
    00057
    00058
    00059 int luaK_jump (FuncState *fs) {
    00060   int jpc = fs->jpc;  /* save list of jumps to here */
    00061   int j;
    00062   fs->jpc = NO_JUMP;
    00063   j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
    00064   luaK_concat(fs, &j, jpc);  /* keep them on hold */
    00065   return j;
    00066 }
    00067
    00068
    00069 void luaK_ret (FuncState *fs, int first, int nret) {
    00070   luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
    00071 }
    00072
    00073
    00074 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
    00075   luaK_codeABC(fs, op, A, B, C);
    00076   return luaK_jump(fs);
    00077 }
    00078
    00079
    00080 static void fixjump (FuncState *fs, int pc, int dest) {
    00081   Instruction *jmp = &fs->f->code[pc];
    00082   int offset = dest-(pc+1);
    00083   lua_assert(dest != NO_JUMP);
    00084   if (abs(offset) > MAXARG_sBx)
    00085     luaX_syntaxerror(fs->ls, "control structure too long");
    00086   SETARG_sBx(*jmp, offset);
    00087 }
    00088
    00089
    00090 /*
    00091 ** returns current `pc' and marks it as a jump target (to avoid wrong
    00092 ** optimizations with consecutive instructions not in the same basic block).
    00093 */
    00094 int luaK_getlabel (FuncState *fs) {
    00095   fs->lasttarget = fs->pc;
    00096   return fs->pc;
    00097 }
    00098
    00099
    00100 static int getjump (FuncState *fs, int pc) {
    00101   int offset = GETARG_sBx(fs->f->code[pc]);
    00102   if (offset == NO_JUMP)  /* point to itself represents end of list */
    00103     return NO_JUMP;  /* end of list */
    00104   else
    00105     return (pc+1)+offset;  /* turn offset into absolute position */
    00106 }
    00107
    00108
    00109 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
    00110   Instruction *pi = &fs->f->code[pc];
    00111   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
    00112     return pi-1;
    00113   else
    00114     return pi;
    00115 }
    00116
    00117
    00118 /*
    00119 ** check whether list has any jump that do not produce a value
    00120 ** (or produce an inverted value)
    00121 */
    00122 static int need_value (FuncState *fs, int list) {
    00123   for (; list != NO_JUMP; list = getjump(fs, list)) {
    00124     Instruction i = *getjumpcontrol(fs, list);
    00125     if (GET_OPCODE(i) != OP_TESTSET) return 1;
    00126   }
    00127   return 0;  /* not found */
    00128 }
    00129
    00130
    00131 static int patchtestreg (FuncState *fs, int node, int reg) {
    00132   Instruction *i = getjumpcontrol(fs, node);
    00133   if (GET_OPCODE(*i) != OP_TESTSET)
    00134     return 0;  /* cannot patch other instructions */
    00135   if (reg != NO_REG && reg != GETARG_B(*i))
    00136     SETARG_A(*i, reg);
    00137   else  /* no register to put value or register already has the value */
    00138     *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
    00139
    00140   return 1;
    00141 }
    00142
    00143
    00144 static void removevalues (FuncState *fs, int list) {
    00145   for (; list != NO_JUMP; list = getjump(fs, list))
    00146       patchtestreg(fs, list, NO_REG);
    00147 }
    00148
    00149
    00150 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
    00151                           int dtarget) {
    00152   while (list != NO_JUMP) {
    00153     int next = getjump(fs, list);
    00154     if (patchtestreg(fs, list, reg))
    00155       fixjump(fs, list, vtarget);
    00156     else
    00157       fixjump(fs, list, dtarget);  /* jump to default target */
    00158     list = next;
    00159   }
    00160 }
    00161
    00162
    00163 static void dischargejpc (FuncState *fs) {
    00164   patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
    00165   fs->jpc = NO_JUMP;
    00166 }
    00167
    00168
    00169 void luaK_patchlist (FuncState *fs, int list, int target) {
    00170   if (target == fs->pc)
    00171     luaK_patchtohere(fs, list);
    00172   else {
    00173     lua_assert(target < fs->pc);
    00174     patchlistaux(fs, list, target, NO_REG, target);
    00175   }
    00176 }
    00177
    00178
    00179 void luaK_patchtohere (FuncState *fs, int list) {
    00180   luaK_getlabel(fs);
    00181   luaK_concat(fs, &fs->jpc, list);
    00182 }
    00183
    00184
    00185 void luaK_concat (FuncState *fs, int *l1, int l2) {
    00186   if (l2 == NO_JUMP) return;
    00187   else if (*l1 == NO_JUMP)
    00188     *l1 = l2;
    00189   else {
    00190     int list = *l1;
    00191     int next;
    00192     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
    00193       list = next;
    00194     fixjump(fs, list, l2);
    00195   }
    00196 }
    00197
    00198
    00199 void luaK_checkstack (FuncState *fs, int n) {
    00200   int newstack = fs->freereg + n;
    00201   if (newstack > fs->f->maxstacksize) {
    00202     if (newstack >= MAXSTACK)
    00203       luaX_syntaxerror(fs->ls, "function or expression too complex");
    00204     fs->f->maxstacksize = cast_byte(newstack);
    00205   }
    00206 }
    00207
    00208
    00209 void luaK_reserveregs (FuncState *fs, int n) {
    00210   luaK_checkstack(fs, n);
    00211   fs->freereg += n;
    00212 }
    00213
    00214
    00215 static void freereg (FuncState *fs, int reg) {
    00216   if (!ISK(reg) && reg >= fs->nactvar) {
    00217     fs->freereg--;
    00218     lua_assert(reg == fs->freereg);
    00219   }
    00220 }
    00221
    00222
    00223 static void freeexp (FuncState *fs, expdesc *e) {
    00224   if (e->k == VNONRELOC)
    00225     freereg(fs, e->u.s.info);
    00226 }
    00227
    00228
    00229 static int addk (FuncState *fs, TValue *k, TValue *v) {
    00230   lua_State *L = fs->L;
    00231   TValue *idx = luaH_set(L, fs->h, k);
    00232   Proto *f = fs->f;
    00233   int oldsize = f->sizek;
    00234   if (ttisnumber(idx)) {
    00235     lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
    00236     return cast_int(nvalue(idx));
    00237   }
    00238   else {  /* constant not found; create a new entry */
    00239     setnvalue(idx, cast_num(fs->nk));
    00240     luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
    00241                     MAXARG_Bx, "constant table overflow");
    00242     while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
    00243     setobj(L, &f->k[fs->nk], v);
    00244     luaC_barrier(L, f, v);
    00245     return fs->nk++;
    00246   }
    00247 }
    00248
    00249
    00250 int luaK_stringK (FuncState *fs, TString *s) {
    00251   TValue o;
    00252   setsvalue(fs->L, &o, s);
    00253   return addk(fs, &o, &o);
    00254 }
    00255
    00256
    00257 int luaK_numberK (FuncState *fs, lua_Number r) {
    00258   TValue o;
    00259   setnvalue(&o, r);
    00260   return addk(fs, &o, &o);
    00261 }
    00262
    00263
    00264 static int boolK (FuncState *fs, int b) {
    00265   TValue o;
    00266   setbvalue(&o, b);
    00267   return addk(fs, &o, &o);
    00268 }
    00269
    00270
    00271 static int nilK (FuncState *fs) {
    00272   TValue k, v;
    00273   setnilvalue(&v);
    00274   /* cannot use nil as key; instead use table itself to represent nil */
    00275   sethvalue(fs->L, &k, fs->h);
    00276   return addk(fs, &k, &v);
    00277 }
    00278
    00279
    00280 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
    00281   if (e->k == VCALL) {  /* expression is an open function call? */
    00282     SETARG_C(getcode(fs, e), nresults+1);
    00283   }
    00284   else if (e->k == VVARARG) {
    00285     SETARG_B(getcode(fs, e), nresults+1);
    00286     SETARG_A(getcode(fs, e), fs->freereg);
    00287     luaK_reserveregs(fs, 1);
    00288   }
    00289 }
    00290
    00291
    00292 void luaK_setoneret (FuncState *fs, expdesc *e) {
    00293   if (e->k == VCALL) {  /* expression is an open function call? */
    00294     e->k = VNONRELOC;
    00295     e->u.s.info = GETARG_A(getcode(fs, e));
    00296   }
    00297   else if (e->k == VVARARG) {
    00298     SETARG_B(getcode(fs, e), 2);
    00299     e->k = VRELOCABLE;  /* can relocate its simple result */
    00300   }
    00301 }
    00302
    00303
    00304 void luaK_dischargevars (FuncState *fs, expdesc *e) {
    00305   switch (e->k) {
    00306     case VLOCAL: {
    00307       e->k = VNONRELOC;
    00308       break;
    00309     }
    00310     case VUPVAL: {
    00311       e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
    00312       e->k = VRELOCABLE;
    00313       break;
    00314     }
    00315     case VGLOBAL: {
    00316       e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
    00317       e->k = VRELOCABLE;
    00318       break;
    00319     }
    00320     case VINDEXED: {
    00321       freereg(fs, e->u.s.aux);
    00322       freereg(fs, e->u.s.info);
    00323       e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
    00324       e->k = VRELOCABLE;
    00325       break;
    00326     }
    00327     case VVARARG:
    00328     case VCALL: {
    00329       luaK_setoneret(fs, e);
    00330       break;
    00331     }
    00332     default: break;  /* there is one value available (somewhere) */
    00333   }
    00334 }
    00335
    00336
    00337 static int code_label (FuncState *fs, int A, int b, int jump) {
    00338   luaK_getlabel(fs);  /* those instructions may be jump targets */
    00339   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
    00340 }
    00341
    00342
    00343 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
    00344   luaK_dischargevars(fs, e);
    00345   switch (e->k) {
    00346     case VNIL: {
    00347       luaK_nil(fs, reg, 1);
    00348       break;
    00349     }
    00350     case VFALSE:  case VTRUE: {
    00351       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
    00352       break;
    00353     }
    00354     case VK: {
    00355       luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
    00356       break;
    00357     }
    00358     case VKNUM: {
    00359       luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
    00360       break;
    00361     }
    00362     case VRELOCABLE: {
    00363       Instruction *pc = &getcode(fs, e);
    00364       SETARG_A(*pc, reg);
    00365       break;
    00366     }
    00367     case VNONRELOC: {
    00368       if (reg != e->u.s.info)
    00369         luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
    00370       break;
    00371     }
    00372     default: {
    00373       lua_assert(e->k == VVOID || e->k == VJMP);
    00374       return;  /* nothing to do... */
    00375     }
    00376   }
    00377   e->u.s.info = reg;
    00378   e->k = VNONRELOC;
    00379 }
    00380
    00381
    00382 static void discharge2anyreg (FuncState *fs, expdesc *e) {
    00383   if (e->k != VNONRELOC) {
    00384     luaK_reserveregs(fs, 1);
    00385     discharge2reg(fs, e, fs->freereg-1);
    00386   }
    00387 }
    00388
    00389
    00390 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
    00391   discharge2reg(fs, e, reg);
    00392   if (e->k == VJMP)
    00393     luaK_concat(fs, &e->t, e->u.s.info);  /* put this jump in `t' list */
    00394   if (hasjumps(e)) {
    00395     int final;  /* position after whole expression */
    00396     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
    00397     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
    00398     if (need_value(fs, e->t) || need_value(fs, e->f)) {
    00399       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
    00400       p_f = code_label(fs, reg, 0, 1);
    00401       p_t = code_label(fs, reg, 1, 0);
    00402       luaK_patchtohere(fs, fj);
    00403     }
    00404     final = luaK_getlabel(fs);
    00405     patchlistaux(fs, e->f, final, reg, p_f);
    00406     patchlistaux(fs, e->t, final, reg, p_t);
    00407   }
    00408   e->f = e->t = NO_JUMP;
    00409   e->u.s.info = reg;
    00410   e->k = VNONRELOC;
    00411 }
    00412
    00413
    00414 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
    00415   luaK_dischargevars(fs, e);
    00416   freeexp(fs, e);
    00417   luaK_reserveregs(fs, 1);
    00418   exp2reg(fs, e, fs->freereg - 1);
    00419 }
    00420
    00421
    00422 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
    00423   luaK_dischargevars(fs, e);
    00424   if (e->k == VNONRELOC) {
    00425     if (!hasjumps(e)) return e->u.s.info;  /* exp is already in a register */
    00426     if (e->u.s.info >= fs->nactvar) {  /* reg. is not a local? */
    00427       exp2reg(fs, e, e->u.s.info);  /* put value on it */
    00428       return e->u.s.info;
    00429     }
    00430   }
    00431   luaK_exp2nextreg(fs, e);  /* default */
    00432   return e->u.s.info;
    00433 }
    00434
    00435
    00436 void luaK_exp2val (FuncState *fs, expdesc *e) {
    00437   if (hasjumps(e))
    00438     luaK_exp2anyreg(fs, e);
    00439   else
    00440     luaK_dischargevars(fs, e);
    00441 }
    00442
    00443
    00444 int luaK_exp2RK (FuncState *fs, expdesc *e) {
    00445   luaK_exp2val(fs, e);
    00446   switch (e->k) {
    00447     case VKNUM:
    00448     case VTRUE:
    00449     case VFALSE:
    00450     case VNIL: {
    00451       if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */
    00452         e->u.s.info = (e->k == VNIL)  ? nilK(fs) :
    00453                       (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
    00454                                         boolK(fs, (e->k == VTRUE));
    00455         e->k = VK;
    00456         return RKASK(e->u.s.info);
    00457       }
    00458       else break;
    00459     }
    00460     case VK: {
    00461       if (e->u.s.info <= MAXINDEXRK)  /* constant fit in argC? */
    00462         return RKASK(e->u.s.info);
    00463       else break;
    00464     }
    00465     default: break;
    00466   }
    00467   /* not a constant in the right range: put it in a register */
    00468   return luaK_exp2anyreg(fs, e);
    00469 }
    00470
    00471
    00472 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
    00473   switch (var->k) {
    00474     case VLOCAL: {
    00475       freeexp(fs, ex);
    00476       exp2reg(fs, ex, var->u.s.info);
    00477       return;
    00478     }
    00479     case VUPVAL: {
    00480       int e = luaK_exp2anyreg(fs, ex);
    00481       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
    00482       break;
    00483     }
    00484     case VGLOBAL: {
    00485       int e = luaK_exp2anyreg(fs, ex);
    00486       luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
    00487       break;
    00488     }
    00489     case VINDEXED: {
    00490       int e = luaK_exp2RK(fs, ex);
    00491       luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
    00492       break;
    00493     }
    00494     default: {
    00495       lua_assert(0);  /* invalid var kind to store */
    00496       break;
    00497     }
    00498   }
    00499   freeexp(fs, ex);
    00500 }
    00501
    00502
    00503 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
    00504   int func;
    00505   luaK_exp2anyreg(fs, e);
    00506   freeexp(fs, e);
    00507   func = fs->freereg;
    00508   luaK_reserveregs(fs, 2);
    00509   luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
    00510   freeexp(fs, key);
    00511   e->u.s.info = func;
    00512   e->k = VNONRELOC;
    00513 }
    00514
    00515
    00516 static void invertjump (FuncState *fs, expdesc *e) {
    00517   Instruction *pc = getjumpcontrol(fs, e->u.s.info);
    00518   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
    00519                                            GET_OPCODE(*pc) != OP_TEST);
    00520   SETARG_A(*pc, !(GETARG_A(*pc)));
    00521 }
    00522
    00523
    00524 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
    00525   if (e->k == VRELOCABLE) {
    00526     Instruction ie = getcode(fs, e);
    00527     if (GET_OPCODE(ie) == OP_NOT) {
    00528       fs->pc--;  /* remove previous OP_NOT */
    00529       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
    00530     }
    00531     /* else go through */
    00532   }
    00533   discharge2anyreg(fs, e);
    00534   freeexp(fs, e);
    00535   return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
    00536 }
    00537
    00538
    00539 void luaK_goiftrue (FuncState *fs, expdesc *e) {
    00540   int pc;  /* pc of last jump */
    00541   luaK_dischargevars(fs, e);
    00542   switch (e->k) {
    00543     case VK: case VKNUM: case VTRUE: {
    00544       pc = NO_JUMP;  /* always true; do nothing */
    00545       break;
    00546     }
    00547     case VFALSE: {
    00548       pc = luaK_jump(fs);  /* always jump */
    00549       break;
    00550     }
    00551     case VJMP: {
    00552       invertjump(fs, e);
    00553       pc = e->u.s.info;
    00554       break;
    00555     }
    00556     default: {
    00557       pc = jumponcond(fs, e, 0);
    00558       break;
    00559     }
    00560   }
    00561   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
    00562   luaK_patchtohere(fs, e->t);
    00563   e->t = NO_JUMP;
    00564 }
    00565
    00566
    00567 static void luaK_goiffalse (FuncState *fs, expdesc *e) {
    00568   int pc;  /* pc of last jump */
    00569   luaK_dischargevars(fs, e);
    00570   switch (e->k) {
    00571     case VNIL: case VFALSE: {
    00572       pc = NO_JUMP;  /* always false; do nothing */
    00573       break;
    00574     }
    00575     case VTRUE: {
    00576       pc = luaK_jump(fs);  /* always jump */
    00577       break;
    00578     }
    00579     case VJMP: {
    00580       pc = e->u.s.info;
    00581       break;
    00582     }
    00583     default: {
    00584       pc = jumponcond(fs, e, 1);
    00585       break;
    00586     }
    00587   }
    00588   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
    00589   luaK_patchtohere(fs, e->f);
    00590   e->f = NO_JUMP;
    00591 }
    00592
    00593
    00594 static void codenot (FuncState *fs, expdesc *e) {
    00595   luaK_dischargevars(fs, e);
    00596   switch (e->k) {
    00597     case VNIL: case VFALSE: {
    00598       e->k = VTRUE;
    00599       break;
    00600     }
    00601     case VK: case VKNUM: case VTRUE: {
    00602       e->k = VFALSE;
    00603       break;
    00604     }
    00605     case VJMP: {
    00606       invertjump(fs, e);
    00607       break;
    00608     }
    00609     case VRELOCABLE:
    00610     case VNONRELOC: {
    00611       discharge2anyreg(fs, e);
    00612       freeexp(fs, e);
    00613       e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
    00614       e->k = VRELOCABLE;
    00615       break;
    00616     }
    00617     default: {
    00618       lua_assert(0);  /* cannot happen */
    00619       break;
    00620     }
    00621   }
    00622   /* interchange true and false lists */
    00623   { int temp = e->f; e->f = e->t; e->t = temp; }
    00624   removevalues(fs, e->f);
    00625   removevalues(fs, e->t);
    00626 }
    00627
    00628
    00629 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
    00630   t->u.s.aux = luaK_exp2RK(fs, k);
    00631   t->k = VINDEXED;
    00632 }
    00633
    00634
    00635 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
    00636   lua_Number v1, v2, r;
    00637   if (!isnumeral(e1) || !isnumeral(e2)) return 0;
    00638   v1 = e1->u.nval;
    00639   v2 = e2->u.nval;
    00640   switch (op) {
    00641     case OP_ADD: r = luai_numadd(v1, v2); break;
    00642     case OP_SUB: r = luai_numsub(v1, v2); break;
    00643     case OP_MUL: r = luai_nummul(v1, v2); break;
    00644     case OP_DIV:
    00645       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
    00646       r = luai_numdiv(v1, v2); break;
    00647     case OP_MOD:
    00648       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
    00649       r = luai_nummod(v1, v2); break;
    00650     case OP_POW: r = luai_numpow(v1, v2); break;
    00651     case OP_UNM: r = luai_numunm(v1); break;
    00652     case OP_LEN: return 0;  /* no constant folding for 'len' */
    00653     default: lua_assert(0); r = 0; break;
    00654   }
    00655   if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */
    00656   e1->u.nval = r;
    00657   return 1;
    00658 }
    00659
    00660
    00661 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
    00662   if (constfolding(op, e1, e2))
    00663     return;
    00664   else {
    00665     int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
    00666     int o1 = luaK_exp2RK(fs, e1);
    00667     if (o1 > o2) {
    00668       freeexp(fs, e1);
    00669       freeexp(fs, e2);
    00670     }
    00671     else {
    00672       freeexp(fs, e2);
    00673       freeexp(fs, e1);
    00674     }
    00675     e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
    00676     e1->k = VRELOCABLE;
    00677   }
    00678 }
    00679
    00680
    00681 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
    00682                                                           expdesc *e2) {
    00683   int o1 = luaK_exp2RK(fs, e1);
    00684   int o2 = luaK_exp2RK(fs, e2);
    00685   freeexp(fs, e2);
    00686   freeexp(fs, e1);
    00687   if (cond == 0 && op != OP_EQ) {
    00688     int temp;  /* exchange args to replace by `<' or `<=' */
    00689     temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
    00690     cond = 1;
    00691   }
    00692   e1->u.s.info = condjump(fs, op, cond, o1, o2);
    00693   e1->k = VJMP;
    00694 }
    00695
    00696
    00697 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
    00698   expdesc e2;
    00699   e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
    00700   switch (op) {
    00701     case OPR_MINUS: {
    00702       if (!isnumeral(e))
    00703         luaK_exp2anyreg(fs, e);  /* cannot operate on non-numeric constants */
    00704       codearith(fs, OP_UNM, e, &e2);
    00705       break;
    00706     }
    00707     case OPR_NOT: codenot(fs, e); break;
    00708     case OPR_LEN: {
    00709       luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
    00710       codearith(fs, OP_LEN, e, &e2);
    00711       break;
    00712     }
    00713     default: lua_assert(0);
    00714   }
    00715 }
    00716
    00717
    00718 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
    00719   switch (op) {
    00720     case OPR_AND: {
    00721       luaK_goiftrue(fs, v);
    00722       break;
    00723     }
    00724     case OPR_OR: {
    00725       luaK_goiffalse(fs, v);
    00726       break;
    00727     }
    00728     case OPR_CONCAT: {
    00729       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
    00730       break;
    00731     }
    00732     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
    00733     case OPR_MOD: case OPR_POW: {
    00734       if (!isnumeral(v)) luaK_exp2RK(fs, v);
    00735       break;
    00736     }
    00737     default: {
    00738       luaK_exp2RK(fs, v);
    00739       break;
    00740     }
    00741   }
    00742 }
    00743
    00744
    00745 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
    00746   switch (op) {
    00747     case OPR_AND: {
    00748       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
    00749       luaK_dischargevars(fs, e2);
    00750       luaK_concat(fs, &e2->f, e1->f);
    00751       *e1 = *e2;
    00752       break;
    00753     }
    00754     case OPR_OR: {
    00755       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
    00756       luaK_dischargevars(fs, e2);
    00757       luaK_concat(fs, &e2->t, e1->t);
    00758       *e1 = *e2;
    00759       break;
    00760     }
    00761     case OPR_CONCAT: {
    00762       luaK_exp2val(fs, e2);
    00763       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
    00764         lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
    00765         freeexp(fs, e1);
    00766         SETARG_B(getcode(fs, e2), e1->u.s.info);
    00767         e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
    00768       }
    00769       else {
    00770         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
    00771         codearith(fs, OP_CONCAT, e1, e2);
    00772       }
    00773       break;
    00774     }
    00775     case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
    00776     case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
    00777     case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
    00778     case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
    00779     case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
    00780     case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
    00781     case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
    00782     case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
    00783     case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
    00784     case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
    00785     case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
    00786     case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
    00787     default: lua_assert(0);
    00788   }
    00789 }
    00790
    00791
    00792 void luaK_fixline (FuncState *fs, int line) {
    00793   fs->f->lineinfo[fs->pc - 1] = line;
    00794 }
    00795
    00796
    00797 static int luaK_code (FuncState *fs, Instruction i, int line) {
    00798   Proto *f = fs->f;
    00799   dischargejpc(fs);  /* `pc' will change */
    00800   /* put new instruction in code array */
    00801   luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
    00802                   MAX_INT, "code size overflow");
    00803   f->code[fs->pc] = i;
    00804   /* save corresponding line information */
    00805   luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
    00806                   MAX_INT, "code size overflow");
    00807   f->lineinfo[fs->pc] = line;
    00808   return fs->pc++;
    00809 }
    00810
    00811
    00812 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
    00813   lua_assert(getOpMode(o) == iABC);
    00814   lua_assert(getBMode(o) != OpArgN || b == 0);
    00815   lua_assert(getCMode(o) != OpArgN || c == 0);
    00816   return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
    00817 }
    00818
    00819
    00820 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
    00821   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
    00822   lua_assert(getCMode(o) == OpArgN);
    00823   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
    00824 }
    00825
    00826
    00827 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
    00828   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
    00829   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
    00830   lua_assert(tostore != 0);
    00831   if (c <= MAXARG_C)
    00832     luaK_codeABC(fs, OP_SETLIST, base, b, c);
    00833   else {
    00834     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
    00835     luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
    00836   }
    00837   fs->freereg = base + 1;  /* free registers with list values */
    00838 }
    00839