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