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