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