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
32static int isnumeral(expdesc *e) {
33  return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
34}
35
36
37void 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
59int 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
69void luaK_ret (FuncState *fs, int first, int nret) {
70  luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
71}
72
73
74static 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
80static 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*/
94int luaK_getlabel (FuncState *fs) {
95  fs->lasttarget = fs->pc;
96  return fs->pc;
97}
98
99
100static 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
109static 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*/
122static 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
131static 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
144static void removevalues (FuncState *fs, int list) {
145  for (; list != NO_JUMP; list = getjump(fs, list))
146      patchtestreg(fs, list, NO_REG);
147}
148
149
150static 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
163static void dischargejpc (FuncState *fs) {
164  patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
165  fs->jpc = NO_JUMP;
166}
167
168
169void 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
179LUAI_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
192void luaK_patchtohere (FuncState *fs, int list) {
193  luaK_getlabel(fs);
194  luaK_concat(fs, &fs->jpc, list);
195}
196
197
198void 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
212static 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
227int 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
236int 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
244static 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
250int 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
261void 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
271void luaK_reserveregs (FuncState *fs, int n) {
272  luaK_checkstack(fs, n);
273  fs->freereg += n;
274}
275
276
277static 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
285static void freeexp (FuncState *fs, expdesc *e) {
286  if (e->k == VNONRELOC)
287    freereg(fs, e->u.info);
288}
289
290
291static 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
319int 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
326int 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
343static int boolK (FuncState *fs, int b) {
344  TValue o;
345  setbvalue(&o, b);
346  return addk(fs, &o, &o);
347}
348
349
350static 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
359void 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
371void 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
383void 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
415static 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
421static 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
460static 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
468static 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
492void 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
500int 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
514void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
515  if (e->k != VUPVAL || hasjumps(e))
516    luaK_exp2anyreg(fs, e);
517}
518
519
520void 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
528int 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
558void 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
585void 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
598static 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
606static 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
621void 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
645void 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
668static 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
703void 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
713static 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
724static 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
746static 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
762void 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
786void 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
813void 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
862void luaK_fixline (FuncState *fs, int line) {
863  fs->f->lineinfo[fs->pc - 1] = line;
864}
865
866
867void 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