lcode.c
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:17k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. /*
  2. ** $Id: lcode.c,v 1.1 2004/08/20 02:26:56 JH Exp $
  3. ** Code generator for Lua
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #define lcode_c
  8. #include "lua.h"
  9. #include "lcode.h"
  10. #include "ldebug.h"
  11. #include "ldo.h"
  12. #include "llex.h"
  13. #include "lmem.h"
  14. #include "lobject.h"
  15. #include "lopcodes.h"
  16. #include "lparser.h"
  17. #include "ltable.h"
  18. #define hasjumps(e) ((e)->t != (e)->f)
  19. void luaK_nil (FuncState *fs, int from, int n) {
  20.   Instruction *previous;
  21.   if (fs->pc > fs->lasttarget &&  /* no jumps to current position? */
  22.       GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
  23.     int pfrom = GETARG_A(*previous);
  24.     int pto = GETARG_B(*previous);
  25.     if (pfrom <= from && from <= pto+1) {  /* can connect both? */
  26.       if (from+n-1 > pto)
  27.         SETARG_B(*previous, from+n-1);
  28.       return;
  29.     }
  30.   }
  31.   luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0);  /* else no optimization */
  32. }
  33. int luaK_jump (FuncState *fs) {
  34.   int jpc = fs->jpc;  /* save list of jumps to here */
  35.   int j;
  36.   fs->jpc = NO_JUMP;
  37.   j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
  38.   luaK_concat(fs, &j, jpc);  /* keep them on hold */
  39.   return j;
  40. }
  41. static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
  42.   luaK_codeABC(fs, op, A, B, C);
  43.   return luaK_jump(fs);
  44. }
  45. static void luaK_fixjump (FuncState *fs, int pc, int dest) {
  46.   Instruction *jmp = &fs->f->code[pc];
  47.   int offset = dest-(pc+1);
  48.   lua_assert(dest != NO_JUMP);
  49.   if (abs(offset) > MAXARG_sBx)
  50.     luaX_syntaxerror(fs->ls, "control structure too long");
  51.   SETARG_sBx(*jmp, offset);
  52. }
  53. /*
  54. ** returns current `pc' and marks it as a jump target (to avoid wrong
  55. ** optimizations with consecutive instructions not in the same basic block).
  56. */
  57. int luaK_getlabel (FuncState *fs) {
  58.   fs->lasttarget = fs->pc;
  59.   return fs->pc;
  60. }
  61. static int luaK_getjump (FuncState *fs, int pc) {
  62.   int offset = GETARG_sBx(fs->f->code[pc]);
  63.   if (offset == NO_JUMP)  /* point to itself represents end of list */
  64.     return NO_JUMP;  /* end of list */
  65.   else
  66.     return (pc+1)+offset;  /* turn offset into absolute position */
  67. }
  68. static Instruction *getjumpcontrol (FuncState *fs, int pc) {
  69.   Instruction *pi = &fs->f->code[pc];
  70.   if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
  71.     return pi-1;
  72.   else
  73.     return pi;
  74. }
  75. /*
  76. ** check whether list has any jump that do not produce a value
  77. ** (or produce an inverted value)
  78. */
  79. static int need_value (FuncState *fs, int list, int cond) {
  80.   for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
  81.     Instruction i = *getjumpcontrol(fs, list);
  82.     if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
  83.   }
  84.   return 0;  /* not found */
  85. }
  86. static void patchtestreg (Instruction *i, int reg) {
  87.   if (reg == NO_REG) reg = GETARG_B(*i);
  88.   SETARG_A(*i, reg);
  89. }
  90. static void luaK_patchlistaux (FuncState *fs, int list,
  91.           int ttarget, int treg, int ftarget, int freg, int dtarget) {
  92.   while (list != NO_JUMP) {
  93.     int next = luaK_getjump(fs, list);
  94.     Instruction *i = getjumpcontrol(fs, list);
  95.     if (GET_OPCODE(*i) != OP_TEST) {
  96.       lua_assert(dtarget != NO_JUMP);
  97.       luaK_fixjump(fs, list, dtarget);  /* jump to default target */
  98.     }
  99.     else {
  100.       if (GETARG_C(*i)) {
  101.         lua_assert(ttarget != NO_JUMP);
  102.         patchtestreg(i, treg);
  103.         luaK_fixjump(fs, list, ttarget);
  104.       }
  105.       else {
  106.         lua_assert(ftarget != NO_JUMP);
  107.         patchtestreg(i, freg);
  108.         luaK_fixjump(fs, list, ftarget);
  109.       }
  110.     }
  111.     list = next;
  112.   }
  113. }
  114. static void luaK_dischargejpc (FuncState *fs) {
  115.   luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
  116.   fs->jpc = NO_JUMP;
  117. }
  118. void luaK_patchlist (FuncState *fs, int list, int target) {
  119.   if (target == fs->pc)
  120.     luaK_patchtohere(fs, list);
  121.   else {
  122.     lua_assert(target < fs->pc);
  123.     luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
  124.   }
  125. }
  126. void luaK_patchtohere (FuncState *fs, int list) {
  127.   luaK_getlabel(fs);
  128.   luaK_concat(fs, &fs->jpc, list);
  129. }
  130. void luaK_concat (FuncState *fs, int *l1, int l2) {
  131.   if (l2 == NO_JUMP) return;
  132.   else if (*l1 == NO_JUMP)
  133.     *l1 = l2;
  134.   else {
  135.     int list = *l1;
  136.     int next;
  137.     while ((next = luaK_getjump(fs, list)) != NO_JUMP)  /* find last element */
  138.       list = next;
  139.     luaK_fixjump(fs, list, l2);
  140.   }
  141. }
  142. void luaK_checkstack (FuncState *fs, int n) {
  143.   int newstack = fs->freereg + n;
  144.   if (newstack > fs->f->maxstacksize) {
  145.     if (newstack >= MAXSTACK)
  146.       luaX_syntaxerror(fs->ls, "function or expression too complex");
  147.     fs->f->maxstacksize = cast(lu_byte, newstack);
  148.   }
  149. }
  150. void luaK_reserveregs (FuncState *fs, int n) {
  151.   luaK_checkstack(fs, n);
  152.   fs->freereg += n;
  153. }
  154. static void freereg (FuncState *fs, int reg) {
  155.   if (reg >= fs->nactvar && reg < MAXSTACK) {
  156.     fs->freereg--;
  157.     lua_assert(reg == fs->freereg);
  158.   }
  159. }
  160. static void freeexp (FuncState *fs, expdesc *e) {
  161.   if (e->k == VNONRELOC)
  162.     freereg(fs, e->info);
  163. }
  164. static int addk (FuncState *fs, TObject *k, TObject *v) {
  165.   const TObject *idx = luaH_get(fs->h, k);
  166.   if (ttisnumber(idx)) {
  167.     lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
  168.     return cast(int, nvalue(idx));
  169.   }
  170.   else {  /* constant not found; create a new entry */
  171.     Proto *f = fs->f;
  172.     luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
  173.                     MAXARG_Bx, "constant table overflow");
  174.     setobj2n(&f->k[fs->nk], v);
  175.     setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
  176.     return fs->nk++;
  177.   }
  178. }
  179. int luaK_stringK (FuncState *fs, TString *s) {
  180.   TObject o;
  181.   setsvalue(&o, s);
  182.   return addk(fs, &o, &o);
  183. }
  184. int luaK_numberK (FuncState *fs, lua_Number r) {
  185.   TObject o;
  186.   setnvalue(&o, r);
  187.   return addk(fs, &o, &o);
  188. }
  189. static int nil_constant (FuncState *fs) {
  190.   TObject k, v;
  191.   setnilvalue(&v);
  192.   sethvalue(&k, fs->h);  /* cannot use nil as key; instead use table itself */
  193.   return addk(fs, &k, &v);
  194. }
  195. void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
  196.   if (e->k == VCALL) {  /* expression is an open function call? */
  197.     SETARG_C(getcode(fs, e), nresults+1);
  198.     if (nresults == 1) {  /* `regular' expression? */
  199.       e->k = VNONRELOC;
  200.       e->info = GETARG_A(getcode(fs, e));
  201.     }
  202.   }
  203. }
  204. void luaK_dischargevars (FuncState *fs, expdesc *e) {
  205.   switch (e->k) {
  206.     case VLOCAL: {
  207.       e->k = VNONRELOC;
  208.       break;
  209.     }
  210.     case VUPVAL: {
  211.       e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
  212.       e->k = VRELOCABLE;
  213.       break;
  214.     }
  215.     case VGLOBAL: {
  216.       e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
  217.       e->k = VRELOCABLE;
  218.       break;
  219.     }
  220.     case VINDEXED: {
  221.       freereg(fs, e->aux);
  222.       freereg(fs, e->info);
  223.       e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
  224.       e->k = VRELOCABLE;
  225.       break;
  226.     }
  227.     case VCALL: {
  228.       luaK_setcallreturns(fs, e, 1);
  229.       break;
  230.     }
  231.     default: break;  /* there is one value available (somewhere) */
  232.   }
  233. }
  234. static int code_label (FuncState *fs, int A, int b, int jump) {
  235.   luaK_getlabel(fs);  /* those instructions may be jump targets */
  236.   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
  237. }
  238. static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
  239.   luaK_dischargevars(fs, e);
  240.   switch (e->k) {
  241.     case VNIL: {
  242.       luaK_nil(fs, reg, 1);
  243.       break;
  244.     }
  245.     case VFALSE:  case VTRUE: {
  246.       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
  247.       break;
  248.     }
  249.     case VK: {
  250.       luaK_codeABx(fs, OP_LOADK, reg, e->info);
  251.       break;
  252.     }
  253.     case VRELOCABLE: {
  254.       Instruction *pc = &getcode(fs, e);
  255.       SETARG_A(*pc, reg);
  256.       break;
  257.     }
  258.     case VNONRELOC: {
  259.       if (reg != e->info)
  260.         luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
  261.       break;
  262.     }
  263.     default: {
  264.       lua_assert(e->k == VVOID || e->k == VJMP);
  265.       return;  /* nothing to do... */
  266.     }
  267.   }
  268.   e->info = reg;
  269.   e->k = VNONRELOC;
  270. }
  271. static void discharge2anyreg (FuncState *fs, expdesc *e) {
  272.   if (e->k != VNONRELOC) {
  273.     luaK_reserveregs(fs, 1);
  274.     discharge2reg(fs, e, fs->freereg-1);
  275.   }
  276. }
  277. static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
  278.   discharge2reg(fs, e, reg);
  279.   if (e->k == VJMP)
  280.     luaK_concat(fs, &e->t, e->info);  /* put this jump in `t' list */
  281.   if (hasjumps(e)) {
  282.     int final;  /* position after whole expression */
  283.     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
  284.     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
  285.     if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
  286.       int fj = NO_JUMP;  /* first jump (over LOAD ops.) */
  287.       if (e->k != VJMP)
  288.         fj = luaK_jump(fs);
  289.       p_f = code_label(fs, reg, 0, 1);
  290.       p_t = code_label(fs, reg, 1, 0);
  291.       luaK_patchtohere(fs, fj);
  292.     }
  293.     final = luaK_getlabel(fs);
  294.     luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
  295.     luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
  296.   }
  297.   e->f = e->t = NO_JUMP;
  298.   e->info = reg;
  299.   e->k = VNONRELOC;
  300. }
  301. void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
  302.   luaK_dischargevars(fs, e);
  303.   freeexp(fs, e);
  304.   luaK_reserveregs(fs, 1);
  305.   luaK_exp2reg(fs, e, fs->freereg - 1);
  306. }
  307. int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
  308.   luaK_dischargevars(fs, e);
  309.   if (e->k == VNONRELOC) {
  310.     if (!hasjumps(e)) return e->info;  /* exp is already in a register */ 
  311.     if (e->info >= fs->nactvar) {  /* reg. is not a local? */
  312.       luaK_exp2reg(fs, e, e->info);  /* put value on it */
  313.       return e->info;
  314.     }
  315.   }
  316.   luaK_exp2nextreg(fs, e);  /* default */
  317.   return e->info;
  318. }
  319. void luaK_exp2val (FuncState *fs, expdesc *e) {
  320.   if (hasjumps(e))
  321.     luaK_exp2anyreg(fs, e);
  322.   else
  323.     luaK_dischargevars(fs, e);
  324. }
  325. int luaK_exp2RK (FuncState *fs, expdesc *e) {
  326.   luaK_exp2val(fs, e);
  327.   switch (e->k) {
  328.     case VNIL: {
  329.       if (fs->nk + MAXSTACK <= MAXARG_C) {  /* constant fit in argC? */
  330.         e->info = nil_constant(fs);
  331.         e->k = VK;
  332.         return e->info + MAXSTACK;
  333.       }
  334.       else break;
  335.     }
  336.     case VK: {
  337.       if (e->info + MAXSTACK <= MAXARG_C)  /* constant fit in argC? */
  338.         return e->info + MAXSTACK;
  339.       else break;
  340.     }
  341.     default: break;
  342.   }
  343.   /* not a constant in the right range: put it in a register */
  344.   return luaK_exp2anyreg(fs, e);
  345. }
  346. void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
  347.   switch (var->k) {
  348.     case VLOCAL: {
  349.       freeexp(fs, exp);
  350.       luaK_exp2reg(fs, exp, var->info);
  351.       return;
  352.     }
  353.     case VUPVAL: {
  354.       int e = luaK_exp2anyreg(fs, exp);
  355.       luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
  356.       break;
  357.     }
  358.     case VGLOBAL: {
  359.       int e = luaK_exp2anyreg(fs, exp);
  360.       luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
  361.       break;
  362.     }
  363.     case VINDEXED: {
  364.       int e = luaK_exp2RK(fs, exp);
  365.       luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
  366.       break;
  367.     }
  368.     default: {
  369.       lua_assert(0);  /* invalid var kind to store */
  370.       break;
  371.     }
  372.   }
  373.   freeexp(fs, exp);
  374. }
  375. void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
  376.   int func;
  377.   luaK_exp2anyreg(fs, e);
  378.   freeexp(fs, e);
  379.   func = fs->freereg;
  380.   luaK_reserveregs(fs, 2);
  381.   luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
  382.   freeexp(fs, key);
  383.   e->info = func;
  384.   e->k = VNONRELOC;
  385. }
  386. static void invertjump (FuncState *fs, expdesc *e) {
  387.   Instruction *pc = getjumpcontrol(fs, e->info);
  388.   lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
  389.              GET_OPCODE(*pc) != OP_TEST);
  390.   SETARG_A(*pc, !(GETARG_A(*pc)));
  391. }
  392. static int jumponcond (FuncState *fs, expdesc *e, int cond) {
  393.   if (e->k == VRELOCABLE) {
  394.     Instruction ie = getcode(fs, e);
  395.     if (GET_OPCODE(ie) == OP_NOT) {
  396.       fs->pc--;  /* remove previous OP_NOT */
  397.       return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
  398.     }
  399.     /* else go through */
  400.   }
  401.   discharge2anyreg(fs, e);
  402.   freeexp(fs, e);
  403.   return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
  404. }
  405. void luaK_goiftrue (FuncState *fs, expdesc *e) {
  406.   int pc;  /* pc of last jump */
  407.   luaK_dischargevars(fs, e);
  408.   switch (e->k) {
  409.     case VK: case VTRUE: {
  410.       pc = NO_JUMP;  /* always true; do nothing */
  411.       break;
  412.     }
  413.     case VFALSE: {
  414.       pc = luaK_jump(fs);  /* always jump */
  415.       break;
  416.     }
  417.     case VJMP: {
  418.       invertjump(fs, e);
  419.       pc = e->info;
  420.       break;
  421.     }
  422.     default: {
  423.       pc = jumponcond(fs, e, 0);
  424.       break;
  425.     }
  426.   }
  427.   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
  428. }
  429. void luaK_goiffalse (FuncState *fs, expdesc *e) {
  430.   int pc;  /* pc of last jump */
  431.   luaK_dischargevars(fs, e);
  432.   switch (e->k) {
  433.     case VNIL: case VFALSE: {
  434.       pc = NO_JUMP;  /* always false; do nothing */
  435.       break;
  436.     }
  437.     case VTRUE: {
  438.       pc = luaK_jump(fs);  /* always jump */
  439.       break;
  440.     }
  441.     case VJMP: {
  442.       pc = e->info;
  443.       break;
  444.     }
  445.     default: {
  446.       pc = jumponcond(fs, e, 1);
  447.       break;
  448.     }
  449.   }
  450.   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
  451. }
  452. static void codenot (FuncState *fs, expdesc *e) {
  453.   luaK_dischargevars(fs, e);
  454.   switch (e->k) {
  455.     case VNIL: case VFALSE: {
  456.       e->k = VTRUE;
  457.       break;
  458.     }
  459.     case VK: case VTRUE: {
  460.       e->k = VFALSE;
  461.       break;
  462.     }
  463.     case VJMP: {
  464.       invertjump(fs, e);
  465.       break;
  466.     }
  467.     case VRELOCABLE:
  468.     case VNONRELOC: {
  469.       discharge2anyreg(fs, e);
  470.       freeexp(fs, e);
  471.       e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
  472.       e->k = VRELOCABLE;
  473.       break;
  474.     }
  475.     default: {
  476.       lua_assert(0);  /* cannot happen */
  477.       break;
  478.     }
  479.   }
  480.   /* interchange true and false lists */
  481.   { int temp = e->f; e->f = e->t; e->t = temp; }
  482. }
  483. void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
  484.   t->aux = luaK_exp2RK(fs, k);
  485.   t->k = VINDEXED;
  486. }
  487. void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
  488.   if (op == OPR_MINUS) {
  489.     luaK_exp2val(fs, e);
  490.     if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
  491.       e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
  492.     else {
  493.       luaK_exp2anyreg(fs, e);
  494.       freeexp(fs, e);
  495.       e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
  496.       e->k = VRELOCABLE;
  497.     }
  498.   }
  499.   else  /* op == NOT */
  500.     codenot(fs, e);
  501. }
  502. void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
  503.   switch (op) {
  504.     case OPR_AND: {
  505.       luaK_goiftrue(fs, v);
  506.       luaK_patchtohere(fs, v->t);
  507.       v->t = NO_JUMP;
  508.       break;
  509.     }
  510.     case OPR_OR: {
  511.       luaK_goiffalse(fs, v);
  512.       luaK_patchtohere(fs, v->f);
  513.       v->f = NO_JUMP;
  514.       break;
  515.     }
  516.     case OPR_CONCAT: {
  517.       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
  518.       break;
  519.     }
  520.     default: {
  521.       luaK_exp2RK(fs, v);
  522.       break;
  523.     }
  524.   }
  525. }
  526. static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
  527.                        int o1, int o2) {
  528.   if (op <= OPR_POW) {  /* arithmetic operator? */
  529.     OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD);  /* ORDER OP */
  530.     res->info = luaK_codeABC(fs, opc, 0, o1, o2);
  531.     res->k = VRELOCABLE;
  532.   }
  533.   else {  /* test operator */
  534.     static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
  535.     int cond = 1;
  536.     if (op >= OPR_GT) {  /* `>' or `>='? */
  537.       int temp;  /* exchange args and replace by `<' or `<=' */
  538.       temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
  539.     }
  540.     else if (op == OPR_NE) cond = 0;
  541.     res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
  542.     res->k = VJMP;
  543.   }
  544. }
  545. void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
  546.   switch (op) {
  547.     case OPR_AND: {
  548.       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
  549.       luaK_dischargevars(fs, e2);
  550.       luaK_concat(fs, &e1->f, e2->f);
  551.       e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
  552.       break;
  553.     }
  554.     case OPR_OR: {
  555.       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
  556.       luaK_dischargevars(fs, e2);
  557.       luaK_concat(fs, &e1->t, e2->t);
  558.       e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
  559.       break;
  560.     }
  561.     case OPR_CONCAT: {
  562.       luaK_exp2val(fs, e2);
  563.       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
  564.         lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
  565.         freeexp(fs, e1);
  566.         SETARG_B(getcode(fs, e2), e1->info);
  567.         e1->k = e2->k; e1->info = e2->info;
  568.       }
  569.       else {
  570.         luaK_exp2nextreg(fs, e2);
  571.         freeexp(fs, e2);
  572.         freeexp(fs, e1);
  573.         e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
  574.         e1->k = VRELOCABLE;
  575.       }
  576.       break;
  577.     }
  578.     default: {
  579.       int o1 = luaK_exp2RK(fs, e1);
  580.       int o2 = luaK_exp2RK(fs, e2);
  581.       freeexp(fs, e2);
  582.       freeexp(fs, e1);
  583.       codebinop(fs, e1, op, o1, o2);
  584.     }
  585.   }
  586. }
  587. void luaK_fixline (FuncState *fs, int line) {
  588.   fs->f->lineinfo[fs->pc - 1] = line;
  589. }
  590. int luaK_code (FuncState *fs, Instruction i, int line) {
  591.   Proto *f = fs->f;
  592.   luaK_dischargejpc(fs);  /* `pc' will change */
  593.   /* put new instruction in code array */
  594.   luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
  595.                   MAX_INT, "code size overflow");
  596.   f->code[fs->pc] = i;
  597.   /* save corresponding line information */
  598.   luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
  599.                   MAX_INT, "code size overflow");
  600.   f->lineinfo[fs->pc] = line;
  601.   return fs->pc++;
  602. }
  603. int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
  604.   lua_assert(getOpMode(o) == iABC);
  605.   return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
  606. }
  607. int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
  608.   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
  609.   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
  610. }