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