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