root/lib/lua/lcode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isnumeral
  2. luaK_nil
  3. luaK_jump
  4. luaK_ret
  5. condjump
  6. fixjump
  7. luaK_getlabel
  8. getjump
  9. getjumpcontrol
  10. need_value
  11. patchtestreg
  12. removevalues
  13. patchlistaux
  14. dischargejpc
  15. luaK_patchlist
  16. luaK_patchtohere
  17. luaK_concat
  18. luaK_checkstack
  19. luaK_reserveregs
  20. freereg
  21. freeexp
  22. addk
  23. luaK_stringK
  24. luaK_numberK
  25. boolK
  26. nilK
  27. luaK_setreturns
  28. luaK_setoneret
  29. luaK_dischargevars
  30. code_label
  31. discharge2reg
  32. discharge2anyreg
  33. exp2reg
  34. luaK_exp2nextreg
  35. luaK_exp2anyreg
  36. luaK_exp2val
  37. luaK_exp2RK
  38. luaK_storevar
  39. luaK_self
  40. invertjump
  41. jumponcond
  42. luaK_goiftrue
  43. luaK_goiffalse
  44. codenot
  45. luaK_indexed
  46. constfolding
  47. codearith
  48. codecomp
  49. luaK_prefix
  50. luaK_infix
  51. luaK_posfix
  52. luaK_fixline
  53. luaK_code
  54. luaK_codeABC
  55. luaK_codeABx
  56. luaK_setlist

   1 /*
   2 ** $Id: lcode.c,v 2.25.1.5 2011/01/31 14:53:16 roberto Exp $
   3 ** Code generator for Lua
   4 ** See Copyright Notice in lua.h
   5 */
   6 
   7 
   8 #include <stdlib.h>
   9 
  10 #define lcode_c
  11 #define LUA_CORE
  12 
  13 #include "lua.h"
  14 
  15 #include "lcode.h"
  16 #include "ldebug.h"
  17 #include "ldo.h"
  18 #include "lgc.h"
  19 #include "llex.h"
  20 #include "lmem.h"
  21 #include "lobject.h"
  22 #include "lopcodes.h"
  23 #include "lparser.h"
  24 #include "ltable.h"
  25 
  26 
  27 #define hasjumps(e)     ((e)->t != (e)->f)
  28 
  29 
  30 static int isnumeral(expdesc *e) {
  31   return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
  32 }
  33 
  34 
  35 LUAI_FUNC 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 }
  57 
  58 
  59 LUAI_FUNC 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 }
  67 
  68 
  69 LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret) {
  70   luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
  71 }
  72 
  73 
  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 }
  78 
  79 
  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 }
  88 
  89 
  90 /*
  91 ** returns current `pc' and marks it as a jump target (to avoid wrong
  92 ** optimizations with consecutive instructions not in the same basic block).
  93 */
  94 LUAI_FUNC int luaK_getlabel (FuncState *fs) {
  95   fs->lasttarget = fs->pc;
  96   return fs->pc;
  97 }
  98 
  99 
 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   else
 105     return (pc+1)+offset;  /* turn offset into absolute position */
 106 }
 107 
 108 
 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   else
 114     return pi;
 115 }
 116 
 117 
 118 /*
 119 ** check whether list has any jump that do not produce a value
 120 ** (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 }
 129 
 130 
 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));
 139 
 140   return 1;
 141 }
 142 
 143 
 144 static void removevalues (FuncState *fs, int list) {
 145   for (; list != NO_JUMP; list = getjump(fs, list))
 146       patchtestreg(fs, list, NO_REG);
 147 }
 148 
 149 
 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     else
 157       fixjump(fs, list, dtarget);  /* jump to default target */
 158     list = next;
 159   }
 160 }
 161 
 162 
 163 static void dischargejpc (FuncState *fs) {
 164   patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
 165   fs->jpc = NO_JUMP;
 166 }
 167 
 168 
 169 LUAI_FUNC 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 }
 177 
 178 
 179 LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list) {
 180   luaK_getlabel(fs);
 181   luaK_concat(fs, &fs->jpc, list);
 182 }
 183 
 184 
 185 LUAI_FUNC 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 }
 197 
 198 
 199 LUAI_FUNC 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 }
 207 
 208 
 209 LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n) {
 210   luaK_checkstack(fs, n);
 211   fs->freereg += n;
 212 }
 213 
 214 
 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 }
 221 
 222 
 223 static void freeexp (FuncState *fs, expdesc *e) {
 224   if (e->k == VNONRELOC)
 225     freereg(fs, e->u.s.info);
 226 }
 227 
 228 
 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 }
 248 
 249 
 250 LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s) {
 251   TValue o;
 252   setsvalue(fs->L, &o, s);
 253   return addk(fs, &o, &o);
 254 }
 255 
 256 
 257 LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r) {
 258   TValue o;
 259   setnvalue(&o, r);
 260   return addk(fs, &o, &o);
 261 }
 262 
 263 
 264 static int boolK (FuncState *fs, int b) {
 265   TValue o;
 266   setbvalue(&o, b);
 267   return addk(fs, &o, &o);
 268 }
 269 
 270 
 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 }
 278 
 279 
 280 LUAI_FUNC 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 }
 290 
 291 
 292 LUAI_FUNC 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 }
 302 
 303 
 304 LUAI_FUNC 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 }
 335 
 336 
 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 }
 341 
 342 
 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 }
 380 
 381 
 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 }
 388 
 389 
 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 }
 412 
 413 
 414 LUAI_FUNC 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 }
 420 
 421 
 422 LUAI_FUNC 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 }
 434 
 435 
 436 LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e) {
 437   if (hasjumps(e))
 438     luaK_exp2anyreg(fs, e);
 439   else
 440     luaK_dischargevars(fs, e);
 441 }
 442 
 443 
 444 LUAI_FUNC 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 }
 470 
 471 
 472 LUAI_FUNC 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 }
 501 
 502 
 503 LUAI_FUNC 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 }
 514 
 515 
 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 }
 522 
 523 
 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 }
 537 
 538 
 539 LUAI_FUNC 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 VJMP: {
 548       invertjump(fs, e);
 549       pc = e->u.s.info;
 550       break;
 551     }
 552     default: {
 553       pc = jumponcond(fs, e, 0);
 554       break;
 555     }
 556   }
 557   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
 558   luaK_patchtohere(fs, e->t);
 559   e->t = NO_JUMP;
 560 }
 561 
 562 
 563 static void luaK_goiffalse (FuncState *fs, expdesc *e) {
 564   int pc;  /* pc of last jump */
 565   luaK_dischargevars(fs, e);
 566   switch (e->k) {
 567     case VNIL: case VFALSE: {
 568       pc = NO_JUMP;  /* always false; do nothing */
 569       break;
 570     }
 571     case VJMP: {
 572       pc = e->u.s.info;
 573       break;
 574     }
 575     default: {
 576       pc = jumponcond(fs, e, 1);
 577       break;
 578     }
 579   }
 580   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
 581   luaK_patchtohere(fs, e->f);
 582   e->f = NO_JUMP;
 583 }
 584 
 585 
 586 static void codenot (FuncState *fs, expdesc *e) {
 587   luaK_dischargevars(fs, e);
 588   switch (e->k) {
 589     case VNIL: case VFALSE: {
 590       e->k = VTRUE;
 591       break;
 592     }
 593     case VK: case VKNUM: case VTRUE: {
 594       e->k = VFALSE;
 595       break;
 596     }
 597     case VJMP: {
 598       invertjump(fs, e);
 599       break;
 600     }
 601     case VRELOCABLE:
 602     case VNONRELOC: {
 603       discharge2anyreg(fs, e);
 604       freeexp(fs, e);
 605       e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
 606       e->k = VRELOCABLE;
 607       break;
 608     }
 609     default: {
 610       lua_assert(0);  /* cannot happen */
 611       break;
 612     }
 613   }
 614   /* interchange true and false lists */
 615   { int temp = e->f; e->f = e->t; e->t = temp; }
 616   removevalues(fs, e->f);
 617   removevalues(fs, e->t);
 618 }
 619 
 620 
 621 LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
 622   t->u.s.aux = luaK_exp2RK(fs, k);
 623   t->k = VINDEXED;
 624 }
 625 
 626 
 627 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
 628   lua_Number v1, v2, r;
 629   if (!isnumeral(e1) || !isnumeral(e2)) return 0;
 630   v1 = e1->u.nval;
 631   v2 = e2->u.nval;
 632   switch (op) {
 633     case OP_ADD: r = luai_numadd(v1, v2); break;
 634     case OP_SUB: r = luai_numsub(v1, v2); break;
 635     case OP_MUL: r = luai_nummul(v1, v2); break;
 636     case OP_DIV:
 637       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
 638       r = luai_numdiv(v1, v2); break;
 639     case OP_MOD:
 640       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
 641       r = luai_nummod(v1, v2); break;
 642     case OP_POW: r = luai_numpow(v1, v2); break;
 643     case OP_UNM: r = luai_numunm(v1); break;
 644     case OP_LEN: return 0;  /* no constant folding for 'len' */
 645     default: lua_assert(0); r = 0; break;
 646   }
 647   if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */
 648   e1->u.nval = r;
 649   return 1;
 650 }
 651 
 652 
 653 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
 654   if (constfolding(op, e1, e2))
 655     return;
 656   else {
 657     int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
 658     int o1 = luaK_exp2RK(fs, e1);
 659     if (o1 > o2) {
 660       freeexp(fs, e1);
 661       freeexp(fs, e2);
 662     }
 663     else {
 664       freeexp(fs, e2);
 665       freeexp(fs, e1);
 666     }
 667     e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
 668     e1->k = VRELOCABLE;
 669   }
 670 }
 671 
 672 
 673 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
 674                                                           expdesc *e2) {
 675   int o1 = luaK_exp2RK(fs, e1);
 676   int o2 = luaK_exp2RK(fs, e2);
 677   freeexp(fs, e2);
 678   freeexp(fs, e1);
 679   if (cond == 0 && op != OP_EQ) {
 680     int temp;  /* exchange args to replace by `<' or `<=' */
 681     temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
 682     cond = 1;
 683   }
 684   e1->u.s.info = condjump(fs, op, cond, o1, o2);
 685   e1->k = VJMP;
 686 }
 687 
 688 
 689 LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
 690   expdesc e2;
 691   e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
 692   switch (op) {
 693     case OPR_MINUS: {
 694       if (!isnumeral(e))
 695         luaK_exp2anyreg(fs, e);  /* cannot operate on non-numeric constants */
 696       codearith(fs, OP_UNM, e, &e2);
 697       break;
 698     }
 699     case OPR_NOT: codenot(fs, e); break;
 700     case OPR_LEN: {
 701       luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
 702       codearith(fs, OP_LEN, e, &e2);
 703       break;
 704     }
 705     default: lua_assert(0);
 706   }
 707 }
 708 
 709 
 710 LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
 711   switch (op) {
 712     case OPR_AND: {
 713       luaK_goiftrue(fs, v);
 714       break;
 715     }
 716     case OPR_OR: {
 717       luaK_goiffalse(fs, v);
 718       break;
 719     }
 720     case OPR_CONCAT: {
 721       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
 722       break;
 723     }
 724     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
 725     case OPR_MOD: case OPR_POW: {
 726       if (!isnumeral(v)) luaK_exp2RK(fs, v);
 727       break;
 728     }
 729     default: {
 730       luaK_exp2RK(fs, v);
 731       break;
 732     }
 733   }
 734 }
 735 
 736 
 737 LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
 738   switch (op) {
 739     case OPR_AND: {
 740       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
 741       luaK_dischargevars(fs, e2);
 742       luaK_concat(fs, &e2->f, e1->f);
 743       *e1 = *e2;
 744       break;
 745     }
 746     case OPR_OR: {
 747       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
 748       luaK_dischargevars(fs, e2);
 749       luaK_concat(fs, &e2->t, e1->t);
 750       *e1 = *e2;
 751       break;
 752     }
 753     case OPR_CONCAT: {
 754       luaK_exp2val(fs, e2);
 755       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
 756         lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
 757         freeexp(fs, e1);
 758         SETARG_B(getcode(fs, e2), e1->u.s.info);
 759         e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
 760       }
 761       else {
 762         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
 763         codearith(fs, OP_CONCAT, e1, e2);
 764       }
 765       break;
 766     }
 767     case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
 768     case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
 769     case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
 770     case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
 771     case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
 772     case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
 773     case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
 774     case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
 775     case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
 776     case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
 777     case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
 778     case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
 779     default: lua_assert(0);
 780   }
 781 }
 782 
 783 
 784 LUAI_FUNC void luaK_fixline (FuncState *fs, int line) {
 785   fs->f->lineinfo[fs->pc - 1] = line;
 786 }
 787 
 788 
 789 static int luaK_code (FuncState *fs, Instruction i, int line) {
 790   Proto *f = fs->f;
 791   dischargejpc(fs);  /* `pc' will change */
 792   /* put new instruction in code array */
 793   luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
 794                   MAX_INT, "code size overflow");
 795   f->code[fs->pc] = i;
 796   /* save corresponding line information */
 797   luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
 798                   MAX_INT, "code size overflow");
 799   f->lineinfo[fs->pc] = line;
 800   return fs->pc++;
 801 }
 802 
 803 
 804 LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
 805   lua_assert(getOpMode(o) == iABC);
 806   lua_assert(getBMode(o) != OpArgN || b == 0);
 807   lua_assert(getCMode(o) != OpArgN || c == 0);
 808   return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
 809 }
 810 
 811 
 812 LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
 813   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
 814   lua_assert(getCMode(o) == OpArgN);
 815   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
 816 }
 817 
 818 
 819 LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
 820   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
 821   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
 822   lua_assert(tostore != 0);
 823   if (c <= MAXARG_C)
 824     luaK_codeABC(fs, OP_SETLIST, base, b, c);
 825   else {
 826     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
 827     luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
 828   }
 829   fs->freereg = base + 1;  /* free registers with list values */
 830 }
 831 

/* [<][>][^][v][top][bottom][index][help] */