1 /* 2 ** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $ 3 ** Code generator for Lua 4 ** See Copyright Notice in lua.h 5 */ 6 7 #include <sys/zfs_context.h> 8 9 #define lcode_c 10 #define LUA_CORE 11 12 #include "lua.h" 13 14 #include "lcode.h" 15 #include "ldebug.h" 16 #include "ldo.h" 17 #include "lgc.h" 18 #include "llex.h" 19 #include "lmem.h" 20 #include "lobject.h" 21 #include "lopcodes.h" 22 #include "lparser.h" 23 #include "lstring.h" 24 #include "ltable.h" 25 #include "lvm.h" 26 27 28 #define hasjumps(e) ((e)->t != (e)->f) 29 30 31 static int isnumeral(expdesc *e) { 32 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); 33 } 34 35 36 void luaK_nil (FuncState *fs, int from, int n) { 37 Instruction *previous; 38 int l = from + n - 1; /* last register to set nil */ 39 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ 40 previous = &fs->f->code[fs->pc-1]; 41 if (GET_OPCODE(*previous) == OP_LOADNIL) { 42 int pfrom = GETARG_A(*previous); 43 int pl = pfrom + GETARG_B(*previous); 44 if ((pfrom <= from && from <= pl + 1) || 45 (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ 46 if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ 47 if (pl > l) l = pl; /* l = max(l, pl) */ 48 SETARG_A(*previous, from); 49 SETARG_B(*previous, l - from); 50 return; 51 } 52 } /* else go through */ 53 } 54 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ 55 } 56 57 58 int luaK_jump (FuncState *fs) { 59 int jpc = fs->jpc; /* save list of jumps to here */ 60 int j; 61 fs->jpc = NO_JUMP; 62 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); 63 luaK_concat(fs, &j, jpc); /* keep them on hold */ 64 return j; 65 } 66 67 68 void luaK_ret (FuncState *fs, int first, int nret) { 69 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); 70 } 71 72 73 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { 74 luaK_codeABC(fs, op, A, B, C); 75 return luaK_jump(fs); 76 } 77 78 79 static void fixjump (FuncState *fs, int pc, int dest) { 80 Instruction *jmp = &fs->f->code[pc]; 81 int offset = dest-(pc+1); 82 lua_assert(dest != NO_JUMP); 83 if (abs(offset) > MAXARG_sBx) 84 luaX_syntaxerror(fs->ls, "control structure too long"); 85 SETARG_sBx(*jmp, offset); 86 } 87 88 89 /* 90 ** returns current `pc' and marks it as a jump target (to avoid wrong 91 ** optimizations with consecutive instructions not in the same basic block). 92 */ 93 int luaK_getlabel (FuncState *fs) { 94 fs->lasttarget = fs->pc; 95 return fs->pc; 96 } 97 98 99 static int getjump (FuncState *fs, int pc) { 100 int offset = GETARG_sBx(fs->f->code[pc]); 101 if (offset == NO_JUMP) /* point to itself represents end of list */ 102 return NO_JUMP; /* end of list */ 103 else 104 return (pc+1)+offset; /* turn offset into absolute position */ 105 } 106 107 108 static Instruction *getjumpcontrol (FuncState *fs, int pc) { 109 Instruction *pi = &fs->f->code[pc]; 110 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) 111 return pi-1; 112 else 113 return pi; 114 } 115 116 117 /* 118 ** check whether list has any jump that do not produce a value 119 ** (or produce an inverted value) 120 */ 121 static int need_value (FuncState *fs, int list) { 122 for (; list != NO_JUMP; list = getjump(fs, list)) { 123 Instruction i = *getjumpcontrol(fs, list); 124 if (GET_OPCODE(i) != OP_TESTSET) return 1; 125 } 126 return 0; /* not found */ 127 } 128 129 130 static int patchtestreg (FuncState *fs, int node, int reg) { 131 Instruction *i = getjumpcontrol(fs, node); 132 if (GET_OPCODE(*i) != OP_TESTSET) 133 return 0; /* cannot patch other instructions */ 134 if (reg != NO_REG && reg != GETARG_B(*i)) 135 SETARG_A(*i, reg); 136 else /* no register to put value or register already has the value */ 137 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); 138 139 return 1; 140 } 141 142 143 static void removevalues (FuncState *fs, int list) { 144 for (; list != NO_JUMP; list = getjump(fs, list)) 145 patchtestreg(fs, list, NO_REG); 146 } 147 148 149 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, 150 int dtarget) { 151 while (list != NO_JUMP) { 152 int next = getjump(fs, list); 153 if (patchtestreg(fs, list, reg)) 154 fixjump(fs, list, vtarget); 155 else 156 fixjump(fs, list, dtarget); /* jump to default target */ 157 list = next; 158 } 159 } 160 161 162 static void dischargejpc (FuncState *fs) { 163 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); 164 fs->jpc = NO_JUMP; 165 } 166 167 168 void luaK_patchlist (FuncState *fs, int list, int target) { 169 if (target == fs->pc) 170 luaK_patchtohere(fs, list); 171 else { 172 lua_assert(target < fs->pc); 173 patchlistaux(fs, list, target, NO_REG, target); 174 } 175 } 176 177 178 LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { 179 level++; /* argument is +1 to reserve 0 as non-op */ 180 while (list != NO_JUMP) { 181 int next = getjump(fs, list); 182 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && 183 (GETARG_A(fs->f->code[list]) == 0 || 184 GETARG_A(fs->f->code[list]) >= level)); 185 SETARG_A(fs->f->code[list], level); 186 list = next; 187 } 188 } 189 190 191 void luaK_patchtohere (FuncState *fs, int list) { 192 luaK_getlabel(fs); 193 luaK_concat(fs, &fs->jpc, list); 194 } 195 196 197 void luaK_concat (FuncState *fs, int *l1, int l2) { 198 if (l2 == NO_JUMP) return; 199 else if (*l1 == NO_JUMP) 200 *l1 = l2; 201 else { 202 int list = *l1; 203 int next; 204 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ 205 list = next; 206 fixjump(fs, list, l2); 207 } 208 } 209 210 211 static int luaK_code (FuncState *fs, Instruction i) { 212 Proto *f = fs->f; 213 dischargejpc(fs); /* `pc' will change */ 214 /* put new instruction in code array */ 215 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, 216 MAX_INT, "opcodes"); 217 f->code[fs->pc] = i; 218 /* save corresponding line information */ 219 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, 220 MAX_INT, "opcodes"); 221 f->lineinfo[fs->pc] = fs->ls->lastline; 222 return fs->pc++; 223 } 224 225 226 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { 227 lua_assert(getOpMode(o) == iABC); 228 lua_assert(getBMode(o) != OpArgN || b == 0); 229 lua_assert(getCMode(o) != OpArgN || c == 0); 230 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); 231 return luaK_code(fs, CREATE_ABC(o, a, b, c)); 232 } 233 234 235 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { 236 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); 237 lua_assert(getCMode(o) == OpArgN); 238 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); 239 return luaK_code(fs, CREATE_ABx(o, a, bc)); 240 } 241 242 243 static int codeextraarg (FuncState *fs, int a) { 244 lua_assert(a <= MAXARG_Ax); 245 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); 246 } 247 248 249 int luaK_codek (FuncState *fs, int reg, int k) { 250 if (k <= MAXARG_Bx) 251 return luaK_codeABx(fs, OP_LOADK, reg, k); 252 else { 253 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); 254 codeextraarg(fs, k); 255 return p; 256 } 257 } 258 259 260 void luaK_checkstack (FuncState *fs, int n) { 261 int newstack = fs->freereg + n; 262 if (newstack > fs->f->maxstacksize) { 263 if (newstack >= MAXSTACK) 264 luaX_syntaxerror(fs->ls, "function or expression too complex"); 265 fs->f->maxstacksize = cast_byte(newstack); 266 } 267 } 268 269 270 void luaK_reserveregs (FuncState *fs, int n) { 271 luaK_checkstack(fs, n); 272 fs->freereg += n; 273 } 274 275 276 static void freereg (FuncState *fs, int reg) { 277 if (!ISK(reg) && reg >= fs->nactvar) { 278 fs->freereg--; 279 lua_assert(reg == fs->freereg); 280 } 281 } 282 283 284 static void freeexp (FuncState *fs, expdesc *e) { 285 if (e->k == VNONRELOC) 286 freereg(fs, e->u.info); 287 } 288 289 290 static int addk (FuncState *fs, TValue *key, TValue *v) { 291 lua_State *L = fs->ls->L; 292 TValue *idx = luaH_set(L, fs->h, key); 293 Proto *f = fs->f; 294 int k, oldsize; 295 if (ttisnumber(idx)) { 296 lua_Number n = nvalue(idx); 297 lua_number2int(k, n); 298 if (luaV_rawequalobj(&f->k[k], v)) 299 return k; 300 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); 301 go through and create a new entry for this value */ 302 } 303 /* constant not found; create a new entry */ 304 oldsize = f->sizek; 305 k = fs->nk; 306 /* numerical value does not need GC barrier; 307 table has no metatable, so it does not need to invalidate cache */ 308 setnvalue(idx, cast_num(k)); 309 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); 310 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); 311 setobj(L, &f->k[k], v); 312 fs->nk++; 313 luaC_barrier(L, f, v); 314 return k; 315 } 316 317 318 int luaK_stringK (FuncState *fs, TString *s) { 319 TValue o; 320 setsvalue(fs->ls->L, &o, s); 321 return addk(fs, &o, &o); 322 } 323 324 325 int luaK_numberK (FuncState *fs, lua_Number r) { 326 int n; 327 lua_State *L = fs->ls->L; 328 TValue o; 329 setnvalue(&o, r); 330 if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ 331 /* use raw representation as key to avoid numeric problems */ 332 setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); 333 n = addk(fs, L->top - 1, &o); 334 L->top--; 335 } 336 else 337 n = addk(fs, &o, &o); /* regular case */ 338 return n; 339 } 340 341 342 static int boolK (FuncState *fs, int b) { 343 TValue o; 344 setbvalue(&o, b); 345 return addk(fs, &o, &o); 346 } 347 348 349 static int nilK (FuncState *fs) { 350 TValue k, v; 351 setnilvalue(&v); 352 /* cannot use nil as key; instead use table itself to represent nil */ 353 sethvalue(fs->ls->L, &k, fs->h); 354 return addk(fs, &k, &v); 355 } 356 357 358 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { 359 if (e->k == VCALL) { /* expression is an open function call? */ 360 SETARG_C(getcode(fs, e), nresults+1); 361 } 362 else if (e->k == VVARARG) { 363 SETARG_B(getcode(fs, e), nresults+1); 364 SETARG_A(getcode(fs, e), fs->freereg); 365 luaK_reserveregs(fs, 1); 366 } 367 } 368 369 370 void luaK_setoneret (FuncState *fs, expdesc *e) { 371 if (e->k == VCALL) { /* expression is an open function call? */ 372 e->k = VNONRELOC; 373 e->u.info = GETARG_A(getcode(fs, e)); 374 } 375 else if (e->k == VVARARG) { 376 SETARG_B(getcode(fs, e), 2); 377 e->k = VRELOCABLE; /* can relocate its simple result */ 378 } 379 } 380 381 382 void luaK_dischargevars (FuncState *fs, expdesc *e) { 383 switch (e->k) { 384 case VLOCAL: { 385 e->k = VNONRELOC; 386 break; 387 } 388 case VUPVAL: { 389 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); 390 e->k = VRELOCABLE; 391 break; 392 } 393 case VINDEXED: { 394 OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ 395 freereg(fs, e->u.ind.idx); 396 if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ 397 freereg(fs, e->u.ind.t); 398 op = OP_GETTABLE; 399 } 400 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); 401 e->k = VRELOCABLE; 402 break; 403 } 404 case VVARARG: 405 case VCALL: { 406 luaK_setoneret(fs, e); 407 break; 408 } 409 default: break; /* there is one value available (somewhere) */ 410 } 411 } 412 413 414 static int code_label (FuncState *fs, int A, int b, int jump) { 415 luaK_getlabel(fs); /* those instructions may be jump targets */ 416 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); 417 } 418 419 420 static void discharge2reg (FuncState *fs, expdesc *e, int reg) { 421 luaK_dischargevars(fs, e); 422 switch (e->k) { 423 case VNIL: { 424 luaK_nil(fs, reg, 1); 425 break; 426 } 427 case VFALSE: case VTRUE: { 428 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); 429 break; 430 } 431 case VK: { 432 luaK_codek(fs, reg, e->u.info); 433 break; 434 } 435 case VKNUM: { 436 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); 437 break; 438 } 439 case VRELOCABLE: { 440 Instruction *pc = &getcode(fs, e); 441 SETARG_A(*pc, reg); 442 break; 443 } 444 case VNONRELOC: { 445 if (reg != e->u.info) 446 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); 447 break; 448 } 449 default: { 450 lua_assert(e->k == VVOID || e->k == VJMP); 451 return; /* nothing to do... */ 452 } 453 } 454 e->u.info = reg; 455 e->k = VNONRELOC; 456 } 457 458 459 static void discharge2anyreg (FuncState *fs, expdesc *e) { 460 if (e->k != VNONRELOC) { 461 luaK_reserveregs(fs, 1); 462 discharge2reg(fs, e, fs->freereg-1); 463 } 464 } 465 466 467 static void exp2reg (FuncState *fs, expdesc *e, int reg) { 468 discharge2reg(fs, e, reg); 469 if (e->k == VJMP) 470 luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ 471 if (hasjumps(e)) { 472 int final; /* position after whole expression */ 473 int p_f = NO_JUMP; /* position of an eventual LOAD false */ 474 int p_t = NO_JUMP; /* position of an eventual LOAD true */ 475 if (need_value(fs, e->t) || need_value(fs, e->f)) { 476 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); 477 p_f = code_label(fs, reg, 0, 1); 478 p_t = code_label(fs, reg, 1, 0); 479 luaK_patchtohere(fs, fj); 480 } 481 final = luaK_getlabel(fs); 482 patchlistaux(fs, e->f, final, reg, p_f); 483 patchlistaux(fs, e->t, final, reg, p_t); 484 } 485 e->f = e->t = NO_JUMP; 486 e->u.info = reg; 487 e->k = VNONRELOC; 488 } 489 490 491 void luaK_exp2nextreg (FuncState *fs, expdesc *e) { 492 luaK_dischargevars(fs, e); 493 freeexp(fs, e); 494 luaK_reserveregs(fs, 1); 495 exp2reg(fs, e, fs->freereg - 1); 496 } 497 498 499 int luaK_exp2anyreg (FuncState *fs, expdesc *e) { 500 luaK_dischargevars(fs, e); 501 if (e->k == VNONRELOC) { 502 if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ 503 if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ 504 exp2reg(fs, e, e->u.info); /* put value on it */ 505 return e->u.info; 506 } 507 } 508 luaK_exp2nextreg(fs, e); /* default */ 509 return e->u.info; 510 } 511 512 513 void luaK_exp2anyregup (FuncState *fs, expdesc *e) { 514 if (e->k != VUPVAL || hasjumps(e)) 515 luaK_exp2anyreg(fs, e); 516 } 517 518 519 void luaK_exp2val (FuncState *fs, expdesc *e) { 520 if (hasjumps(e)) 521 luaK_exp2anyreg(fs, e); 522 else 523 luaK_dischargevars(fs, e); 524 } 525 526 527 int luaK_exp2RK (FuncState *fs, expdesc *e) { 528 luaK_exp2val(fs, e); 529 switch (e->k) { 530 case VTRUE: 531 case VFALSE: 532 case VNIL: { 533 if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ 534 e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); 535 e->k = VK; 536 return RKASK(e->u.info); 537 } 538 else break; 539 } 540 case VKNUM: { 541 e->u.info = luaK_numberK(fs, e->u.nval); 542 e->k = VK; 543 /* go through */ 544 } 545 case VK: { 546 if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ 547 return RKASK(e->u.info); 548 else break; 549 } 550 default: break; 551 } 552 /* not a constant in the right range: put it in a register */ 553 return luaK_exp2anyreg(fs, e); 554 } 555 556 557 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { 558 switch (var->k) { 559 case VLOCAL: { 560 freeexp(fs, ex); 561 exp2reg(fs, ex, var->u.info); 562 return; 563 } 564 case VUPVAL: { 565 int e = luaK_exp2anyreg(fs, ex); 566 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); 567 break; 568 } 569 case VINDEXED: { 570 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; 571 int e = luaK_exp2RK(fs, ex); 572 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); 573 break; 574 } 575 default: { 576 lua_assert(0); /* invalid var kind to store */ 577 break; 578 } 579 } 580 freeexp(fs, ex); 581 } 582 583 584 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { 585 int ereg; 586 luaK_exp2anyreg(fs, e); 587 ereg = e->u.info; /* register where 'e' was placed */ 588 freeexp(fs, e); 589 e->u.info = fs->freereg; /* base register for op_self */ 590 e->k = VNONRELOC; 591 luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ 592 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); 593 freeexp(fs, key); 594 } 595 596 597 static void invertjump (FuncState *fs, expdesc *e) { 598 Instruction *pc = getjumpcontrol(fs, e->u.info); 599 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && 600 GET_OPCODE(*pc) != OP_TEST); 601 SETARG_A(*pc, !(GETARG_A(*pc))); 602 } 603 604 605 static int jumponcond (FuncState *fs, expdesc *e, int cond) { 606 if (e->k == VRELOCABLE) { 607 Instruction ie = getcode(fs, e); 608 if (GET_OPCODE(ie) == OP_NOT) { 609 fs->pc--; /* remove previous OP_NOT */ 610 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 611 } 612 /* else go through */ 613 } 614 discharge2anyreg(fs, e); 615 freeexp(fs, e); 616 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); 617 } 618 619 620 void luaK_goiftrue (FuncState *fs, expdesc *e) { 621 int pc; /* pc of last jump */ 622 luaK_dischargevars(fs, e); 623 switch (e->k) { 624 case VJMP: { 625 invertjump(fs, e); 626 pc = e->u.info; 627 break; 628 } 629 case VK: case VKNUM: case VTRUE: { 630 pc = NO_JUMP; /* always true; do nothing */ 631 break; 632 } 633 default: { 634 pc = jumponcond(fs, e, 0); 635 break; 636 } 637 } 638 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ 639 luaK_patchtohere(fs, e->t); 640 e->t = NO_JUMP; 641 } 642 643 644 void luaK_goiffalse (FuncState *fs, expdesc *e) { 645 int pc; /* pc of last jump */ 646 luaK_dischargevars(fs, e); 647 switch (e->k) { 648 case VJMP: { 649 pc = e->u.info; 650 break; 651 } 652 case VNIL: case VFALSE: { 653 pc = NO_JUMP; /* always false; do nothing */ 654 break; 655 } 656 default: { 657 pc = jumponcond(fs, e, 1); 658 break; 659 } 660 } 661 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ 662 luaK_patchtohere(fs, e->f); 663 e->f = NO_JUMP; 664 } 665 666 667 static void codenot (FuncState *fs, expdesc *e) { 668 luaK_dischargevars(fs, e); 669 switch (e->k) { 670 case VNIL: case VFALSE: { 671 e->k = VTRUE; 672 break; 673 } 674 case VK: case VKNUM: case VTRUE: { 675 e->k = VFALSE; 676 break; 677 } 678 case VJMP: { 679 invertjump(fs, e); 680 break; 681 } 682 case VRELOCABLE: 683 case VNONRELOC: { 684 discharge2anyreg(fs, e); 685 freeexp(fs, e); 686 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); 687 e->k = VRELOCABLE; 688 break; 689 } 690 default: { 691 lua_assert(0); /* cannot happen */ 692 break; 693 } 694 } 695 /* interchange true and false lists */ 696 { int temp = e->f; e->f = e->t; e->t = temp; } 697 removevalues(fs, e->f); 698 removevalues(fs, e->t); 699 } 700 701 702 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 703 lua_assert(!hasjumps(t)); 704 t->u.ind.t = t->u.info; 705 t->u.ind.idx = luaK_exp2RK(fs, k); 706 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL 707 : check_exp(vkisinreg(t->k), VLOCAL); 708 t->k = VINDEXED; 709 } 710 711 712 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { 713 lua_Number r; 714 if (!isnumeral(e1) || !isnumeral(e2)) return 0; 715 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) 716 return 0; /* do not attempt to divide by 0 */ 717 /* 718 * Patched: check for MIN_INT / -1 719 */ 720 if (op == OP_DIV && e1->u.nval == INT64_MIN && e2->u.nval == -1) 721 return 0; 722 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); 723 e1->u.nval = r; 724 return 1; 725 } 726 727 728 static void codearith (FuncState *fs, OpCode op, 729 expdesc *e1, expdesc *e2, int line) { 730 if (constfolding(op, e1, e2)) 731 return; 732 else { 733 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; 734 int o1 = luaK_exp2RK(fs, e1); 735 if (o1 > o2) { 736 freeexp(fs, e1); 737 freeexp(fs, e2); 738 } 739 else { 740 freeexp(fs, e2); 741 freeexp(fs, e1); 742 } 743 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); 744 e1->k = VRELOCABLE; 745 luaK_fixline(fs, line); 746 } 747 } 748 749 750 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, 751 expdesc *e2) { 752 int o1 = luaK_exp2RK(fs, e1); 753 int o2 = luaK_exp2RK(fs, e2); 754 freeexp(fs, e2); 755 freeexp(fs, e1); 756 if (cond == 0 && op != OP_EQ) { 757 int temp; /* exchange args to replace by `<' or `<=' */ 758 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ 759 cond = 1; 760 } 761 e1->u.info = condjump(fs, op, cond, o1, o2); 762 e1->k = VJMP; 763 } 764 765 766 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { 767 expdesc e2; 768 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; 769 switch (op) { 770 case OPR_MINUS: { 771 if (isnumeral(e)) /* minus constant? */ 772 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ 773 else { 774 luaK_exp2anyreg(fs, e); 775 codearith(fs, OP_UNM, e, &e2, line); 776 } 777 break; 778 } 779 case OPR_NOT: codenot(fs, e); break; 780 case OPR_LEN: { 781 luaK_exp2anyreg(fs, e); /* cannot operate on constants */ 782 codearith(fs, OP_LEN, e, &e2, line); 783 break; 784 } 785 default: lua_assert(0); 786 } 787 } 788 789 790 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { 791 switch (op) { 792 case OPR_AND: { 793 luaK_goiftrue(fs, v); 794 break; 795 } 796 case OPR_OR: { 797 luaK_goiffalse(fs, v); 798 break; 799 } 800 case OPR_CONCAT: { 801 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ 802 break; 803 } 804 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 805 case OPR_MOD: case OPR_POW: { 806 if (!isnumeral(v)) luaK_exp2RK(fs, v); 807 break; 808 } 809 default: { 810 luaK_exp2RK(fs, v); 811 break; 812 } 813 } 814 } 815 816 817 void luaK_posfix (FuncState *fs, BinOpr op, 818 expdesc *e1, expdesc *e2, int line) { 819 switch (op) { 820 case OPR_AND: { 821 lua_assert(e1->t == NO_JUMP); /* list must be closed */ 822 luaK_dischargevars(fs, e2); 823 luaK_concat(fs, &e2->f, e1->f); 824 *e1 = *e2; 825 break; 826 } 827 case OPR_OR: { 828 lua_assert(e1->f == NO_JUMP); /* list must be closed */ 829 luaK_dischargevars(fs, e2); 830 luaK_concat(fs, &e2->t, e1->t); 831 *e1 = *e2; 832 break; 833 } 834 case OPR_CONCAT: { 835 luaK_exp2val(fs, e2); 836 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { 837 lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); 838 freeexp(fs, e1); 839 SETARG_B(getcode(fs, e2), e1->u.info); 840 e1->k = VRELOCABLE; e1->u.info = e2->u.info; 841 } 842 else { 843 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ 844 codearith(fs, OP_CONCAT, e1, e2, line); 845 } 846 break; 847 } 848 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 849 case OPR_MOD: case OPR_POW: { 850 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); 851 break; 852 } 853 case OPR_EQ: case OPR_LT: case OPR_LE: { 854 codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); 855 break; 856 } 857 case OPR_NE: case OPR_GT: case OPR_GE: { 858 codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); 859 break; 860 } 861 default: lua_assert(0); 862 } 863 } 864 865 866 void luaK_fixline (FuncState *fs, int line) { 867 fs->f->lineinfo[fs->pc - 1] = line; 868 } 869 870 871 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { 872 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; 873 int b = (tostore == LUA_MULTRET) ? 0 : tostore; 874 lua_assert(tostore != 0); 875 if (c <= MAXARG_C) 876 luaK_codeABC(fs, OP_SETLIST, base, b, c); 877 else if (c <= MAXARG_Ax) { 878 luaK_codeABC(fs, OP_SETLIST, base, b, 0); 879 codeextraarg(fs, c); 880 } 881 else 882 luaX_syntaxerror(fs->ls, "constructor too long"); 883 fs->freereg = base + 1; /* free registers with list values */ 884 } 885 886