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