00001
00002
00003
00004
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 "lstring.h"
00025 #include "ltable.h"
00026 #include "lvm.h"
00027
00028
00029 #define hasjumps(e) ((e)->t != (e)->f)
00030
00031
00032 static int isnumeral(expdesc *e) {
00033 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
00034 }
00035
00036
00037 void luaK_nil (FuncState *fs, int from, int n) {
00038 Instruction *previous;
00039 int l = from + n - 1;
00040 if (fs->pc > fs->lasttarget) {
00041 previous = &fs->f->code[fs->pc-1];
00042 if (GET_OPCODE(*previous) == OP_LOADNIL) {
00043 int pfrom = GETARG_A(*previous);
00044 int pl = pfrom + GETARG_B(*previous);
00045 if ((pfrom <= from && from <= pl + 1) ||
00046 (from <= pfrom && pfrom <= l + 1)) {
00047 if (pfrom < from) from = pfrom;
00048 if (pl > l) l = pl;
00049 SETARG_A(*previous, from);
00050 SETARG_B(*previous, l - from);
00051 return;
00052 }
00053 }
00054 }
00055 luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);
00056 }
00057
00058
00059 int luaK_jump (FuncState *fs) {
00060 int jpc = fs->jpc;
00061 int j;
00062 fs->jpc = NO_JUMP;
00063 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
00064 luaK_concat(fs, &j, jpc);
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
00092
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)
00103 return NO_JUMP;
00104 else
00105 return (pc+1)+offset;
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
00120
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;
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;
00135 if (reg != NO_REG && reg != GETARG_B(*i))
00136 SETARG_A(*i, reg);
00137 else
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);
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 LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
00180 level++;
00181 while (list != NO_JUMP) {
00182 int next = getjump(fs, list);
00183 lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
00184 (GETARG_A(fs->f->code[list]) == 0 ||
00185 GETARG_A(fs->f->code[list]) >= level));
00186 SETARG_A(fs->f->code[list], level);
00187 list = next;
00188 }
00189 }
00190
00191
00192 void luaK_patchtohere (FuncState *fs, int list) {
00193 luaK_getlabel(fs);
00194 luaK_concat(fs, &fs->jpc, list);
00195 }
00196
00197
00198 void luaK_concat (FuncState *fs, int *l1, int l2) {
00199 if (l2 == NO_JUMP) return;
00200 else if (*l1 == NO_JUMP)
00201 *l1 = l2;
00202 else {
00203 int list = *l1;
00204 int next;
00205 while ((next = getjump(fs, list)) != NO_JUMP)
00206 list = next;
00207 fixjump(fs, list, l2);
00208 }
00209 }
00210
00211
00212 static int luaK_code (FuncState *fs, Instruction i) {
00213 Proto *f = fs->f;
00214 dischargejpc(fs);
00215
00216 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
00217 MAX_INT, "opcodes");
00218 f->code[fs->pc] = i;
00219
00220 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
00221 MAX_INT, "opcodes");
00222 f->lineinfo[fs->pc] = fs->ls->lastline;
00223 return fs->pc++;
00224 }
00225
00226
00227 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
00228 lua_assert(getOpMode(o) == iABC);
00229 lua_assert(getBMode(o) != OpArgN || b == 0);
00230 lua_assert(getCMode(o) != OpArgN || c == 0);
00231 lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
00232 return luaK_code(fs, CREATE_ABC(o, a, b, c));
00233 }
00234
00235
00236 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
00237 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
00238 lua_assert(getCMode(o) == OpArgN);
00239 lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
00240 return luaK_code(fs, CREATE_ABx(o, a, bc));
00241 }
00242
00243
00244 static int codeextraarg (FuncState *fs, int a) {
00245 lua_assert(a <= MAXARG_Ax);
00246 return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
00247 }
00248
00249
00250 int luaK_codek (FuncState *fs, int reg, int k) {
00251 if (k <= MAXARG_Bx)
00252 return luaK_codeABx(fs, OP_LOADK, reg, k);
00253 else {
00254 int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
00255 codeextraarg(fs, k);
00256 return p;
00257 }
00258 }
00259
00260
00261 void luaK_checkstack (FuncState *fs, int n) {
00262 int newstack = fs->freereg + n;
00263 if (newstack > fs->f->maxstacksize) {
00264 if (newstack >= MAXSTACK)
00265 luaX_syntaxerror(fs->ls, "function or expression too complex");
00266 fs->f->maxstacksize = cast_byte(newstack);
00267 }
00268 }
00269
00270
00271 void luaK_reserveregs (FuncState *fs, int n) {
00272 luaK_checkstack(fs, n);
00273 fs->freereg += n;
00274 }
00275
00276
00277 static void freereg (FuncState *fs, int reg) {
00278 if (!ISK(reg) && reg >= fs->nactvar) {
00279 fs->freereg--;
00280 lua_assert(reg == fs->freereg);
00281 }
00282 }
00283
00284
00285 static void freeexp (FuncState *fs, expdesc *e) {
00286 if (e->k == VNONRELOC)
00287 freereg(fs, e->u.info);
00288 }
00289
00290
00291 static int addk (FuncState *fs, TValue *key, TValue *v) {
00292 lua_State *L = fs->ls->L;
00293 TValue *idx = luaH_set(L, fs->h, key);
00294 Proto *f = fs->f;
00295 int k, oldsize;
00296 if (ttisnumber(idx)) {
00297 lua_Number n = nvalue(idx);
00298 lua_number2int(k, n);
00299 if (luaV_rawequalobj(&f->k[k], v))
00300 return k;
00301
00302
00303 }
00304
00305 oldsize = f->sizek;
00306 k = fs->nk;
00307
00308
00309 setnvalue(idx, cast_num(k));
00310 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
00311 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
00312 setobj(L, &f->k[k], v);
00313 fs->nk++;
00314 luaC_barrier(L, f, v);
00315 return k;
00316 }
00317
00318
00319 int luaK_stringK (FuncState *fs, TString *s) {
00320 TValue o;
00321 setsvalue(fs->ls->L, &o, s);
00322 return addk(fs, &o, &o);
00323 }
00324
00325
00326 int luaK_numberK (FuncState *fs, lua_Number r) {
00327 int n;
00328 lua_State *L = fs->ls->L;
00329 TValue o;
00330 setnvalue(&o, r);
00331 if (r == 0 || luai_numisnan(NULL, r)) {
00332
00333 setsvalue(L, L->top, luaS_newlstr(L, (char *)&r, sizeof(r)));
00334 incr_top(L);
00335 n = addk(fs, L->top - 1, &o);
00336 L->top--;
00337 }
00338 else
00339 n = addk(fs, &o, &o);
00340 return n;
00341 }
00342
00343
00344 static int boolK (FuncState *fs, int b) {
00345 TValue o;
00346 setbvalue(&o, b);
00347 return addk(fs, &o, &o);
00348 }
00349
00350
00351 static int nilK (FuncState *fs) {
00352 TValue k, v;
00353 setnilvalue(&v);
00354
00355 sethvalue(fs->ls->L, &k, fs->h);
00356 return addk(fs, &k, &v);
00357 }
00358
00359
00360 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
00361 if (e->k == VCALL) {
00362 SETARG_C(getcode(fs, e), nresults+1);
00363 }
00364 else if (e->k == VVARARG) {
00365 SETARG_B(getcode(fs, e), nresults+1);
00366 SETARG_A(getcode(fs, e), fs->freereg);
00367 luaK_reserveregs(fs, 1);
00368 }
00369 }
00370
00371
00372 void luaK_setoneret (FuncState *fs, expdesc *e) {
00373 if (e->k == VCALL) {
00374 e->k = VNONRELOC;
00375 e->u.info = GETARG_A(getcode(fs, e));
00376 }
00377 else if (e->k == VVARARG) {
00378 SETARG_B(getcode(fs, e), 2);
00379 e->k = VRELOCABLE;
00380 }
00381 }
00382
00383
00384 void luaK_dischargevars (FuncState *fs, expdesc *e) {
00385 switch (e->k) {
00386 case VLOCAL: {
00387 e->k = VNONRELOC;
00388 break;
00389 }
00390 case VUPVAL: {
00391 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
00392 e->k = VRELOCABLE;
00393 break;
00394 }
00395 case VINDEXED: {
00396 OpCode op = OP_GETTABUP;
00397 freereg(fs, e->u.ind.idx);
00398 if (e->u.ind.vt == VLOCAL) {
00399 freereg(fs, e->u.ind.t);
00400 op = OP_GETTABLE;
00401 }
00402 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
00403 e->k = VRELOCABLE;
00404 break;
00405 }
00406 case VVARARG:
00407 case VCALL: {
00408 luaK_setoneret(fs, e);
00409 break;
00410 }
00411 default: break;
00412 }
00413 }
00414
00415
00416 static int code_label (FuncState *fs, int A, int b, int jump) {
00417 luaK_getlabel(fs);
00418 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
00419 }
00420
00421
00422 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
00423 luaK_dischargevars(fs, e);
00424 switch (e->k) {
00425 case VNIL: {
00426 luaK_nil(fs, reg, 1);
00427 break;
00428 }
00429 case VFALSE: case VTRUE: {
00430 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
00431 break;
00432 }
00433 case VK: {
00434 luaK_codek(fs, reg, e->u.info);
00435 break;
00436 }
00437 case VKNUM: {
00438 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
00439 break;
00440 }
00441 case VRELOCABLE: {
00442 Instruction *pc = &getcode(fs, e);
00443 SETARG_A(*pc, reg);
00444 break;
00445 }
00446 case VNONRELOC: {
00447 if (reg != e->u.info)
00448 luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
00449 break;
00450 }
00451 default: {
00452 lua_assert(e->k == VVOID || e->k == VJMP);
00453 return;
00454 }
00455 }
00456 e->u.info = reg;
00457 e->k = VNONRELOC;
00458 }
00459
00460
00461 static void discharge2anyreg (FuncState *fs, expdesc *e) {
00462 if (e->k != VNONRELOC) {
00463 luaK_reserveregs(fs, 1);
00464 discharge2reg(fs, e, fs->freereg-1);
00465 }
00466 }
00467
00468
00469 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
00470 discharge2reg(fs, e, reg);
00471 if (e->k == VJMP)
00472 luaK_concat(fs, &e->t, e->u.info);
00473 if (hasjumps(e)) {
00474 int final;
00475 int p_f = NO_JUMP;
00476 int p_t = NO_JUMP;
00477 if (need_value(fs, e->t) || need_value(fs, e->f)) {
00478 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
00479 p_f = code_label(fs, reg, 0, 1);
00480 p_t = code_label(fs, reg, 1, 0);
00481 luaK_patchtohere(fs, fj);
00482 }
00483 final = luaK_getlabel(fs);
00484 patchlistaux(fs, e->f, final, reg, p_f);
00485 patchlistaux(fs, e->t, final, reg, p_t);
00486 }
00487 e->f = e->t = NO_JUMP;
00488 e->u.info = reg;
00489 e->k = VNONRELOC;
00490 }
00491
00492
00493 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
00494 luaK_dischargevars(fs, e);
00495 freeexp(fs, e);
00496 luaK_reserveregs(fs, 1);
00497 exp2reg(fs, e, fs->freereg - 1);
00498 }
00499
00500
00501 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
00502 luaK_dischargevars(fs, e);
00503 if (e->k == VNONRELOC) {
00504 if (!hasjumps(e)) return e->u.info;
00505 if (e->u.info >= fs->nactvar) {
00506 exp2reg(fs, e, e->u.info);
00507 return e->u.info;
00508 }
00509 }
00510 luaK_exp2nextreg(fs, e);
00511 return e->u.info;
00512 }
00513
00514
00515 void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
00516 if (e->k != VUPVAL || hasjumps(e))
00517 luaK_exp2anyreg(fs, e);
00518 }
00519
00520
00521 void luaK_exp2val (FuncState *fs, expdesc *e) {
00522 if (hasjumps(e))
00523 luaK_exp2anyreg(fs, e);
00524 else
00525 luaK_dischargevars(fs, e);
00526 }
00527
00528
00529 int luaK_exp2RK (FuncState *fs, expdesc *e) {
00530 luaK_exp2val(fs, e);
00531 switch (e->k) {
00532 case VTRUE:
00533 case VFALSE:
00534 case VNIL: {
00535 if (fs->nk <= MAXINDEXRK) {
00536 e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
00537 e->k = VK;
00538 return RKASK(e->u.info);
00539 }
00540 else break;
00541 }
00542 case VKNUM: {
00543 e->u.info = luaK_numberK(fs, e->u.nval);
00544 e->k = VK;
00545
00546 }
00547 case VK: {
00548 if (e->u.info <= MAXINDEXRK)
00549 return RKASK(e->u.info);
00550 else break;
00551 }
00552 default: break;
00553 }
00554
00555 return luaK_exp2anyreg(fs, e);
00556 }
00557
00558
00559 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
00560 switch (var->k) {
00561 case VLOCAL: {
00562 freeexp(fs, ex);
00563 exp2reg(fs, ex, var->u.info);
00564 return;
00565 }
00566 case VUPVAL: {
00567 int e = luaK_exp2anyreg(fs, ex);
00568 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
00569 break;
00570 }
00571 case VINDEXED: {
00572 OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
00573 int e = luaK_exp2RK(fs, ex);
00574 luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
00575 break;
00576 }
00577 default: {
00578 lua_assert(0);
00579 break;
00580 }
00581 }
00582 freeexp(fs, ex);
00583 }
00584
00585
00586 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
00587 int ereg;
00588 luaK_exp2anyreg(fs, e);
00589 ereg = e->u.info;
00590 freeexp(fs, e);
00591 e->u.info = fs->freereg;
00592 e->k = VNONRELOC;
00593 luaK_reserveregs(fs, 2);
00594 luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
00595 freeexp(fs, key);
00596 }
00597
00598
00599 static void invertjump (FuncState *fs, expdesc *e) {
00600 Instruction *pc = getjumpcontrol(fs, e->u.info);
00601 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
00602 GET_OPCODE(*pc) != OP_TEST);
00603 SETARG_A(*pc, !(GETARG_A(*pc)));
00604 }
00605
00606
00607 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
00608 if (e->k == VRELOCABLE) {
00609 Instruction ie = getcode(fs, e);
00610 if (GET_OPCODE(ie) == OP_NOT) {
00611 fs->pc--;
00612 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
00613 }
00614
00615 }
00616 discharge2anyreg(fs, e);
00617 freeexp(fs, e);
00618 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
00619 }
00620
00621
00622 void luaK_goiftrue (FuncState *fs, expdesc *e) {
00623 int pc;
00624 luaK_dischargevars(fs, e);
00625 switch (e->k) {
00626 case VJMP: {
00627 invertjump(fs, e);
00628 pc = e->u.info;
00629 break;
00630 }
00631 case VK: case VKNUM: case VTRUE: {
00632 pc = NO_JUMP;
00633 break;
00634 }
00635 default: {
00636 pc = jumponcond(fs, e, 0);
00637 break;
00638 }
00639 }
00640 luaK_concat(fs, &e->f, pc);
00641 luaK_patchtohere(fs, e->t);
00642 e->t = NO_JUMP;
00643 }
00644
00645
00646 void luaK_goiffalse (FuncState *fs, expdesc *e) {
00647 int pc;
00648 luaK_dischargevars(fs, e);
00649 switch (e->k) {
00650 case VJMP: {
00651 pc = e->u.info;
00652 break;
00653 }
00654 case VNIL: case VFALSE: {
00655 pc = NO_JUMP;
00656 break;
00657 }
00658 default: {
00659 pc = jumponcond(fs, e, 1);
00660 break;
00661 }
00662 }
00663 luaK_concat(fs, &e->t, pc);
00664 luaK_patchtohere(fs, e->f);
00665 e->f = NO_JUMP;
00666 }
00667
00668
00669 static void codenot (FuncState *fs, expdesc *e) {
00670 luaK_dischargevars(fs, e);
00671 switch (e->k) {
00672 case VNIL: case VFALSE: {
00673 e->k = VTRUE;
00674 break;
00675 }
00676 case VK: case VKNUM: case VTRUE: {
00677 e->k = VFALSE;
00678 break;
00679 }
00680 case VJMP: {
00681 invertjump(fs, e);
00682 break;
00683 }
00684 case VRELOCABLE:
00685 case VNONRELOC: {
00686 discharge2anyreg(fs, e);
00687 freeexp(fs, e);
00688 e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
00689 e->k = VRELOCABLE;
00690 break;
00691 }
00692 default: {
00693 lua_assert(0);
00694 break;
00695 }
00696 }
00697
00698 { int temp = e->f; e->f = e->t; e->t = temp; }
00699 removevalues(fs, e->f);
00700 removevalues(fs, e->t);
00701 }
00702
00703
00704 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
00705 lua_assert(!hasjumps(t));
00706 t->u.ind.t = t->u.info;
00707 t->u.ind.idx = luaK_exp2RK(fs, k);
00708 t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
00709 : check_exp(vkisinreg(t->k), VLOCAL);
00710 t->k = VINDEXED;
00711 }
00712
00713
00714 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
00715 lua_Number r;
00716 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
00717 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
00718 return 0;
00719 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
00720 e1->u.nval = r;
00721 return 1;
00722 }
00723
00724
00725 static void codearith (FuncState *fs, OpCode op,
00726 expdesc *e1, expdesc *e2, int line) {
00727 if (constfolding(op, e1, e2))
00728 return;
00729 else {
00730 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
00731 int o1 = luaK_exp2RK(fs, e1);
00732 if (o1 > o2) {
00733 freeexp(fs, e1);
00734 freeexp(fs, e2);
00735 }
00736 else {
00737 freeexp(fs, e2);
00738 freeexp(fs, e1);
00739 }
00740 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
00741 e1->k = VRELOCABLE;
00742 luaK_fixline(fs, line);
00743 }
00744 }
00745
00746
00747 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
00748 expdesc *e2) {
00749 int o1 = luaK_exp2RK(fs, e1);
00750 int o2 = luaK_exp2RK(fs, e2);
00751 freeexp(fs, e2);
00752 freeexp(fs, e1);
00753 if (cond == 0 && op != OP_EQ) {
00754 int temp;
00755 temp = o1; o1 = o2; o2 = temp;
00756 cond = 1;
00757 }
00758 e1->u.info = condjump(fs, op, cond, o1, o2);
00759 e1->k = VJMP;
00760 }
00761
00762
00763 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
00764 expdesc e2;
00765 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
00766 switch (op) {
00767 case OPR_MINUS: {
00768 if (isnumeral(e))
00769 e->u.nval = luai_numunm(NULL, e->u.nval);
00770 else {
00771 luaK_exp2anyreg(fs, e);
00772 codearith(fs, OP_UNM, e, &e2, line);
00773 }
00774 break;
00775 }
00776 case OPR_NOT: codenot(fs, e); break;
00777 case OPR_LEN: {
00778 luaK_exp2anyreg(fs, e);
00779 codearith(fs, OP_LEN, e, &e2, line);
00780 break;
00781 }
00782 default: lua_assert(0);
00783 }
00784 }
00785
00786
00787 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
00788 switch (op) {
00789 case OPR_AND: {
00790 luaK_goiftrue(fs, v);
00791 break;
00792 }
00793 case OPR_OR: {
00794 luaK_goiffalse(fs, v);
00795 break;
00796 }
00797 case OPR_CONCAT: {
00798 luaK_exp2nextreg(fs, v);
00799 break;
00800 }
00801 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
00802 case OPR_MOD: case OPR_POW: {
00803 if (!isnumeral(v)) luaK_exp2RK(fs, v);
00804 break;
00805 }
00806 default: {
00807 luaK_exp2RK(fs, v);
00808 break;
00809 }
00810 }
00811 }
00812
00813
00814 void luaK_posfix (FuncState *fs, BinOpr op,
00815 expdesc *e1, expdesc *e2, int line) {
00816 switch (op) {
00817 case OPR_AND: {
00818 lua_assert(e1->t == NO_JUMP);
00819 luaK_dischargevars(fs, e2);
00820 luaK_concat(fs, &e2->f, e1->f);
00821 *e1 = *e2;
00822 break;
00823 }
00824 case OPR_OR: {
00825 lua_assert(e1->f == NO_JUMP);
00826 luaK_dischargevars(fs, e2);
00827 luaK_concat(fs, &e2->t, e1->t);
00828 *e1 = *e2;
00829 break;
00830 }
00831 case OPR_CONCAT: {
00832 luaK_exp2val(fs, e2);
00833 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
00834 lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
00835 freeexp(fs, e1);
00836 SETARG_B(getcode(fs, e2), e1->u.info);
00837 e1->k = VRELOCABLE; e1->u.info = e2->u.info;
00838 }
00839 else {
00840 luaK_exp2nextreg(fs, e2);
00841 codearith(fs, OP_CONCAT, e1, e2, line);
00842 }
00843 break;
00844 }
00845 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
00846 case OPR_MOD: case OPR_POW: {
00847 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
00848 break;
00849 }
00850 case OPR_EQ: case OPR_LT: case OPR_LE: {
00851 codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
00852 break;
00853 }
00854 case OPR_NE: case OPR_GT: case OPR_GE: {
00855 codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
00856 break;
00857 }
00858 default: lua_assert(0);
00859 }
00860 }
00861
00862
00863 void luaK_fixline (FuncState *fs, int line) {
00864 fs->f->lineinfo[fs->pc - 1] = line;
00865 }
00866
00867
00868 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
00869 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
00870 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
00871 lua_assert(tostore != 0);
00872 if (c <= MAXARG_C)
00873 luaK_codeABC(fs, OP_SETLIST, base, b, c);
00874 else if (c <= MAXARG_Ax) {
00875 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
00876 codeextraarg(fs, c);
00877 }
00878 else
00879 luaX_syntaxerror(fs->ls, "constructor too long");
00880 fs->freereg = base + 1;
00881 }
00882