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