xref: /aosp_15_r20/external/lua/src/lcode.c (revision 088332b5b69e7ab13924864b272aabfc2509d2d5)
1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: lcode.c $
3*088332b5SXin Li ** Code generator for Lua
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li 
7*088332b5SXin Li #define lcode_c
8*088332b5SXin Li #define LUA_CORE
9*088332b5SXin Li 
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li 
12*088332b5SXin Li 
13*088332b5SXin Li #include <limits.h>
14*088332b5SXin Li #include <math.h>
15*088332b5SXin Li #include <stdlib.h>
16*088332b5SXin Li 
17*088332b5SXin Li #include "lua.h"
18*088332b5SXin Li 
19*088332b5SXin Li #include "lcode.h"
20*088332b5SXin Li #include "ldebug.h"
21*088332b5SXin Li #include "ldo.h"
22*088332b5SXin Li #include "lgc.h"
23*088332b5SXin Li #include "llex.h"
24*088332b5SXin Li #include "lmem.h"
25*088332b5SXin Li #include "lobject.h"
26*088332b5SXin Li #include "lopcodes.h"
27*088332b5SXin Li #include "lparser.h"
28*088332b5SXin Li #include "lstring.h"
29*088332b5SXin Li #include "ltable.h"
30*088332b5SXin Li #include "lvm.h"
31*088332b5SXin Li 
32*088332b5SXin Li 
33*088332b5SXin Li /* Maximum number of registers in a Lua function (must fit in 8 bits) */
34*088332b5SXin Li #define MAXREGS		255
35*088332b5SXin Li 
36*088332b5SXin Li 
37*088332b5SXin Li #define hasjumps(e)	((e)->t != (e)->f)
38*088332b5SXin Li 
39*088332b5SXin Li 
40*088332b5SXin Li static int codesJ (FuncState *fs, OpCode o, int sj, int k);
41*088332b5SXin Li 
42*088332b5SXin Li 
43*088332b5SXin Li 
44*088332b5SXin Li /* semantic error */
luaK_semerror(LexState * ls,const char * msg)45*088332b5SXin Li l_noret luaK_semerror (LexState *ls, const char *msg) {
46*088332b5SXin Li   ls->t.token = 0;  /* remove "near <token>" from final message */
47*088332b5SXin Li   luaX_syntaxerror(ls, msg);
48*088332b5SXin Li }
49*088332b5SXin Li 
50*088332b5SXin Li 
51*088332b5SXin Li /*
52*088332b5SXin Li ** If expression is a numeric constant, fills 'v' with its value
53*088332b5SXin Li ** and returns 1. Otherwise, returns 0.
54*088332b5SXin Li */
tonumeral(const expdesc * e,TValue * v)55*088332b5SXin Li static int tonumeral (const expdesc *e, TValue *v) {
56*088332b5SXin Li   if (hasjumps(e))
57*088332b5SXin Li     return 0;  /* not a numeral */
58*088332b5SXin Li   switch (e->k) {
59*088332b5SXin Li     case VKINT:
60*088332b5SXin Li       if (v) setivalue(v, e->u.ival);
61*088332b5SXin Li       return 1;
62*088332b5SXin Li     case VKFLT:
63*088332b5SXin Li       if (v) setfltvalue(v, e->u.nval);
64*088332b5SXin Li       return 1;
65*088332b5SXin Li     default: return 0;
66*088332b5SXin Li   }
67*088332b5SXin Li }
68*088332b5SXin Li 
69*088332b5SXin Li 
70*088332b5SXin Li /*
71*088332b5SXin Li ** Get the constant value from a constant expression
72*088332b5SXin Li */
const2val(FuncState * fs,const expdesc * e)73*088332b5SXin Li static TValue *const2val (FuncState *fs, const expdesc *e) {
74*088332b5SXin Li   lua_assert(e->k == VCONST);
75*088332b5SXin Li   return &fs->ls->dyd->actvar.arr[e->u.info].k;
76*088332b5SXin Li }
77*088332b5SXin Li 
78*088332b5SXin Li 
79*088332b5SXin Li /*
80*088332b5SXin Li ** If expression is a constant, fills 'v' with its value
81*088332b5SXin Li ** and returns 1. Otherwise, returns 0.
82*088332b5SXin Li */
luaK_exp2const(FuncState * fs,const expdesc * e,TValue * v)83*088332b5SXin Li int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
84*088332b5SXin Li   if (hasjumps(e))
85*088332b5SXin Li     return 0;  /* not a constant */
86*088332b5SXin Li   switch (e->k) {
87*088332b5SXin Li     case VFALSE:
88*088332b5SXin Li       setbfvalue(v);
89*088332b5SXin Li       return 1;
90*088332b5SXin Li     case VTRUE:
91*088332b5SXin Li       setbtvalue(v);
92*088332b5SXin Li       return 1;
93*088332b5SXin Li     case VNIL:
94*088332b5SXin Li       setnilvalue(v);
95*088332b5SXin Li       return 1;
96*088332b5SXin Li     case VKSTR: {
97*088332b5SXin Li       setsvalue(fs->ls->L, v, e->u.strval);
98*088332b5SXin Li       return 1;
99*088332b5SXin Li     }
100*088332b5SXin Li     case VCONST: {
101*088332b5SXin Li       setobj(fs->ls->L, v, const2val(fs, e));
102*088332b5SXin Li       return 1;
103*088332b5SXin Li     }
104*088332b5SXin Li     default: return tonumeral(e, v);
105*088332b5SXin Li   }
106*088332b5SXin Li }
107*088332b5SXin Li 
108*088332b5SXin Li 
109*088332b5SXin Li /*
110*088332b5SXin Li ** Return the previous instruction of the current code. If there
111*088332b5SXin Li ** may be a jump target between the current instruction and the
112*088332b5SXin Li ** previous one, return an invalid instruction (to avoid wrong
113*088332b5SXin Li ** optimizations).
114*088332b5SXin Li */
previousinstruction(FuncState * fs)115*088332b5SXin Li static Instruction *previousinstruction (FuncState *fs) {
116*088332b5SXin Li   static const Instruction invalidinstruction = ~(Instruction)0;
117*088332b5SXin Li   if (fs->pc > fs->lasttarget)
118*088332b5SXin Li     return &fs->f->code[fs->pc - 1];  /* previous instruction */
119*088332b5SXin Li   else
120*088332b5SXin Li     return cast(Instruction*, &invalidinstruction);
121*088332b5SXin Li }
122*088332b5SXin Li 
123*088332b5SXin Li 
124*088332b5SXin Li /*
125*088332b5SXin Li ** Create a OP_LOADNIL instruction, but try to optimize: if the previous
126*088332b5SXin Li ** instruction is also OP_LOADNIL and ranges are compatible, adjust
127*088332b5SXin Li ** range of previous instruction instead of emitting a new one. (For
128*088332b5SXin Li ** instance, 'local a; local b' will generate a single opcode.)
129*088332b5SXin Li */
luaK_nil(FuncState * fs,int from,int n)130*088332b5SXin Li void luaK_nil (FuncState *fs, int from, int n) {
131*088332b5SXin Li   int l = from + n - 1;  /* last register to set nil */
132*088332b5SXin Li   Instruction *previous = previousinstruction(fs);
133*088332b5SXin Li   if (GET_OPCODE(*previous) == OP_LOADNIL) {  /* previous is LOADNIL? */
134*088332b5SXin Li     int pfrom = GETARG_A(*previous);  /* get previous range */
135*088332b5SXin Li     int pl = pfrom + GETARG_B(*previous);
136*088332b5SXin Li     if ((pfrom <= from && from <= pl + 1) ||
137*088332b5SXin Li         (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
138*088332b5SXin Li       if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
139*088332b5SXin Li       if (pl > l) l = pl;  /* l = max(l, pl) */
140*088332b5SXin Li       SETARG_A(*previous, from);
141*088332b5SXin Li       SETARG_B(*previous, l - from);
142*088332b5SXin Li       return;
143*088332b5SXin Li     }  /* else go through */
144*088332b5SXin Li   }
145*088332b5SXin Li   luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
146*088332b5SXin Li }
147*088332b5SXin Li 
148*088332b5SXin Li 
149*088332b5SXin Li /*
150*088332b5SXin Li ** Gets the destination address of a jump instruction. Used to traverse
151*088332b5SXin Li ** a list of jumps.
152*088332b5SXin Li */
getjump(FuncState * fs,int pc)153*088332b5SXin Li static int getjump (FuncState *fs, int pc) {
154*088332b5SXin Li   int offset = GETARG_sJ(fs->f->code[pc]);
155*088332b5SXin Li   if (offset == NO_JUMP)  /* point to itself represents end of list */
156*088332b5SXin Li     return NO_JUMP;  /* end of list */
157*088332b5SXin Li   else
158*088332b5SXin Li     return (pc+1)+offset;  /* turn offset into absolute position */
159*088332b5SXin Li }
160*088332b5SXin Li 
161*088332b5SXin Li 
162*088332b5SXin Li /*
163*088332b5SXin Li ** Fix jump instruction at position 'pc' to jump to 'dest'.
164*088332b5SXin Li ** (Jump addresses are relative in Lua)
165*088332b5SXin Li */
fixjump(FuncState * fs,int pc,int dest)166*088332b5SXin Li static void fixjump (FuncState *fs, int pc, int dest) {
167*088332b5SXin Li   Instruction *jmp = &fs->f->code[pc];
168*088332b5SXin Li   int offset = dest - (pc + 1);
169*088332b5SXin Li   lua_assert(dest != NO_JUMP);
170*088332b5SXin Li   if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ))
171*088332b5SXin Li     luaX_syntaxerror(fs->ls, "control structure too long");
172*088332b5SXin Li   lua_assert(GET_OPCODE(*jmp) == OP_JMP);
173*088332b5SXin Li   SETARG_sJ(*jmp, offset);
174*088332b5SXin Li }
175*088332b5SXin Li 
176*088332b5SXin Li 
177*088332b5SXin Li /*
178*088332b5SXin Li ** Concatenate jump-list 'l2' into jump-list 'l1'
179*088332b5SXin Li */
luaK_concat(FuncState * fs,int * l1,int l2)180*088332b5SXin Li void luaK_concat (FuncState *fs, int *l1, int l2) {
181*088332b5SXin Li   if (l2 == NO_JUMP) return;  /* nothing to concatenate? */
182*088332b5SXin Li   else if (*l1 == NO_JUMP)  /* no original list? */
183*088332b5SXin Li     *l1 = l2;  /* 'l1' points to 'l2' */
184*088332b5SXin Li   else {
185*088332b5SXin Li     int list = *l1;
186*088332b5SXin Li     int next;
187*088332b5SXin Li     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
188*088332b5SXin Li       list = next;
189*088332b5SXin Li     fixjump(fs, list, l2);  /* last element links to 'l2' */
190*088332b5SXin Li   }
191*088332b5SXin Li }
192*088332b5SXin Li 
193*088332b5SXin Li 
194*088332b5SXin Li /*
195*088332b5SXin Li ** Create a jump instruction and return its position, so its destination
196*088332b5SXin Li ** can be fixed later (with 'fixjump').
197*088332b5SXin Li */
luaK_jump(FuncState * fs)198*088332b5SXin Li int luaK_jump (FuncState *fs) {
199*088332b5SXin Li   return codesJ(fs, OP_JMP, NO_JUMP, 0);
200*088332b5SXin Li }
201*088332b5SXin Li 
202*088332b5SXin Li 
203*088332b5SXin Li /*
204*088332b5SXin Li ** Code a 'return' instruction
205*088332b5SXin Li */
luaK_ret(FuncState * fs,int first,int nret)206*088332b5SXin Li void luaK_ret (FuncState *fs, int first, int nret) {
207*088332b5SXin Li   OpCode op;
208*088332b5SXin Li   switch (nret) {
209*088332b5SXin Li     case 0: op = OP_RETURN0; break;
210*088332b5SXin Li     case 1: op = OP_RETURN1; break;
211*088332b5SXin Li     default: op = OP_RETURN; break;
212*088332b5SXin Li   }
213*088332b5SXin Li   luaK_codeABC(fs, op, first, nret + 1, 0);
214*088332b5SXin Li }
215*088332b5SXin Li 
216*088332b5SXin Li 
217*088332b5SXin Li /*
218*088332b5SXin Li ** Code a "conditional jump", that is, a test or comparison opcode
219*088332b5SXin Li ** followed by a jump. Return jump position.
220*088332b5SXin Li */
condjump(FuncState * fs,OpCode op,int A,int B,int C,int k)221*088332b5SXin Li static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) {
222*088332b5SXin Li   luaK_codeABCk(fs, op, A, B, C, k);
223*088332b5SXin Li   return luaK_jump(fs);
224*088332b5SXin Li }
225*088332b5SXin Li 
226*088332b5SXin Li 
227*088332b5SXin Li /*
228*088332b5SXin Li ** returns current 'pc' and marks it as a jump target (to avoid wrong
229*088332b5SXin Li ** optimizations with consecutive instructions not in the same basic block).
230*088332b5SXin Li */
luaK_getlabel(FuncState * fs)231*088332b5SXin Li int luaK_getlabel (FuncState *fs) {
232*088332b5SXin Li   fs->lasttarget = fs->pc;
233*088332b5SXin Li   return fs->pc;
234*088332b5SXin Li }
235*088332b5SXin Li 
236*088332b5SXin Li 
237*088332b5SXin Li /*
238*088332b5SXin Li ** Returns the position of the instruction "controlling" a given
239*088332b5SXin Li ** jump (that is, its condition), or the jump itself if it is
240*088332b5SXin Li ** unconditional.
241*088332b5SXin Li */
getjumpcontrol(FuncState * fs,int pc)242*088332b5SXin Li static Instruction *getjumpcontrol (FuncState *fs, int pc) {
243*088332b5SXin Li   Instruction *pi = &fs->f->code[pc];
244*088332b5SXin Li   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
245*088332b5SXin Li     return pi-1;
246*088332b5SXin Li   else
247*088332b5SXin Li     return pi;
248*088332b5SXin Li }
249*088332b5SXin Li 
250*088332b5SXin Li 
251*088332b5SXin Li /*
252*088332b5SXin Li ** Patch destination register for a TESTSET instruction.
253*088332b5SXin Li ** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
254*088332b5SXin Li ** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
255*088332b5SXin Li ** register. Otherwise, change instruction to a simple 'TEST' (produces
256*088332b5SXin Li ** no register value)
257*088332b5SXin Li */
patchtestreg(FuncState * fs,int node,int reg)258*088332b5SXin Li static int patchtestreg (FuncState *fs, int node, int reg) {
259*088332b5SXin Li   Instruction *i = getjumpcontrol(fs, node);
260*088332b5SXin Li   if (GET_OPCODE(*i) != OP_TESTSET)
261*088332b5SXin Li     return 0;  /* cannot patch other instructions */
262*088332b5SXin Li   if (reg != NO_REG && reg != GETARG_B(*i))
263*088332b5SXin Li     SETARG_A(*i, reg);
264*088332b5SXin Li   else {
265*088332b5SXin Li      /* no register to put value or register already has the value;
266*088332b5SXin Li         change instruction to simple test */
267*088332b5SXin Li     *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i));
268*088332b5SXin Li   }
269*088332b5SXin Li   return 1;
270*088332b5SXin Li }
271*088332b5SXin Li 
272*088332b5SXin Li 
273*088332b5SXin Li /*
274*088332b5SXin Li ** Traverse a list of tests ensuring no one produces a value
275*088332b5SXin Li */
removevalues(FuncState * fs,int list)276*088332b5SXin Li static void removevalues (FuncState *fs, int list) {
277*088332b5SXin Li   for (; list != NO_JUMP; list = getjump(fs, list))
278*088332b5SXin Li       patchtestreg(fs, list, NO_REG);
279*088332b5SXin Li }
280*088332b5SXin Li 
281*088332b5SXin Li 
282*088332b5SXin Li /*
283*088332b5SXin Li ** Traverse a list of tests, patching their destination address and
284*088332b5SXin Li ** registers: tests producing values jump to 'vtarget' (and put their
285*088332b5SXin Li ** values in 'reg'), other tests jump to 'dtarget'.
286*088332b5SXin Li */
patchlistaux(FuncState * fs,int list,int vtarget,int reg,int dtarget)287*088332b5SXin Li static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
288*088332b5SXin Li                           int dtarget) {
289*088332b5SXin Li   while (list != NO_JUMP) {
290*088332b5SXin Li     int next = getjump(fs, list);
291*088332b5SXin Li     if (patchtestreg(fs, list, reg))
292*088332b5SXin Li       fixjump(fs, list, vtarget);
293*088332b5SXin Li     else
294*088332b5SXin Li       fixjump(fs, list, dtarget);  /* jump to default target */
295*088332b5SXin Li     list = next;
296*088332b5SXin Li   }
297*088332b5SXin Li }
298*088332b5SXin Li 
299*088332b5SXin Li 
300*088332b5SXin Li /*
301*088332b5SXin Li ** Path all jumps in 'list' to jump to 'target'.
302*088332b5SXin Li ** (The assert means that we cannot fix a jump to a forward address
303*088332b5SXin Li ** because we only know addresses once code is generated.)
304*088332b5SXin Li */
luaK_patchlist(FuncState * fs,int list,int target)305*088332b5SXin Li void luaK_patchlist (FuncState *fs, int list, int target) {
306*088332b5SXin Li   lua_assert(target <= fs->pc);
307*088332b5SXin Li   patchlistaux(fs, list, target, NO_REG, target);
308*088332b5SXin Li }
309*088332b5SXin Li 
310*088332b5SXin Li 
luaK_patchtohere(FuncState * fs,int list)311*088332b5SXin Li void luaK_patchtohere (FuncState *fs, int list) {
312*088332b5SXin Li   int hr = luaK_getlabel(fs);  /* mark "here" as a jump target */
313*088332b5SXin Li   luaK_patchlist(fs, list, hr);
314*088332b5SXin Li }
315*088332b5SXin Li 
316*088332b5SXin Li 
317*088332b5SXin Li /*
318*088332b5SXin Li ** MAXimum number of successive Instructions WiTHout ABSolute line
319*088332b5SXin Li ** information.
320*088332b5SXin Li */
321*088332b5SXin Li #if !defined(MAXIWTHABS)
322*088332b5SXin Li #define MAXIWTHABS	120
323*088332b5SXin Li #endif
324*088332b5SXin Li 
325*088332b5SXin Li 
326*088332b5SXin Li /* limit for difference between lines in relative line info. */
327*088332b5SXin Li #define LIMLINEDIFF	0x80
328*088332b5SXin Li 
329*088332b5SXin Li 
330*088332b5SXin Li /*
331*088332b5SXin Li ** Save line info for a new instruction. If difference from last line
332*088332b5SXin Li ** does not fit in a byte, of after that many instructions, save a new
333*088332b5SXin Li ** absolute line info; (in that case, the special value 'ABSLINEINFO'
334*088332b5SXin Li ** in 'lineinfo' signals the existence of this absolute information.)
335*088332b5SXin Li ** Otherwise, store the difference from last line in 'lineinfo'.
336*088332b5SXin Li */
savelineinfo(FuncState * fs,Proto * f,int line)337*088332b5SXin Li static void savelineinfo (FuncState *fs, Proto *f, int line) {
338*088332b5SXin Li   int linedif = line - fs->previousline;
339*088332b5SXin Li   int pc = fs->pc - 1;  /* last instruction coded */
340*088332b5SXin Li   if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) {
341*088332b5SXin Li     luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo,
342*088332b5SXin Li                     f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines");
343*088332b5SXin Li     f->abslineinfo[fs->nabslineinfo].pc = pc;
344*088332b5SXin Li     f->abslineinfo[fs->nabslineinfo++].line = line;
345*088332b5SXin Li     linedif = ABSLINEINFO;  /* signal that there is absolute information */
346*088332b5SXin Li     fs->iwthabs = 0;  /* restart counter */
347*088332b5SXin Li   }
348*088332b5SXin Li   luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte,
349*088332b5SXin Li                   MAX_INT, "opcodes");
350*088332b5SXin Li   f->lineinfo[pc] = linedif;
351*088332b5SXin Li   fs->previousline = line;  /* last line saved */
352*088332b5SXin Li }
353*088332b5SXin Li 
354*088332b5SXin Li 
355*088332b5SXin Li /*
356*088332b5SXin Li ** Remove line information from the last instruction.
357*088332b5SXin Li ** If line information for that instruction is absolute, set 'iwthabs'
358*088332b5SXin Li ** above its max to force the new (replacing) instruction to have
359*088332b5SXin Li ** absolute line info, too.
360*088332b5SXin Li */
removelastlineinfo(FuncState * fs)361*088332b5SXin Li static void removelastlineinfo (FuncState *fs) {
362*088332b5SXin Li   Proto *f = fs->f;
363*088332b5SXin Li   int pc = fs->pc - 1;  /* last instruction coded */
364*088332b5SXin Li   if (f->lineinfo[pc] != ABSLINEINFO) {  /* relative line info? */
365*088332b5SXin Li     fs->previousline -= f->lineinfo[pc];  /* correct last line saved */
366*088332b5SXin Li     fs->iwthabs--;  /* undo previous increment */
367*088332b5SXin Li   }
368*088332b5SXin Li   else {  /* absolute line information */
369*088332b5SXin Li     lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc);
370*088332b5SXin Li     fs->nabslineinfo--;  /* remove it */
371*088332b5SXin Li     fs->iwthabs = MAXIWTHABS + 1;  /* force next line info to be absolute */
372*088332b5SXin Li   }
373*088332b5SXin Li }
374*088332b5SXin Li 
375*088332b5SXin Li 
376*088332b5SXin Li /*
377*088332b5SXin Li ** Remove the last instruction created, correcting line information
378*088332b5SXin Li ** accordingly.
379*088332b5SXin Li */
removelastinstruction(FuncState * fs)380*088332b5SXin Li static void removelastinstruction (FuncState *fs) {
381*088332b5SXin Li   removelastlineinfo(fs);
382*088332b5SXin Li   fs->pc--;
383*088332b5SXin Li }
384*088332b5SXin Li 
385*088332b5SXin Li 
386*088332b5SXin Li /*
387*088332b5SXin Li ** Emit instruction 'i', checking for array sizes and saving also its
388*088332b5SXin Li ** line information. Return 'i' position.
389*088332b5SXin Li */
luaK_code(FuncState * fs,Instruction i)390*088332b5SXin Li int luaK_code (FuncState *fs, Instruction i) {
391*088332b5SXin Li   Proto *f = fs->f;
392*088332b5SXin Li   /* put new instruction in code array */
393*088332b5SXin Li   luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
394*088332b5SXin Li                   MAX_INT, "opcodes");
395*088332b5SXin Li   f->code[fs->pc++] = i;
396*088332b5SXin Li   savelineinfo(fs, f, fs->ls->lastline);
397*088332b5SXin Li   return fs->pc - 1;  /* index of new instruction */
398*088332b5SXin Li }
399*088332b5SXin Li 
400*088332b5SXin Li 
401*088332b5SXin Li /*
402*088332b5SXin Li ** Format and emit an 'iABC' instruction. (Assertions check consistency
403*088332b5SXin Li ** of parameters versus opcode.)
404*088332b5SXin Li */
luaK_codeABCk(FuncState * fs,OpCode o,int a,int b,int c,int k)405*088332b5SXin Li int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) {
406*088332b5SXin Li   lua_assert(getOpMode(o) == iABC);
407*088332b5SXin Li   lua_assert(a <= MAXARG_A && b <= MAXARG_B &&
408*088332b5SXin Li              c <= MAXARG_C && (k & ~1) == 0);
409*088332b5SXin Li   return luaK_code(fs, CREATE_ABCk(o, a, b, c, k));
410*088332b5SXin Li }
411*088332b5SXin Li 
412*088332b5SXin Li 
413*088332b5SXin Li /*
414*088332b5SXin Li ** Format and emit an 'iABx' instruction.
415*088332b5SXin Li */
luaK_codeABx(FuncState * fs,OpCode o,int a,unsigned int bc)416*088332b5SXin Li int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
417*088332b5SXin Li   lua_assert(getOpMode(o) == iABx);
418*088332b5SXin Li   lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
419*088332b5SXin Li   return luaK_code(fs, CREATE_ABx(o, a, bc));
420*088332b5SXin Li }
421*088332b5SXin Li 
422*088332b5SXin Li 
423*088332b5SXin Li /*
424*088332b5SXin Li ** Format and emit an 'iAsBx' instruction.
425*088332b5SXin Li */
luaK_codeAsBx(FuncState * fs,OpCode o,int a,int bc)426*088332b5SXin Li int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
427*088332b5SXin Li   unsigned int b = bc + OFFSET_sBx;
428*088332b5SXin Li   lua_assert(getOpMode(o) == iAsBx);
429*088332b5SXin Li   lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
430*088332b5SXin Li   return luaK_code(fs, CREATE_ABx(o, a, b));
431*088332b5SXin Li }
432*088332b5SXin Li 
433*088332b5SXin Li 
434*088332b5SXin Li /*
435*088332b5SXin Li ** Format and emit an 'isJ' instruction.
436*088332b5SXin Li */
codesJ(FuncState * fs,OpCode o,int sj,int k)437*088332b5SXin Li static int codesJ (FuncState *fs, OpCode o, int sj, int k) {
438*088332b5SXin Li   unsigned int j = sj + OFFSET_sJ;
439*088332b5SXin Li   lua_assert(getOpMode(o) == isJ);
440*088332b5SXin Li   lua_assert(j <= MAXARG_sJ && (k & ~1) == 0);
441*088332b5SXin Li   return luaK_code(fs, CREATE_sJ(o, j, k));
442*088332b5SXin Li }
443*088332b5SXin Li 
444*088332b5SXin Li 
445*088332b5SXin Li /*
446*088332b5SXin Li ** Emit an "extra argument" instruction (format 'iAx')
447*088332b5SXin Li */
codeextraarg(FuncState * fs,int a)448*088332b5SXin Li static int codeextraarg (FuncState *fs, int a) {
449*088332b5SXin Li   lua_assert(a <= MAXARG_Ax);
450*088332b5SXin Li   return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
451*088332b5SXin Li }
452*088332b5SXin Li 
453*088332b5SXin Li 
454*088332b5SXin Li /*
455*088332b5SXin Li ** Emit a "load constant" instruction, using either 'OP_LOADK'
456*088332b5SXin Li ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
457*088332b5SXin Li ** instruction with "extra argument".
458*088332b5SXin Li */
luaK_codek(FuncState * fs,int reg,int k)459*088332b5SXin Li static int luaK_codek (FuncState *fs, int reg, int k) {
460*088332b5SXin Li   if (k <= MAXARG_Bx)
461*088332b5SXin Li     return luaK_codeABx(fs, OP_LOADK, reg, k);
462*088332b5SXin Li   else {
463*088332b5SXin Li     int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
464*088332b5SXin Li     codeextraarg(fs, k);
465*088332b5SXin Li     return p;
466*088332b5SXin Li   }
467*088332b5SXin Li }
468*088332b5SXin Li 
469*088332b5SXin Li 
470*088332b5SXin Li /*
471*088332b5SXin Li ** Check register-stack level, keeping track of its maximum size
472*088332b5SXin Li ** in field 'maxstacksize'
473*088332b5SXin Li */
luaK_checkstack(FuncState * fs,int n)474*088332b5SXin Li void luaK_checkstack (FuncState *fs, int n) {
475*088332b5SXin Li   int newstack = fs->freereg + n;
476*088332b5SXin Li   if (newstack > fs->f->maxstacksize) {
477*088332b5SXin Li     if (newstack >= MAXREGS)
478*088332b5SXin Li       luaX_syntaxerror(fs->ls,
479*088332b5SXin Li         "function or expression needs too many registers");
480*088332b5SXin Li     fs->f->maxstacksize = cast_byte(newstack);
481*088332b5SXin Li   }
482*088332b5SXin Li }
483*088332b5SXin Li 
484*088332b5SXin Li 
485*088332b5SXin Li /*
486*088332b5SXin Li ** Reserve 'n' registers in register stack
487*088332b5SXin Li */
luaK_reserveregs(FuncState * fs,int n)488*088332b5SXin Li void luaK_reserveregs (FuncState *fs, int n) {
489*088332b5SXin Li   luaK_checkstack(fs, n);
490*088332b5SXin Li   fs->freereg += n;
491*088332b5SXin Li }
492*088332b5SXin Li 
493*088332b5SXin Li 
494*088332b5SXin Li /*
495*088332b5SXin Li ** Free register 'reg', if it is neither a constant index nor
496*088332b5SXin Li ** a local variable.
497*088332b5SXin Li )
498*088332b5SXin Li */
freereg(FuncState * fs,int reg)499*088332b5SXin Li static void freereg (FuncState *fs, int reg) {
500*088332b5SXin Li   if (reg >= luaY_nvarstack(fs)) {
501*088332b5SXin Li     fs->freereg--;
502*088332b5SXin Li     lua_assert(reg == fs->freereg);
503*088332b5SXin Li   }
504*088332b5SXin Li }
505*088332b5SXin Li 
506*088332b5SXin Li 
507*088332b5SXin Li /*
508*088332b5SXin Li ** Free two registers in proper order
509*088332b5SXin Li */
freeregs(FuncState * fs,int r1,int r2)510*088332b5SXin Li static void freeregs (FuncState *fs, int r1, int r2) {
511*088332b5SXin Li   if (r1 > r2) {
512*088332b5SXin Li     freereg(fs, r1);
513*088332b5SXin Li     freereg(fs, r2);
514*088332b5SXin Li   }
515*088332b5SXin Li   else {
516*088332b5SXin Li     freereg(fs, r2);
517*088332b5SXin Li     freereg(fs, r1);
518*088332b5SXin Li   }
519*088332b5SXin Li }
520*088332b5SXin Li 
521*088332b5SXin Li 
522*088332b5SXin Li /*
523*088332b5SXin Li ** Free register used by expression 'e' (if any)
524*088332b5SXin Li */
freeexp(FuncState * fs,expdesc * e)525*088332b5SXin Li static void freeexp (FuncState *fs, expdesc *e) {
526*088332b5SXin Li   if (e->k == VNONRELOC)
527*088332b5SXin Li     freereg(fs, e->u.info);
528*088332b5SXin Li }
529*088332b5SXin Li 
530*088332b5SXin Li 
531*088332b5SXin Li /*
532*088332b5SXin Li ** Free registers used by expressions 'e1' and 'e2' (if any) in proper
533*088332b5SXin Li ** order.
534*088332b5SXin Li */
freeexps(FuncState * fs,expdesc * e1,expdesc * e2)535*088332b5SXin Li static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
536*088332b5SXin Li   int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
537*088332b5SXin Li   int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
538*088332b5SXin Li   freeregs(fs, r1, r2);
539*088332b5SXin Li }
540*088332b5SXin Li 
541*088332b5SXin Li 
542*088332b5SXin Li /*
543*088332b5SXin Li ** Add constant 'v' to prototype's list of constants (field 'k').
544*088332b5SXin Li ** Use scanner's table to cache position of constants in constant list
545*088332b5SXin Li ** and try to reuse constants. Because some values should not be used
546*088332b5SXin Li ** as keys (nil cannot be a key, integer keys can collapse with float
547*088332b5SXin Li ** keys), the caller must provide a useful 'key' for indexing the cache.
548*088332b5SXin Li */
addk(FuncState * fs,TValue * key,TValue * v)549*088332b5SXin Li static int addk (FuncState *fs, TValue *key, TValue *v) {
550*088332b5SXin Li   lua_State *L = fs->ls->L;
551*088332b5SXin Li   Proto *f = fs->f;
552*088332b5SXin Li   TValue *idx = luaH_set(L, fs->ls->h, key);  /* index scanner table */
553*088332b5SXin Li   int k, oldsize;
554*088332b5SXin Li   if (ttisinteger(idx)) {  /* is there an index there? */
555*088332b5SXin Li     k = cast_int(ivalue(idx));
556*088332b5SXin Li     /* correct value? (warning: must distinguish floats from integers!) */
557*088332b5SXin Li     if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) &&
558*088332b5SXin Li                       luaV_rawequalobj(&f->k[k], v))
559*088332b5SXin Li       return k;  /* reuse index */
560*088332b5SXin Li   }
561*088332b5SXin Li   /* constant not found; create a new entry */
562*088332b5SXin Li   oldsize = f->sizek;
563*088332b5SXin Li   k = fs->nk;
564*088332b5SXin Li   /* numerical value does not need GC barrier;
565*088332b5SXin Li      table has no metatable, so it does not need to invalidate cache */
566*088332b5SXin Li   setivalue(idx, k);
567*088332b5SXin Li   luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
568*088332b5SXin Li   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
569*088332b5SXin Li   setobj(L, &f->k[k], v);
570*088332b5SXin Li   fs->nk++;
571*088332b5SXin Li   luaC_barrier(L, f, v);
572*088332b5SXin Li   return k;
573*088332b5SXin Li }
574*088332b5SXin Li 
575*088332b5SXin Li 
576*088332b5SXin Li /*
577*088332b5SXin Li ** Add a string to list of constants and return its index.
578*088332b5SXin Li */
stringK(FuncState * fs,TString * s)579*088332b5SXin Li static int stringK (FuncState *fs, TString *s) {
580*088332b5SXin Li   TValue o;
581*088332b5SXin Li   setsvalue(fs->ls->L, &o, s);
582*088332b5SXin Li   return addk(fs, &o, &o);  /* use string itself as key */
583*088332b5SXin Li }
584*088332b5SXin Li 
585*088332b5SXin Li 
586*088332b5SXin Li /*
587*088332b5SXin Li ** Add an integer to list of constants and return its index.
588*088332b5SXin Li ** Integers use userdata as keys to avoid collision with floats with
589*088332b5SXin Li ** same value; conversion to 'void*' is used only for hashing, so there
590*088332b5SXin Li ** are no "precision" problems.
591*088332b5SXin Li */
luaK_intK(FuncState * fs,lua_Integer n)592*088332b5SXin Li static int luaK_intK (FuncState *fs, lua_Integer n) {
593*088332b5SXin Li   TValue k, o;
594*088332b5SXin Li   setpvalue(&k, cast_voidp(cast_sizet(n)));
595*088332b5SXin Li   setivalue(&o, n);
596*088332b5SXin Li   return addk(fs, &k, &o);
597*088332b5SXin Li }
598*088332b5SXin Li 
599*088332b5SXin Li /*
600*088332b5SXin Li ** Add a float to list of constants and return its index.
601*088332b5SXin Li */
luaK_numberK(FuncState * fs,lua_Number r)602*088332b5SXin Li static int luaK_numberK (FuncState *fs, lua_Number r) {
603*088332b5SXin Li   TValue o;
604*088332b5SXin Li   setfltvalue(&o, r);
605*088332b5SXin Li   return addk(fs, &o, &o);  /* use number itself as key */
606*088332b5SXin Li }
607*088332b5SXin Li 
608*088332b5SXin Li 
609*088332b5SXin Li /*
610*088332b5SXin Li ** Add a false to list of constants and return its index.
611*088332b5SXin Li */
boolF(FuncState * fs)612*088332b5SXin Li static int boolF (FuncState *fs) {
613*088332b5SXin Li   TValue o;
614*088332b5SXin Li   setbfvalue(&o);
615*088332b5SXin Li   return addk(fs, &o, &o);  /* use boolean itself as key */
616*088332b5SXin Li }
617*088332b5SXin Li 
618*088332b5SXin Li 
619*088332b5SXin Li /*
620*088332b5SXin Li ** Add a true to list of constants and return its index.
621*088332b5SXin Li */
boolT(FuncState * fs)622*088332b5SXin Li static int boolT (FuncState *fs) {
623*088332b5SXin Li   TValue o;
624*088332b5SXin Li   setbtvalue(&o);
625*088332b5SXin Li   return addk(fs, &o, &o);  /* use boolean itself as key */
626*088332b5SXin Li }
627*088332b5SXin Li 
628*088332b5SXin Li 
629*088332b5SXin Li /*
630*088332b5SXin Li ** Add nil to list of constants and return its index.
631*088332b5SXin Li */
nilK(FuncState * fs)632*088332b5SXin Li static int nilK (FuncState *fs) {
633*088332b5SXin Li   TValue k, v;
634*088332b5SXin Li   setnilvalue(&v);
635*088332b5SXin Li   /* cannot use nil as key; instead use table itself to represent nil */
636*088332b5SXin Li   sethvalue(fs->ls->L, &k, fs->ls->h);
637*088332b5SXin Li   return addk(fs, &k, &v);
638*088332b5SXin Li }
639*088332b5SXin Li 
640*088332b5SXin Li 
641*088332b5SXin Li /*
642*088332b5SXin Li ** Check whether 'i' can be stored in an 'sC' operand. Equivalent to
643*088332b5SXin Li ** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of
644*088332b5SXin Li ** overflows in the hidden addition inside 'int2sC'.
645*088332b5SXin Li */
fitsC(lua_Integer i)646*088332b5SXin Li static int fitsC (lua_Integer i) {
647*088332b5SXin Li   return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C));
648*088332b5SXin Li }
649*088332b5SXin Li 
650*088332b5SXin Li 
651*088332b5SXin Li /*
652*088332b5SXin Li ** Check whether 'i' can be stored in an 'sBx' operand.
653*088332b5SXin Li */
fitsBx(lua_Integer i)654*088332b5SXin Li static int fitsBx (lua_Integer i) {
655*088332b5SXin Li   return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx);
656*088332b5SXin Li }
657*088332b5SXin Li 
658*088332b5SXin Li 
luaK_int(FuncState * fs,int reg,lua_Integer i)659*088332b5SXin Li void luaK_int (FuncState *fs, int reg, lua_Integer i) {
660*088332b5SXin Li   if (fitsBx(i))
661*088332b5SXin Li     luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i));
662*088332b5SXin Li   else
663*088332b5SXin Li     luaK_codek(fs, reg, luaK_intK(fs, i));
664*088332b5SXin Li }
665*088332b5SXin Li 
666*088332b5SXin Li 
luaK_float(FuncState * fs,int reg,lua_Number f)667*088332b5SXin Li static void luaK_float (FuncState *fs, int reg, lua_Number f) {
668*088332b5SXin Li   lua_Integer fi;
669*088332b5SXin Li   if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi))
670*088332b5SXin Li     luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
671*088332b5SXin Li   else
672*088332b5SXin Li     luaK_codek(fs, reg, luaK_numberK(fs, f));
673*088332b5SXin Li }
674*088332b5SXin Li 
675*088332b5SXin Li 
676*088332b5SXin Li /*
677*088332b5SXin Li ** Convert a constant in 'v' into an expression description 'e'
678*088332b5SXin Li */
const2exp(TValue * v,expdesc * e)679*088332b5SXin Li static void const2exp (TValue *v, expdesc *e) {
680*088332b5SXin Li   switch (ttypetag(v)) {
681*088332b5SXin Li     case LUA_VNUMINT:
682*088332b5SXin Li       e->k = VKINT; e->u.ival = ivalue(v);
683*088332b5SXin Li       break;
684*088332b5SXin Li     case LUA_VNUMFLT:
685*088332b5SXin Li       e->k = VKFLT; e->u.nval = fltvalue(v);
686*088332b5SXin Li       break;
687*088332b5SXin Li     case LUA_VFALSE:
688*088332b5SXin Li       e->k = VFALSE;
689*088332b5SXin Li       break;
690*088332b5SXin Li     case LUA_VTRUE:
691*088332b5SXin Li       e->k = VTRUE;
692*088332b5SXin Li       break;
693*088332b5SXin Li     case LUA_VNIL:
694*088332b5SXin Li       e->k = VNIL;
695*088332b5SXin Li       break;
696*088332b5SXin Li     case LUA_VSHRSTR:  case LUA_VLNGSTR:
697*088332b5SXin Li       e->k = VKSTR; e->u.strval = tsvalue(v);
698*088332b5SXin Li       break;
699*088332b5SXin Li     default: lua_assert(0);
700*088332b5SXin Li   }
701*088332b5SXin Li }
702*088332b5SXin Li 
703*088332b5SXin Li 
704*088332b5SXin Li /*
705*088332b5SXin Li ** Fix an expression to return the number of results 'nresults'.
706*088332b5SXin Li ** 'e' must be a multi-ret expression (function call or vararg).
707*088332b5SXin Li */
luaK_setreturns(FuncState * fs,expdesc * e,int nresults)708*088332b5SXin Li void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
709*088332b5SXin Li   Instruction *pc = &getinstruction(fs, e);
710*088332b5SXin Li   if (e->k == VCALL)  /* expression is an open function call? */
711*088332b5SXin Li     SETARG_C(*pc, nresults + 1);
712*088332b5SXin Li   else {
713*088332b5SXin Li     lua_assert(e->k == VVARARG);
714*088332b5SXin Li     SETARG_C(*pc, nresults + 1);
715*088332b5SXin Li     SETARG_A(*pc, fs->freereg);
716*088332b5SXin Li     luaK_reserveregs(fs, 1);
717*088332b5SXin Li   }
718*088332b5SXin Li }
719*088332b5SXin Li 
720*088332b5SXin Li 
721*088332b5SXin Li /*
722*088332b5SXin Li ** Convert a VKSTR to a VK
723*088332b5SXin Li */
str2K(FuncState * fs,expdesc * e)724*088332b5SXin Li static void str2K (FuncState *fs, expdesc *e) {
725*088332b5SXin Li   lua_assert(e->k == VKSTR);
726*088332b5SXin Li   e->u.info = stringK(fs, e->u.strval);
727*088332b5SXin Li   e->k = VK;
728*088332b5SXin Li }
729*088332b5SXin Li 
730*088332b5SXin Li 
731*088332b5SXin Li /*
732*088332b5SXin Li ** Fix an expression to return one result.
733*088332b5SXin Li ** If expression is not a multi-ret expression (function call or
734*088332b5SXin Li ** vararg), it already returns one result, so nothing needs to be done.
735*088332b5SXin Li ** Function calls become VNONRELOC expressions (as its result comes
736*088332b5SXin Li ** fixed in the base register of the call), while vararg expressions
737*088332b5SXin Li ** become VRELOC (as OP_VARARG puts its results where it wants).
738*088332b5SXin Li ** (Calls are created returning one result, so that does not need
739*088332b5SXin Li ** to be fixed.)
740*088332b5SXin Li */
luaK_setoneret(FuncState * fs,expdesc * e)741*088332b5SXin Li void luaK_setoneret (FuncState *fs, expdesc *e) {
742*088332b5SXin Li   if (e->k == VCALL) {  /* expression is an open function call? */
743*088332b5SXin Li     /* already returns 1 value */
744*088332b5SXin Li     lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
745*088332b5SXin Li     e->k = VNONRELOC;  /* result has fixed position */
746*088332b5SXin Li     e->u.info = GETARG_A(getinstruction(fs, e));
747*088332b5SXin Li   }
748*088332b5SXin Li   else if (e->k == VVARARG) {
749*088332b5SXin Li     SETARG_C(getinstruction(fs, e), 2);
750*088332b5SXin Li     e->k = VRELOC;  /* can relocate its simple result */
751*088332b5SXin Li   }
752*088332b5SXin Li }
753*088332b5SXin Li 
754*088332b5SXin Li 
755*088332b5SXin Li /*
756*088332b5SXin Li ** Ensure that expression 'e' is not a variable (nor a constant).
757*088332b5SXin Li ** (Expression still may have jump lists.)
758*088332b5SXin Li */
luaK_dischargevars(FuncState * fs,expdesc * e)759*088332b5SXin Li void luaK_dischargevars (FuncState *fs, expdesc *e) {
760*088332b5SXin Li   switch (e->k) {
761*088332b5SXin Li     case VCONST: {
762*088332b5SXin Li       const2exp(const2val(fs, e), e);
763*088332b5SXin Li       break;
764*088332b5SXin Li     }
765*088332b5SXin Li     case VLOCAL: {  /* already in a register */
766*088332b5SXin Li       e->u.info = e->u.var.sidx;
767*088332b5SXin Li       e->k = VNONRELOC;  /* becomes a non-relocatable value */
768*088332b5SXin Li       break;
769*088332b5SXin Li     }
770*088332b5SXin Li     case VUPVAL: {  /* move value to some (pending) register */
771*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
772*088332b5SXin Li       e->k = VRELOC;
773*088332b5SXin Li       break;
774*088332b5SXin Li     }
775*088332b5SXin Li     case VINDEXUP: {
776*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx);
777*088332b5SXin Li       e->k = VRELOC;
778*088332b5SXin Li       break;
779*088332b5SXin Li     }
780*088332b5SXin Li     case VINDEXI: {
781*088332b5SXin Li       freereg(fs, e->u.ind.t);
782*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx);
783*088332b5SXin Li       e->k = VRELOC;
784*088332b5SXin Li       break;
785*088332b5SXin Li     }
786*088332b5SXin Li     case VINDEXSTR: {
787*088332b5SXin Li       freereg(fs, e->u.ind.t);
788*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx);
789*088332b5SXin Li       e->k = VRELOC;
790*088332b5SXin Li       break;
791*088332b5SXin Li     }
792*088332b5SXin Li     case VINDEXED: {
793*088332b5SXin Li       freeregs(fs, e->u.ind.t, e->u.ind.idx);
794*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx);
795*088332b5SXin Li       e->k = VRELOC;
796*088332b5SXin Li       break;
797*088332b5SXin Li     }
798*088332b5SXin Li     case VVARARG: case VCALL: {
799*088332b5SXin Li       luaK_setoneret(fs, e);
800*088332b5SXin Li       break;
801*088332b5SXin Li     }
802*088332b5SXin Li     default: break;  /* there is one value available (somewhere) */
803*088332b5SXin Li   }
804*088332b5SXin Li }
805*088332b5SXin Li 
806*088332b5SXin Li 
807*088332b5SXin Li /*
808*088332b5SXin Li ** Ensures expression value is in register 'reg' (and therefore
809*088332b5SXin Li ** 'e' will become a non-relocatable expression).
810*088332b5SXin Li ** (Expression still may have jump lists.)
811*088332b5SXin Li */
discharge2reg(FuncState * fs,expdesc * e,int reg)812*088332b5SXin Li static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
813*088332b5SXin Li   luaK_dischargevars(fs, e);
814*088332b5SXin Li   switch (e->k) {
815*088332b5SXin Li     case VNIL: {
816*088332b5SXin Li       luaK_nil(fs, reg, 1);
817*088332b5SXin Li       break;
818*088332b5SXin Li     }
819*088332b5SXin Li     case VFALSE: {
820*088332b5SXin Li       luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0);
821*088332b5SXin Li       break;
822*088332b5SXin Li     }
823*088332b5SXin Li     case VTRUE: {
824*088332b5SXin Li       luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0);
825*088332b5SXin Li       break;
826*088332b5SXin Li     }
827*088332b5SXin Li     case VKSTR: {
828*088332b5SXin Li       str2K(fs, e);
829*088332b5SXin Li     }  /* FALLTHROUGH */
830*088332b5SXin Li     case VK: {
831*088332b5SXin Li       luaK_codek(fs, reg, e->u.info);
832*088332b5SXin Li       break;
833*088332b5SXin Li     }
834*088332b5SXin Li     case VKFLT: {
835*088332b5SXin Li       luaK_float(fs, reg, e->u.nval);
836*088332b5SXin Li       break;
837*088332b5SXin Li     }
838*088332b5SXin Li     case VKINT: {
839*088332b5SXin Li       luaK_int(fs, reg, e->u.ival);
840*088332b5SXin Li       break;
841*088332b5SXin Li     }
842*088332b5SXin Li     case VRELOC: {
843*088332b5SXin Li       Instruction *pc = &getinstruction(fs, e);
844*088332b5SXin Li       SETARG_A(*pc, reg);  /* instruction will put result in 'reg' */
845*088332b5SXin Li       break;
846*088332b5SXin Li     }
847*088332b5SXin Li     case VNONRELOC: {
848*088332b5SXin Li       if (reg != e->u.info)
849*088332b5SXin Li         luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
850*088332b5SXin Li       break;
851*088332b5SXin Li     }
852*088332b5SXin Li     default: {
853*088332b5SXin Li       lua_assert(e->k == VJMP);
854*088332b5SXin Li       return;  /* nothing to do... */
855*088332b5SXin Li     }
856*088332b5SXin Li   }
857*088332b5SXin Li   e->u.info = reg;
858*088332b5SXin Li   e->k = VNONRELOC;
859*088332b5SXin Li }
860*088332b5SXin Li 
861*088332b5SXin Li 
862*088332b5SXin Li /*
863*088332b5SXin Li ** Ensures expression value is in any register.
864*088332b5SXin Li ** (Expression still may have jump lists.)
865*088332b5SXin Li */
discharge2anyreg(FuncState * fs,expdesc * e)866*088332b5SXin Li static void discharge2anyreg (FuncState *fs, expdesc *e) {
867*088332b5SXin Li   if (e->k != VNONRELOC) {  /* no fixed register yet? */
868*088332b5SXin Li     luaK_reserveregs(fs, 1);  /* get a register */
869*088332b5SXin Li     discharge2reg(fs, e, fs->freereg-1);  /* put value there */
870*088332b5SXin Li   }
871*088332b5SXin Li }
872*088332b5SXin Li 
873*088332b5SXin Li 
code_loadbool(FuncState * fs,int A,OpCode op)874*088332b5SXin Li static int code_loadbool (FuncState *fs, int A, OpCode op) {
875*088332b5SXin Li   luaK_getlabel(fs);  /* those instructions may be jump targets */
876*088332b5SXin Li   return luaK_codeABC(fs, op, A, 0, 0);
877*088332b5SXin Li }
878*088332b5SXin Li 
879*088332b5SXin Li 
880*088332b5SXin Li /*
881*088332b5SXin Li ** check whether list has any jump that do not produce a value
882*088332b5SXin Li ** or produce an inverted value
883*088332b5SXin Li */
need_value(FuncState * fs,int list)884*088332b5SXin Li static int need_value (FuncState *fs, int list) {
885*088332b5SXin Li   for (; list != NO_JUMP; list = getjump(fs, list)) {
886*088332b5SXin Li     Instruction i = *getjumpcontrol(fs, list);
887*088332b5SXin Li     if (GET_OPCODE(i) != OP_TESTSET) return 1;
888*088332b5SXin Li   }
889*088332b5SXin Li   return 0;  /* not found */
890*088332b5SXin Li }
891*088332b5SXin Li 
892*088332b5SXin Li 
893*088332b5SXin Li /*
894*088332b5SXin Li ** Ensures final expression result (which includes results from its
895*088332b5SXin Li ** jump lists) is in register 'reg'.
896*088332b5SXin Li ** If expression has jumps, need to patch these jumps either to
897*088332b5SXin Li ** its final position or to "load" instructions (for those tests
898*088332b5SXin Li ** that do not produce values).
899*088332b5SXin Li */
exp2reg(FuncState * fs,expdesc * e,int reg)900*088332b5SXin Li static void exp2reg (FuncState *fs, expdesc *e, int reg) {
901*088332b5SXin Li   discharge2reg(fs, e, reg);
902*088332b5SXin Li   if (e->k == VJMP)  /* expression itself is a test? */
903*088332b5SXin Li     luaK_concat(fs, &e->t, e->u.info);  /* put this jump in 't' list */
904*088332b5SXin Li   if (hasjumps(e)) {
905*088332b5SXin Li     int final;  /* position after whole expression */
906*088332b5SXin Li     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
907*088332b5SXin Li     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
908*088332b5SXin Li     if (need_value(fs, e->t) || need_value(fs, e->f)) {
909*088332b5SXin Li       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
910*088332b5SXin Li       p_f = code_loadbool(fs, reg, OP_LFALSESKIP);  /* skip next inst. */
911*088332b5SXin Li       p_t = code_loadbool(fs, reg, OP_LOADTRUE);
912*088332b5SXin Li       /* jump around these booleans if 'e' is not a test */
913*088332b5SXin Li       luaK_patchtohere(fs, fj);
914*088332b5SXin Li     }
915*088332b5SXin Li     final = luaK_getlabel(fs);
916*088332b5SXin Li     patchlistaux(fs, e->f, final, reg, p_f);
917*088332b5SXin Li     patchlistaux(fs, e->t, final, reg, p_t);
918*088332b5SXin Li   }
919*088332b5SXin Li   e->f = e->t = NO_JUMP;
920*088332b5SXin Li   e->u.info = reg;
921*088332b5SXin Li   e->k = VNONRELOC;
922*088332b5SXin Li }
923*088332b5SXin Li 
924*088332b5SXin Li 
925*088332b5SXin Li /*
926*088332b5SXin Li ** Ensures final expression result is in next available register.
927*088332b5SXin Li */
luaK_exp2nextreg(FuncState * fs,expdesc * e)928*088332b5SXin Li void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
929*088332b5SXin Li   luaK_dischargevars(fs, e);
930*088332b5SXin Li   freeexp(fs, e);
931*088332b5SXin Li   luaK_reserveregs(fs, 1);
932*088332b5SXin Li   exp2reg(fs, e, fs->freereg - 1);
933*088332b5SXin Li }
934*088332b5SXin Li 
935*088332b5SXin Li 
936*088332b5SXin Li /*
937*088332b5SXin Li ** Ensures final expression result is in some (any) register
938*088332b5SXin Li ** and return that register.
939*088332b5SXin Li */
luaK_exp2anyreg(FuncState * fs,expdesc * e)940*088332b5SXin Li int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
941*088332b5SXin Li   luaK_dischargevars(fs, e);
942*088332b5SXin Li   if (e->k == VNONRELOC) {  /* expression already has a register? */
943*088332b5SXin Li     if (!hasjumps(e))  /* no jumps? */
944*088332b5SXin Li       return e->u.info;  /* result is already in a register */
945*088332b5SXin Li     if (e->u.info >= luaY_nvarstack(fs)) {  /* reg. is not a local? */
946*088332b5SXin Li       exp2reg(fs, e, e->u.info);  /* put final result in it */
947*088332b5SXin Li       return e->u.info;
948*088332b5SXin Li     }
949*088332b5SXin Li   }
950*088332b5SXin Li   luaK_exp2nextreg(fs, e);  /* otherwise, use next available register */
951*088332b5SXin Li   return e->u.info;
952*088332b5SXin Li }
953*088332b5SXin Li 
954*088332b5SXin Li 
955*088332b5SXin Li /*
956*088332b5SXin Li ** Ensures final expression result is either in a register
957*088332b5SXin Li ** or in an upvalue.
958*088332b5SXin Li */
luaK_exp2anyregup(FuncState * fs,expdesc * e)959*088332b5SXin Li void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
960*088332b5SXin Li   if (e->k != VUPVAL || hasjumps(e))
961*088332b5SXin Li     luaK_exp2anyreg(fs, e);
962*088332b5SXin Li }
963*088332b5SXin Li 
964*088332b5SXin Li 
965*088332b5SXin Li /*
966*088332b5SXin Li ** Ensures final expression result is either in a register
967*088332b5SXin Li ** or it is a constant.
968*088332b5SXin Li */
luaK_exp2val(FuncState * fs,expdesc * e)969*088332b5SXin Li void luaK_exp2val (FuncState *fs, expdesc *e) {
970*088332b5SXin Li   if (hasjumps(e))
971*088332b5SXin Li     luaK_exp2anyreg(fs, e);
972*088332b5SXin Li   else
973*088332b5SXin Li     luaK_dischargevars(fs, e);
974*088332b5SXin Li }
975*088332b5SXin Li 
976*088332b5SXin Li 
977*088332b5SXin Li /*
978*088332b5SXin Li ** Try to make 'e' a K expression with an index in the range of R/K
979*088332b5SXin Li ** indices. Return true iff succeeded.
980*088332b5SXin Li */
luaK_exp2K(FuncState * fs,expdesc * e)981*088332b5SXin Li static int luaK_exp2K (FuncState *fs, expdesc *e) {
982*088332b5SXin Li   if (!hasjumps(e)) {
983*088332b5SXin Li     int info;
984*088332b5SXin Li     switch (e->k) {  /* move constants to 'k' */
985*088332b5SXin Li       case VTRUE: info = boolT(fs); break;
986*088332b5SXin Li       case VFALSE: info = boolF(fs); break;
987*088332b5SXin Li       case VNIL: info = nilK(fs); break;
988*088332b5SXin Li       case VKINT: info = luaK_intK(fs, e->u.ival); break;
989*088332b5SXin Li       case VKFLT: info = luaK_numberK(fs, e->u.nval); break;
990*088332b5SXin Li       case VKSTR: info = stringK(fs, e->u.strval); break;
991*088332b5SXin Li       case VK: info = e->u.info; break;
992*088332b5SXin Li       default: return 0;  /* not a constant */
993*088332b5SXin Li     }
994*088332b5SXin Li     if (info <= MAXINDEXRK) {  /* does constant fit in 'argC'? */
995*088332b5SXin Li       e->k = VK;  /* make expression a 'K' expression */
996*088332b5SXin Li       e->u.info = info;
997*088332b5SXin Li       return 1;
998*088332b5SXin Li     }
999*088332b5SXin Li   }
1000*088332b5SXin Li   /* else, expression doesn't fit; leave it unchanged */
1001*088332b5SXin Li   return 0;
1002*088332b5SXin Li }
1003*088332b5SXin Li 
1004*088332b5SXin Li 
1005*088332b5SXin Li /*
1006*088332b5SXin Li ** Ensures final expression result is in a valid R/K index
1007*088332b5SXin Li ** (that is, it is either in a register or in 'k' with an index
1008*088332b5SXin Li ** in the range of R/K indices).
1009*088332b5SXin Li ** Returns 1 iff expression is K.
1010*088332b5SXin Li */
luaK_exp2RK(FuncState * fs,expdesc * e)1011*088332b5SXin Li int luaK_exp2RK (FuncState *fs, expdesc *e) {
1012*088332b5SXin Li   if (luaK_exp2K(fs, e))
1013*088332b5SXin Li     return 1;
1014*088332b5SXin Li   else {  /* not a constant in the right range: put it in a register */
1015*088332b5SXin Li     luaK_exp2anyreg(fs, e);
1016*088332b5SXin Li     return 0;
1017*088332b5SXin Li   }
1018*088332b5SXin Li }
1019*088332b5SXin Li 
1020*088332b5SXin Li 
codeABRK(FuncState * fs,OpCode o,int a,int b,expdesc * ec)1021*088332b5SXin Li static void codeABRK (FuncState *fs, OpCode o, int a, int b,
1022*088332b5SXin Li                       expdesc *ec) {
1023*088332b5SXin Li   int k = luaK_exp2RK(fs, ec);
1024*088332b5SXin Li   luaK_codeABCk(fs, o, a, b, ec->u.info, k);
1025*088332b5SXin Li }
1026*088332b5SXin Li 
1027*088332b5SXin Li 
1028*088332b5SXin Li /*
1029*088332b5SXin Li ** Generate code to store result of expression 'ex' into variable 'var'.
1030*088332b5SXin Li */
luaK_storevar(FuncState * fs,expdesc * var,expdesc * ex)1031*088332b5SXin Li void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
1032*088332b5SXin Li   switch (var->k) {
1033*088332b5SXin Li     case VLOCAL: {
1034*088332b5SXin Li       freeexp(fs, ex);
1035*088332b5SXin Li       exp2reg(fs, ex, var->u.var.sidx);  /* compute 'ex' into proper place */
1036*088332b5SXin Li       return;
1037*088332b5SXin Li     }
1038*088332b5SXin Li     case VUPVAL: {
1039*088332b5SXin Li       int e = luaK_exp2anyreg(fs, ex);
1040*088332b5SXin Li       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
1041*088332b5SXin Li       break;
1042*088332b5SXin Li     }
1043*088332b5SXin Li     case VINDEXUP: {
1044*088332b5SXin Li       codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex);
1045*088332b5SXin Li       break;
1046*088332b5SXin Li     }
1047*088332b5SXin Li     case VINDEXI: {
1048*088332b5SXin Li       codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex);
1049*088332b5SXin Li       break;
1050*088332b5SXin Li     }
1051*088332b5SXin Li     case VINDEXSTR: {
1052*088332b5SXin Li       codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex);
1053*088332b5SXin Li       break;
1054*088332b5SXin Li     }
1055*088332b5SXin Li     case VINDEXED: {
1056*088332b5SXin Li       codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex);
1057*088332b5SXin Li       break;
1058*088332b5SXin Li     }
1059*088332b5SXin Li     default: lua_assert(0);  /* invalid var kind to store */
1060*088332b5SXin Li   }
1061*088332b5SXin Li   freeexp(fs, ex);
1062*088332b5SXin Li }
1063*088332b5SXin Li 
1064*088332b5SXin Li 
1065*088332b5SXin Li /*
1066*088332b5SXin Li ** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
1067*088332b5SXin Li */
luaK_self(FuncState * fs,expdesc * e,expdesc * key)1068*088332b5SXin Li void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
1069*088332b5SXin Li   int ereg;
1070*088332b5SXin Li   luaK_exp2anyreg(fs, e);
1071*088332b5SXin Li   ereg = e->u.info;  /* register where 'e' was placed */
1072*088332b5SXin Li   freeexp(fs, e);
1073*088332b5SXin Li   e->u.info = fs->freereg;  /* base register for op_self */
1074*088332b5SXin Li   e->k = VNONRELOC;  /* self expression has a fixed register */
1075*088332b5SXin Li   luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
1076*088332b5SXin Li   codeABRK(fs, OP_SELF, e->u.info, ereg, key);
1077*088332b5SXin Li   freeexp(fs, key);
1078*088332b5SXin Li }
1079*088332b5SXin Li 
1080*088332b5SXin Li 
1081*088332b5SXin Li /*
1082*088332b5SXin Li ** Negate condition 'e' (where 'e' is a comparison).
1083*088332b5SXin Li */
negatecondition(FuncState * fs,expdesc * e)1084*088332b5SXin Li static void negatecondition (FuncState *fs, expdesc *e) {
1085*088332b5SXin Li   Instruction *pc = getjumpcontrol(fs, e->u.info);
1086*088332b5SXin Li   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
1087*088332b5SXin Li                                            GET_OPCODE(*pc) != OP_TEST);
1088*088332b5SXin Li   SETARG_k(*pc, (GETARG_k(*pc) ^ 1));
1089*088332b5SXin Li }
1090*088332b5SXin Li 
1091*088332b5SXin Li 
1092*088332b5SXin Li /*
1093*088332b5SXin Li ** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
1094*088332b5SXin Li ** is true, code will jump if 'e' is true.) Return jump position.
1095*088332b5SXin Li ** Optimize when 'e' is 'not' something, inverting the condition
1096*088332b5SXin Li ** and removing the 'not'.
1097*088332b5SXin Li */
jumponcond(FuncState * fs,expdesc * e,int cond)1098*088332b5SXin Li static int jumponcond (FuncState *fs, expdesc *e, int cond) {
1099*088332b5SXin Li   if (e->k == VRELOC) {
1100*088332b5SXin Li     Instruction ie = getinstruction(fs, e);
1101*088332b5SXin Li     if (GET_OPCODE(ie) == OP_NOT) {
1102*088332b5SXin Li       removelastinstruction(fs);  /* remove previous OP_NOT */
1103*088332b5SXin Li       return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond);
1104*088332b5SXin Li     }
1105*088332b5SXin Li     /* else go through */
1106*088332b5SXin Li   }
1107*088332b5SXin Li   discharge2anyreg(fs, e);
1108*088332b5SXin Li   freeexp(fs, e);
1109*088332b5SXin Li   return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond);
1110*088332b5SXin Li }
1111*088332b5SXin Li 
1112*088332b5SXin Li 
1113*088332b5SXin Li /*
1114*088332b5SXin Li ** Emit code to go through if 'e' is true, jump otherwise.
1115*088332b5SXin Li */
luaK_goiftrue(FuncState * fs,expdesc * e)1116*088332b5SXin Li void luaK_goiftrue (FuncState *fs, expdesc *e) {
1117*088332b5SXin Li   int pc;  /* pc of new jump */
1118*088332b5SXin Li   luaK_dischargevars(fs, e);
1119*088332b5SXin Li   switch (e->k) {
1120*088332b5SXin Li     case VJMP: {  /* condition? */
1121*088332b5SXin Li       negatecondition(fs, e);  /* jump when it is false */
1122*088332b5SXin Li       pc = e->u.info;  /* save jump position */
1123*088332b5SXin Li       break;
1124*088332b5SXin Li     }
1125*088332b5SXin Li     case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
1126*088332b5SXin Li       pc = NO_JUMP;  /* always true; do nothing */
1127*088332b5SXin Li       break;
1128*088332b5SXin Li     }
1129*088332b5SXin Li     default: {
1130*088332b5SXin Li       pc = jumponcond(fs, e, 0);  /* jump when false */
1131*088332b5SXin Li       break;
1132*088332b5SXin Li     }
1133*088332b5SXin Li   }
1134*088332b5SXin Li   luaK_concat(fs, &e->f, pc);  /* insert new jump in false list */
1135*088332b5SXin Li   luaK_patchtohere(fs, e->t);  /* true list jumps to here (to go through) */
1136*088332b5SXin Li   e->t = NO_JUMP;
1137*088332b5SXin Li }
1138*088332b5SXin Li 
1139*088332b5SXin Li 
1140*088332b5SXin Li /*
1141*088332b5SXin Li ** Emit code to go through if 'e' is false, jump otherwise.
1142*088332b5SXin Li */
luaK_goiffalse(FuncState * fs,expdesc * e)1143*088332b5SXin Li void luaK_goiffalse (FuncState *fs, expdesc *e) {
1144*088332b5SXin Li   int pc;  /* pc of new jump */
1145*088332b5SXin Li   luaK_dischargevars(fs, e);
1146*088332b5SXin Li   switch (e->k) {
1147*088332b5SXin Li     case VJMP: {
1148*088332b5SXin Li       pc = e->u.info;  /* already jump if true */
1149*088332b5SXin Li       break;
1150*088332b5SXin Li     }
1151*088332b5SXin Li     case VNIL: case VFALSE: {
1152*088332b5SXin Li       pc = NO_JUMP;  /* always false; do nothing */
1153*088332b5SXin Li       break;
1154*088332b5SXin Li     }
1155*088332b5SXin Li     default: {
1156*088332b5SXin Li       pc = jumponcond(fs, e, 1);  /* jump if true */
1157*088332b5SXin Li       break;
1158*088332b5SXin Li     }
1159*088332b5SXin Li   }
1160*088332b5SXin Li   luaK_concat(fs, &e->t, pc);  /* insert new jump in 't' list */
1161*088332b5SXin Li   luaK_patchtohere(fs, e->f);  /* false list jumps to here (to go through) */
1162*088332b5SXin Li   e->f = NO_JUMP;
1163*088332b5SXin Li }
1164*088332b5SXin Li 
1165*088332b5SXin Li 
1166*088332b5SXin Li /*
1167*088332b5SXin Li ** Code 'not e', doing constant folding.
1168*088332b5SXin Li */
codenot(FuncState * fs,expdesc * e)1169*088332b5SXin Li static void codenot (FuncState *fs, expdesc *e) {
1170*088332b5SXin Li   switch (e->k) {
1171*088332b5SXin Li     case VNIL: case VFALSE: {
1172*088332b5SXin Li       e->k = VTRUE;  /* true == not nil == not false */
1173*088332b5SXin Li       break;
1174*088332b5SXin Li     }
1175*088332b5SXin Li     case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
1176*088332b5SXin Li       e->k = VFALSE;  /* false == not "x" == not 0.5 == not 1 == not true */
1177*088332b5SXin Li       break;
1178*088332b5SXin Li     }
1179*088332b5SXin Li     case VJMP: {
1180*088332b5SXin Li       negatecondition(fs, e);
1181*088332b5SXin Li       break;
1182*088332b5SXin Li     }
1183*088332b5SXin Li     case VRELOC:
1184*088332b5SXin Li     case VNONRELOC: {
1185*088332b5SXin Li       discharge2anyreg(fs, e);
1186*088332b5SXin Li       freeexp(fs, e);
1187*088332b5SXin Li       e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
1188*088332b5SXin Li       e->k = VRELOC;
1189*088332b5SXin Li       break;
1190*088332b5SXin Li     }
1191*088332b5SXin Li     default: lua_assert(0);  /* cannot happen */
1192*088332b5SXin Li   }
1193*088332b5SXin Li   /* interchange true and false lists */
1194*088332b5SXin Li   { int temp = e->f; e->f = e->t; e->t = temp; }
1195*088332b5SXin Li   removevalues(fs, e->f);  /* values are useless when negated */
1196*088332b5SXin Li   removevalues(fs, e->t);
1197*088332b5SXin Li }
1198*088332b5SXin Li 
1199*088332b5SXin Li 
1200*088332b5SXin Li /*
1201*088332b5SXin Li ** Check whether expression 'e' is a small literal string
1202*088332b5SXin Li */
isKstr(FuncState * fs,expdesc * e)1203*088332b5SXin Li static int isKstr (FuncState *fs, expdesc *e) {
1204*088332b5SXin Li   return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
1205*088332b5SXin Li           ttisshrstring(&fs->f->k[e->u.info]));
1206*088332b5SXin Li }
1207*088332b5SXin Li 
1208*088332b5SXin Li /*
1209*088332b5SXin Li ** Check whether expression 'e' is a literal integer.
1210*088332b5SXin Li */
luaK_isKint(expdesc * e)1211*088332b5SXin Li int luaK_isKint (expdesc *e) {
1212*088332b5SXin Li   return (e->k == VKINT && !hasjumps(e));
1213*088332b5SXin Li }
1214*088332b5SXin Li 
1215*088332b5SXin Li 
1216*088332b5SXin Li /*
1217*088332b5SXin Li ** Check whether expression 'e' is a literal integer in
1218*088332b5SXin Li ** proper range to fit in register C
1219*088332b5SXin Li */
isCint(expdesc * e)1220*088332b5SXin Li static int isCint (expdesc *e) {
1221*088332b5SXin Li   return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
1222*088332b5SXin Li }
1223*088332b5SXin Li 
1224*088332b5SXin Li 
1225*088332b5SXin Li /*
1226*088332b5SXin Li ** Check whether expression 'e' is a literal integer in
1227*088332b5SXin Li ** proper range to fit in register sC
1228*088332b5SXin Li */
isSCint(expdesc * e)1229*088332b5SXin Li static int isSCint (expdesc *e) {
1230*088332b5SXin Li   return luaK_isKint(e) && fitsC(e->u.ival);
1231*088332b5SXin Li }
1232*088332b5SXin Li 
1233*088332b5SXin Li 
1234*088332b5SXin Li /*
1235*088332b5SXin Li ** Check whether expression 'e' is a literal integer or float in
1236*088332b5SXin Li ** proper range to fit in a register (sB or sC).
1237*088332b5SXin Li */
isSCnumber(expdesc * e,int * pi,int * isfloat)1238*088332b5SXin Li static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
1239*088332b5SXin Li   lua_Integer i;
1240*088332b5SXin Li   if (e->k == VKINT)
1241*088332b5SXin Li     i = e->u.ival;
1242*088332b5SXin Li   else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq))
1243*088332b5SXin Li     *isfloat = 1;
1244*088332b5SXin Li   else
1245*088332b5SXin Li     return 0;  /* not a number */
1246*088332b5SXin Li   if (!hasjumps(e) && fitsC(i)) {
1247*088332b5SXin Li     *pi = int2sC(cast_int(i));
1248*088332b5SXin Li     return 1;
1249*088332b5SXin Li   }
1250*088332b5SXin Li   else
1251*088332b5SXin Li     return 0;
1252*088332b5SXin Li }
1253*088332b5SXin Li 
1254*088332b5SXin Li 
1255*088332b5SXin Li /*
1256*088332b5SXin Li ** Create expression 't[k]'. 't' must have its final result already in a
1257*088332b5SXin Li ** register or upvalue. Upvalues can only be indexed by literal strings.
1258*088332b5SXin Li ** Keys can be literal strings in the constant table or arbitrary
1259*088332b5SXin Li ** values in registers.
1260*088332b5SXin Li */
luaK_indexed(FuncState * fs,expdesc * t,expdesc * k)1261*088332b5SXin Li void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1262*088332b5SXin Li   if (k->k == VKSTR)
1263*088332b5SXin Li     str2K(fs, k);
1264*088332b5SXin Li   lua_assert(!hasjumps(t) &&
1265*088332b5SXin Li              (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
1266*088332b5SXin Li   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
1267*088332b5SXin Li     luaK_exp2anyreg(fs, t);  /* put it in a register */
1268*088332b5SXin Li   if (t->k == VUPVAL) {
1269*088332b5SXin Li     t->u.ind.t = t->u.info;  /* upvalue index */
1270*088332b5SXin Li     t->u.ind.idx = k->u.info;  /* literal string */
1271*088332b5SXin Li     t->k = VINDEXUP;
1272*088332b5SXin Li   }
1273*088332b5SXin Li   else {
1274*088332b5SXin Li     /* register index of the table */
1275*088332b5SXin Li     t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info;
1276*088332b5SXin Li     if (isKstr(fs, k)) {
1277*088332b5SXin Li       t->u.ind.idx = k->u.info;  /* literal string */
1278*088332b5SXin Li       t->k = VINDEXSTR;
1279*088332b5SXin Li     }
1280*088332b5SXin Li     else if (isCint(k)) {
1281*088332b5SXin Li       t->u.ind.idx = cast_int(k->u.ival);  /* int. constant in proper range */
1282*088332b5SXin Li       t->k = VINDEXI;
1283*088332b5SXin Li     }
1284*088332b5SXin Li     else {
1285*088332b5SXin Li       t->u.ind.idx = luaK_exp2anyreg(fs, k);  /* register */
1286*088332b5SXin Li       t->k = VINDEXED;
1287*088332b5SXin Li     }
1288*088332b5SXin Li   }
1289*088332b5SXin Li }
1290*088332b5SXin Li 
1291*088332b5SXin Li 
1292*088332b5SXin Li /*
1293*088332b5SXin Li ** Return false if folding can raise an error.
1294*088332b5SXin Li ** Bitwise operations need operands convertible to integers; division
1295*088332b5SXin Li ** operations cannot have 0 as divisor.
1296*088332b5SXin Li */
validop(int op,TValue * v1,TValue * v2)1297*088332b5SXin Li static int validop (int op, TValue *v1, TValue *v2) {
1298*088332b5SXin Li   switch (op) {
1299*088332b5SXin Li     case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
1300*088332b5SXin Li     case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: {  /* conversion errors */
1301*088332b5SXin Li       lua_Integer i;
1302*088332b5SXin Li       return (tointegerns(v1, &i) && tointegerns(v2, &i));
1303*088332b5SXin Li     }
1304*088332b5SXin Li     case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD:  /* division by 0 */
1305*088332b5SXin Li       return (nvalue(v2) != 0);
1306*088332b5SXin Li     default: return 1;  /* everything else is valid */
1307*088332b5SXin Li   }
1308*088332b5SXin Li }
1309*088332b5SXin Li 
1310*088332b5SXin Li 
1311*088332b5SXin Li /*
1312*088332b5SXin Li ** Try to "constant-fold" an operation; return 1 iff successful.
1313*088332b5SXin Li ** (In this case, 'e1' has the final result.)
1314*088332b5SXin Li */
constfolding(FuncState * fs,int op,expdesc * e1,const expdesc * e2)1315*088332b5SXin Li static int constfolding (FuncState *fs, int op, expdesc *e1,
1316*088332b5SXin Li                                         const expdesc *e2) {
1317*088332b5SXin Li   TValue v1, v2, res;
1318*088332b5SXin Li   if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
1319*088332b5SXin Li     return 0;  /* non-numeric operands or not safe to fold */
1320*088332b5SXin Li   luaO_rawarith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
1321*088332b5SXin Li   if (ttisinteger(&res)) {
1322*088332b5SXin Li     e1->k = VKINT;
1323*088332b5SXin Li     e1->u.ival = ivalue(&res);
1324*088332b5SXin Li   }
1325*088332b5SXin Li   else {  /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
1326*088332b5SXin Li     lua_Number n = fltvalue(&res);
1327*088332b5SXin Li     if (luai_numisnan(n) || n == 0)
1328*088332b5SXin Li       return 0;
1329*088332b5SXin Li     e1->k = VKFLT;
1330*088332b5SXin Li     e1->u.nval = n;
1331*088332b5SXin Li   }
1332*088332b5SXin Li   return 1;
1333*088332b5SXin Li }
1334*088332b5SXin Li 
1335*088332b5SXin Li 
1336*088332b5SXin Li /*
1337*088332b5SXin Li ** Emit code for unary expressions that "produce values"
1338*088332b5SXin Li ** (everything but 'not').
1339*088332b5SXin Li ** Expression to produce final result will be encoded in 'e'.
1340*088332b5SXin Li */
codeunexpval(FuncState * fs,OpCode op,expdesc * e,int line)1341*088332b5SXin Li static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1342*088332b5SXin Li   int r = luaK_exp2anyreg(fs, e);  /* opcodes operate only on registers */
1343*088332b5SXin Li   freeexp(fs, e);
1344*088332b5SXin Li   e->u.info = luaK_codeABC(fs, op, 0, r, 0);  /* generate opcode */
1345*088332b5SXin Li   e->k = VRELOC;  /* all those operations are relocatable */
1346*088332b5SXin Li   luaK_fixline(fs, line);
1347*088332b5SXin Li }
1348*088332b5SXin Li 
1349*088332b5SXin Li 
1350*088332b5SXin Li /*
1351*088332b5SXin Li ** Emit code for binary expressions that "produce values"
1352*088332b5SXin Li ** (everything but logical operators 'and'/'or' and comparison
1353*088332b5SXin Li ** operators).
1354*088332b5SXin Li ** Expression to produce final result will be encoded in 'e1'.
1355*088332b5SXin Li */
finishbinexpval(FuncState * fs,expdesc * e1,expdesc * e2,OpCode op,int v2,int flip,int line,OpCode mmop,TMS event)1356*088332b5SXin Li static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1357*088332b5SXin Li                              OpCode op, int v2, int flip, int line,
1358*088332b5SXin Li                              OpCode mmop, TMS event) {
1359*088332b5SXin Li   int v1 = luaK_exp2anyreg(fs, e1);
1360*088332b5SXin Li   int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0);
1361*088332b5SXin Li   freeexps(fs, e1, e2);
1362*088332b5SXin Li   e1->u.info = pc;
1363*088332b5SXin Li   e1->k = VRELOC;  /* all those operations are relocatable */
1364*088332b5SXin Li   luaK_fixline(fs, line);
1365*088332b5SXin Li   luaK_codeABCk(fs, mmop, v1, v2, event, flip);  /* to call metamethod */
1366*088332b5SXin Li   luaK_fixline(fs, line);
1367*088332b5SXin Li }
1368*088332b5SXin Li 
1369*088332b5SXin Li 
1370*088332b5SXin Li /*
1371*088332b5SXin Li ** Emit code for binary expressions that "produce values" over
1372*088332b5SXin Li ** two registers.
1373*088332b5SXin Li */
codebinexpval(FuncState * fs,OpCode op,expdesc * e1,expdesc * e2,int line)1374*088332b5SXin Li static void codebinexpval (FuncState *fs, OpCode op,
1375*088332b5SXin Li                            expdesc *e1, expdesc *e2, int line) {
1376*088332b5SXin Li   int v2 = luaK_exp2anyreg(fs, e2);  /* both operands are in registers */
1377*088332b5SXin Li   lua_assert(OP_ADD <= op && op <= OP_SHR);
1378*088332b5SXin Li   finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN,
1379*088332b5SXin Li                   cast(TMS, (op - OP_ADD) + TM_ADD));
1380*088332b5SXin Li }
1381*088332b5SXin Li 
1382*088332b5SXin Li 
1383*088332b5SXin Li /*
1384*088332b5SXin Li ** Code binary operators with immediate operands.
1385*088332b5SXin Li */
codebini(FuncState * fs,OpCode op,expdesc * e1,expdesc * e2,int flip,int line,TMS event)1386*088332b5SXin Li static void codebini (FuncState *fs, OpCode op,
1387*088332b5SXin Li                        expdesc *e1, expdesc *e2, int flip, int line,
1388*088332b5SXin Li                        TMS event) {
1389*088332b5SXin Li   int v2 = int2sC(cast_int(e2->u.ival));  /* immediate operand */
1390*088332b5SXin Li   lua_assert(e2->k == VKINT);
1391*088332b5SXin Li   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event);
1392*088332b5SXin Li }
1393*088332b5SXin Li 
1394*088332b5SXin Li 
1395*088332b5SXin Li /* Try to code a binary operator negating its second operand.
1396*088332b5SXin Li ** For the metamethod, 2nd operand must keep its original value.
1397*088332b5SXin Li */
finishbinexpneg(FuncState * fs,expdesc * e1,expdesc * e2,OpCode op,int line,TMS event)1398*088332b5SXin Li static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
1399*088332b5SXin Li                              OpCode op, int line, TMS event) {
1400*088332b5SXin Li   if (!luaK_isKint(e2))
1401*088332b5SXin Li     return 0;  /* not an integer constant */
1402*088332b5SXin Li   else {
1403*088332b5SXin Li     lua_Integer i2 = e2->u.ival;
1404*088332b5SXin Li     if (!(fitsC(i2) && fitsC(-i2)))
1405*088332b5SXin Li       return 0;  /* not in the proper range */
1406*088332b5SXin Li     else {  /* operating a small integer constant */
1407*088332b5SXin Li       int v2 = cast_int(i2);
1408*088332b5SXin Li       finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event);
1409*088332b5SXin Li       /* correct metamethod argument */
1410*088332b5SXin Li       SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2));
1411*088332b5SXin Li       return 1;  /* successfully coded */
1412*088332b5SXin Li     }
1413*088332b5SXin Li   }
1414*088332b5SXin Li }
1415*088332b5SXin Li 
1416*088332b5SXin Li 
swapexps(expdesc * e1,expdesc * e2)1417*088332b5SXin Li static void swapexps (expdesc *e1, expdesc *e2) {
1418*088332b5SXin Li   expdesc temp = *e1; *e1 = *e2; *e2 = temp;  /* swap 'e1' and 'e2' */
1419*088332b5SXin Li }
1420*088332b5SXin Li 
1421*088332b5SXin Li 
1422*088332b5SXin Li /*
1423*088332b5SXin Li ** Code arithmetic operators ('+', '-', ...). If second operand is a
1424*088332b5SXin Li ** constant in the proper range, use variant opcodes with K operands.
1425*088332b5SXin Li */
codearith(FuncState * fs,BinOpr opr,expdesc * e1,expdesc * e2,int flip,int line)1426*088332b5SXin Li static void codearith (FuncState *fs, BinOpr opr,
1427*088332b5SXin Li                        expdesc *e1, expdesc *e2, int flip, int line) {
1428*088332b5SXin Li   TMS event = cast(TMS, opr + TM_ADD);
1429*088332b5SXin Li   if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) {  /* K operand? */
1430*088332b5SXin Li     int v2 = e2->u.info;  /* K index */
1431*088332b5SXin Li     OpCode op = cast(OpCode, opr + OP_ADDK);
1432*088332b5SXin Li     finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
1433*088332b5SXin Li   }
1434*088332b5SXin Li   else {  /* 'e2' is neither an immediate nor a K operand */
1435*088332b5SXin Li     OpCode op = cast(OpCode, opr + OP_ADD);
1436*088332b5SXin Li     if (flip)
1437*088332b5SXin Li       swapexps(e1, e2);  /* back to original order */
1438*088332b5SXin Li     codebinexpval(fs, op, e1, e2, line);  /* use standard operators */
1439*088332b5SXin Li   }
1440*088332b5SXin Li }
1441*088332b5SXin Li 
1442*088332b5SXin Li 
1443*088332b5SXin Li /*
1444*088332b5SXin Li ** Code commutative operators ('+', '*'). If first operand is a
1445*088332b5SXin Li ** numeric constant, change order of operands to try to use an
1446*088332b5SXin Li ** immediate or K operator.
1447*088332b5SXin Li */
codecommutative(FuncState * fs,BinOpr op,expdesc * e1,expdesc * e2,int line)1448*088332b5SXin Li static void codecommutative (FuncState *fs, BinOpr op,
1449*088332b5SXin Li                              expdesc *e1, expdesc *e2, int line) {
1450*088332b5SXin Li   int flip = 0;
1451*088332b5SXin Li   if (tonumeral(e1, NULL)) {  /* is first operand a numeric constant? */
1452*088332b5SXin Li     swapexps(e1, e2);  /* change order */
1453*088332b5SXin Li     flip = 1;
1454*088332b5SXin Li   }
1455*088332b5SXin Li   if (op == OPR_ADD && isSCint(e2))  /* immediate operand? */
1456*088332b5SXin Li     codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD);
1457*088332b5SXin Li   else
1458*088332b5SXin Li     codearith(fs, op, e1, e2, flip, line);
1459*088332b5SXin Li }
1460*088332b5SXin Li 
1461*088332b5SXin Li 
1462*088332b5SXin Li /*
1463*088332b5SXin Li ** Code bitwise operations; they are all associative, so the function
1464*088332b5SXin Li ** tries to put an integer constant as the 2nd operand (a K operand).
1465*088332b5SXin Li */
codebitwise(FuncState * fs,BinOpr opr,expdesc * e1,expdesc * e2,int line)1466*088332b5SXin Li static void codebitwise (FuncState *fs, BinOpr opr,
1467*088332b5SXin Li                          expdesc *e1, expdesc *e2, int line) {
1468*088332b5SXin Li   int flip = 0;
1469*088332b5SXin Li   int v2;
1470*088332b5SXin Li   OpCode op;
1471*088332b5SXin Li   if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
1472*088332b5SXin Li     swapexps(e1, e2);  /* 'e2' will be the constant operand */
1473*088332b5SXin Li     flip = 1;
1474*088332b5SXin Li   }
1475*088332b5SXin Li   else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) {  /* no constants? */
1476*088332b5SXin Li     op = cast(OpCode, opr + OP_ADD);
1477*088332b5SXin Li     codebinexpval(fs, op, e1, e2, line);  /* all-register opcodes */
1478*088332b5SXin Li     return;
1479*088332b5SXin Li   }
1480*088332b5SXin Li   v2 = e2->u.info;  /* index in K array */
1481*088332b5SXin Li   op = cast(OpCode, opr + OP_ADDK);
1482*088332b5SXin Li   lua_assert(ttisinteger(&fs->f->k[v2]));
1483*088332b5SXin Li   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK,
1484*088332b5SXin Li                   cast(TMS, opr + TM_ADD));
1485*088332b5SXin Li }
1486*088332b5SXin Li 
1487*088332b5SXin Li 
1488*088332b5SXin Li /*
1489*088332b5SXin Li ** Emit code for order comparisons. When using an immediate operand,
1490*088332b5SXin Li ** 'isfloat' tells whether the original value was a float.
1491*088332b5SXin Li */
codeorder(FuncState * fs,OpCode op,expdesc * e1,expdesc * e2)1492*088332b5SXin Li static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1493*088332b5SXin Li   int r1, r2;
1494*088332b5SXin Li   int im;
1495*088332b5SXin Li   int isfloat = 0;
1496*088332b5SXin Li   if (isSCnumber(e2, &im, &isfloat)) {
1497*088332b5SXin Li     /* use immediate operand */
1498*088332b5SXin Li     r1 = luaK_exp2anyreg(fs, e1);
1499*088332b5SXin Li     r2 = im;
1500*088332b5SXin Li     op = cast(OpCode, (op - OP_LT) + OP_LTI);
1501*088332b5SXin Li   }
1502*088332b5SXin Li   else if (isSCnumber(e1, &im, &isfloat)) {
1503*088332b5SXin Li     /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1504*088332b5SXin Li     r1 = luaK_exp2anyreg(fs, e2);
1505*088332b5SXin Li     r2 = im;
1506*088332b5SXin Li     op = (op == OP_LT) ? OP_GTI : OP_GEI;
1507*088332b5SXin Li   }
1508*088332b5SXin Li   else {  /* regular case, compare two registers */
1509*088332b5SXin Li     r1 = luaK_exp2anyreg(fs, e1);
1510*088332b5SXin Li     r2 = luaK_exp2anyreg(fs, e2);
1511*088332b5SXin Li   }
1512*088332b5SXin Li   freeexps(fs, e1, e2);
1513*088332b5SXin Li   e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
1514*088332b5SXin Li   e1->k = VJMP;
1515*088332b5SXin Li }
1516*088332b5SXin Li 
1517*088332b5SXin Li 
1518*088332b5SXin Li /*
1519*088332b5SXin Li ** Emit code for equality comparisons ('==', '~=').
1520*088332b5SXin Li ** 'e1' was already put as RK by 'luaK_infix'.
1521*088332b5SXin Li */
codeeq(FuncState * fs,BinOpr opr,expdesc * e1,expdesc * e2)1522*088332b5SXin Li static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1523*088332b5SXin Li   int r1, r2;
1524*088332b5SXin Li   int im;
1525*088332b5SXin Li   int isfloat = 0;  /* not needed here, but kept for symmetry */
1526*088332b5SXin Li   OpCode op;
1527*088332b5SXin Li   if (e1->k != VNONRELOC) {
1528*088332b5SXin Li     lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT);
1529*088332b5SXin Li     swapexps(e1, e2);
1530*088332b5SXin Li   }
1531*088332b5SXin Li   r1 = luaK_exp2anyreg(fs, e1);  /* 1st expression must be in register */
1532*088332b5SXin Li   if (isSCnumber(e2, &im, &isfloat)) {
1533*088332b5SXin Li     op = OP_EQI;
1534*088332b5SXin Li     r2 = im;  /* immediate operand */
1535*088332b5SXin Li   }
1536*088332b5SXin Li   else if (luaK_exp2RK(fs, e2)) {  /* 1st expression is constant? */
1537*088332b5SXin Li     op = OP_EQK;
1538*088332b5SXin Li     r2 = e2->u.info;  /* constant index */
1539*088332b5SXin Li   }
1540*088332b5SXin Li   else {
1541*088332b5SXin Li     op = OP_EQ;  /* will compare two registers */
1542*088332b5SXin Li     r2 = luaK_exp2anyreg(fs, e2);
1543*088332b5SXin Li   }
1544*088332b5SXin Li   freeexps(fs, e1, e2);
1545*088332b5SXin Li   e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ));
1546*088332b5SXin Li   e1->k = VJMP;
1547*088332b5SXin Li }
1548*088332b5SXin Li 
1549*088332b5SXin Li 
1550*088332b5SXin Li /*
1551*088332b5SXin Li ** Apply prefix operation 'op' to expression 'e'.
1552*088332b5SXin Li */
luaK_prefix(FuncState * fs,UnOpr op,expdesc * e,int line)1553*088332b5SXin Li void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
1554*088332b5SXin Li   static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
1555*088332b5SXin Li   luaK_dischargevars(fs, e);
1556*088332b5SXin Li   switch (op) {
1557*088332b5SXin Li     case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
1558*088332b5SXin Li       if (constfolding(fs, op + LUA_OPUNM, e, &ef))
1559*088332b5SXin Li         break;
1560*088332b5SXin Li       /* else */ /* FALLTHROUGH */
1561*088332b5SXin Li     case OPR_LEN:
1562*088332b5SXin Li       codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
1563*088332b5SXin Li       break;
1564*088332b5SXin Li     case OPR_NOT: codenot(fs, e); break;
1565*088332b5SXin Li     default: lua_assert(0);
1566*088332b5SXin Li   }
1567*088332b5SXin Li }
1568*088332b5SXin Li 
1569*088332b5SXin Li 
1570*088332b5SXin Li /*
1571*088332b5SXin Li ** Process 1st operand 'v' of binary operation 'op' before reading
1572*088332b5SXin Li ** 2nd operand.
1573*088332b5SXin Li */
luaK_infix(FuncState * fs,BinOpr op,expdesc * v)1574*088332b5SXin Li void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1575*088332b5SXin Li   luaK_dischargevars(fs, v);
1576*088332b5SXin Li   switch (op) {
1577*088332b5SXin Li     case OPR_AND: {
1578*088332b5SXin Li       luaK_goiftrue(fs, v);  /* go ahead only if 'v' is true */
1579*088332b5SXin Li       break;
1580*088332b5SXin Li     }
1581*088332b5SXin Li     case OPR_OR: {
1582*088332b5SXin Li       luaK_goiffalse(fs, v);  /* go ahead only if 'v' is false */
1583*088332b5SXin Li       break;
1584*088332b5SXin Li     }
1585*088332b5SXin Li     case OPR_CONCAT: {
1586*088332b5SXin Li       luaK_exp2nextreg(fs, v);  /* operand must be on the stack */
1587*088332b5SXin Li       break;
1588*088332b5SXin Li     }
1589*088332b5SXin Li     case OPR_ADD: case OPR_SUB:
1590*088332b5SXin Li     case OPR_MUL: case OPR_DIV: case OPR_IDIV:
1591*088332b5SXin Li     case OPR_MOD: case OPR_POW:
1592*088332b5SXin Li     case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1593*088332b5SXin Li     case OPR_SHL: case OPR_SHR: {
1594*088332b5SXin Li       if (!tonumeral(v, NULL))
1595*088332b5SXin Li         luaK_exp2anyreg(fs, v);
1596*088332b5SXin Li       /* else keep numeral, which may be folded with 2nd operand */
1597*088332b5SXin Li       break;
1598*088332b5SXin Li     }
1599*088332b5SXin Li     case OPR_EQ: case OPR_NE: {
1600*088332b5SXin Li       if (!tonumeral(v, NULL))
1601*088332b5SXin Li         luaK_exp2RK(fs, v);
1602*088332b5SXin Li       /* else keep numeral, which may be an immediate operand */
1603*088332b5SXin Li       break;
1604*088332b5SXin Li     }
1605*088332b5SXin Li     case OPR_LT: case OPR_LE:
1606*088332b5SXin Li     case OPR_GT: case OPR_GE: {
1607*088332b5SXin Li       int dummy, dummy2;
1608*088332b5SXin Li       if (!isSCnumber(v, &dummy, &dummy2))
1609*088332b5SXin Li         luaK_exp2anyreg(fs, v);
1610*088332b5SXin Li       /* else keep numeral, which may be an immediate operand */
1611*088332b5SXin Li       break;
1612*088332b5SXin Li     }
1613*088332b5SXin Li     default: lua_assert(0);
1614*088332b5SXin Li   }
1615*088332b5SXin Li }
1616*088332b5SXin Li 
1617*088332b5SXin Li /*
1618*088332b5SXin Li ** Create code for '(e1 .. e2)'.
1619*088332b5SXin Li ** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))',
1620*088332b5SXin Li ** because concatenation is right associative), merge both CONCATs.
1621*088332b5SXin Li */
codeconcat(FuncState * fs,expdesc * e1,expdesc * e2,int line)1622*088332b5SXin Li static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) {
1623*088332b5SXin Li   Instruction *ie2 = previousinstruction(fs);
1624*088332b5SXin Li   if (GET_OPCODE(*ie2) == OP_CONCAT) {  /* is 'e2' a concatenation? */
1625*088332b5SXin Li     int n = GETARG_B(*ie2);  /* # of elements concatenated in 'e2' */
1626*088332b5SXin Li     lua_assert(e1->u.info + 1 == GETARG_A(*ie2));
1627*088332b5SXin Li     freeexp(fs, e2);
1628*088332b5SXin Li     SETARG_A(*ie2, e1->u.info);  /* correct first element ('e1') */
1629*088332b5SXin Li     SETARG_B(*ie2, n + 1);  /* will concatenate one more element */
1630*088332b5SXin Li   }
1631*088332b5SXin Li   else {  /* 'e2' is not a concatenation */
1632*088332b5SXin Li     luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0);  /* new concat opcode */
1633*088332b5SXin Li     freeexp(fs, e2);
1634*088332b5SXin Li     luaK_fixline(fs, line);
1635*088332b5SXin Li   }
1636*088332b5SXin Li }
1637*088332b5SXin Li 
1638*088332b5SXin Li 
1639*088332b5SXin Li /*
1640*088332b5SXin Li ** Finalize code for binary operation, after reading 2nd operand.
1641*088332b5SXin Li */
luaK_posfix(FuncState * fs,BinOpr opr,expdesc * e1,expdesc * e2,int line)1642*088332b5SXin Li void luaK_posfix (FuncState *fs, BinOpr opr,
1643*088332b5SXin Li                   expdesc *e1, expdesc *e2, int line) {
1644*088332b5SXin Li   luaK_dischargevars(fs, e2);
1645*088332b5SXin Li   if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2))
1646*088332b5SXin Li     return;  /* done by folding */
1647*088332b5SXin Li   switch (opr) {
1648*088332b5SXin Li     case OPR_AND: {
1649*088332b5SXin Li       lua_assert(e1->t == NO_JUMP);  /* list closed by 'luaK_infix' */
1650*088332b5SXin Li       luaK_concat(fs, &e2->f, e1->f);
1651*088332b5SXin Li       *e1 = *e2;
1652*088332b5SXin Li       break;
1653*088332b5SXin Li     }
1654*088332b5SXin Li     case OPR_OR: {
1655*088332b5SXin Li       lua_assert(e1->f == NO_JUMP);  /* list closed by 'luaK_infix' */
1656*088332b5SXin Li       luaK_concat(fs, &e2->t, e1->t);
1657*088332b5SXin Li       *e1 = *e2;
1658*088332b5SXin Li       break;
1659*088332b5SXin Li     }
1660*088332b5SXin Li     case OPR_CONCAT: {  /* e1 .. e2 */
1661*088332b5SXin Li       luaK_exp2nextreg(fs, e2);
1662*088332b5SXin Li       codeconcat(fs, e1, e2, line);
1663*088332b5SXin Li       break;
1664*088332b5SXin Li     }
1665*088332b5SXin Li     case OPR_ADD: case OPR_MUL: {
1666*088332b5SXin Li       codecommutative(fs, opr, e1, e2, line);
1667*088332b5SXin Li       break;
1668*088332b5SXin Li     }
1669*088332b5SXin Li     case OPR_SUB: {
1670*088332b5SXin Li       if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB))
1671*088332b5SXin Li         break; /* coded as (r1 + -I) */
1672*088332b5SXin Li       /* ELSE */
1673*088332b5SXin Li     }  /* FALLTHROUGH */
1674*088332b5SXin Li     case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: {
1675*088332b5SXin Li       codearith(fs, opr, e1, e2, 0, line);
1676*088332b5SXin Li       break;
1677*088332b5SXin Li     }
1678*088332b5SXin Li     case OPR_BAND: case OPR_BOR: case OPR_BXOR: {
1679*088332b5SXin Li       codebitwise(fs, opr, e1, e2, line);
1680*088332b5SXin Li       break;
1681*088332b5SXin Li     }
1682*088332b5SXin Li     case OPR_SHL: {
1683*088332b5SXin Li       if (isSCint(e1)) {
1684*088332b5SXin Li         swapexps(e1, e2);
1685*088332b5SXin Li         codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL);  /* I << r2 */
1686*088332b5SXin Li       }
1687*088332b5SXin Li       else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) {
1688*088332b5SXin Li         /* coded as (r1 >> -I) */;
1689*088332b5SXin Li       }
1690*088332b5SXin Li       else  /* regular case (two registers) */
1691*088332b5SXin Li        codebinexpval(fs, OP_SHL, e1, e2, line);
1692*088332b5SXin Li       break;
1693*088332b5SXin Li     }
1694*088332b5SXin Li     case OPR_SHR: {
1695*088332b5SXin Li       if (isSCint(e2))
1696*088332b5SXin Li         codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR);  /* r1 >> I */
1697*088332b5SXin Li       else  /* regular case (two registers) */
1698*088332b5SXin Li         codebinexpval(fs, OP_SHR, e1, e2, line);
1699*088332b5SXin Li       break;
1700*088332b5SXin Li     }
1701*088332b5SXin Li     case OPR_EQ: case OPR_NE: {
1702*088332b5SXin Li       codeeq(fs, opr, e1, e2);
1703*088332b5SXin Li       break;
1704*088332b5SXin Li     }
1705*088332b5SXin Li     case OPR_LT: case OPR_LE: {
1706*088332b5SXin Li       OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
1707*088332b5SXin Li       codeorder(fs, op, e1, e2);
1708*088332b5SXin Li       break;
1709*088332b5SXin Li     }
1710*088332b5SXin Li     case OPR_GT: case OPR_GE: {
1711*088332b5SXin Li       /* '(a > b)' <=> '(b < a)';  '(a >= b)' <=> '(b <= a)' */
1712*088332b5SXin Li       OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
1713*088332b5SXin Li       swapexps(e1, e2);
1714*088332b5SXin Li       codeorder(fs, op, e1, e2);
1715*088332b5SXin Li       break;
1716*088332b5SXin Li     }
1717*088332b5SXin Li     default: lua_assert(0);
1718*088332b5SXin Li   }
1719*088332b5SXin Li }
1720*088332b5SXin Li 
1721*088332b5SXin Li 
1722*088332b5SXin Li /*
1723*088332b5SXin Li ** Change line information associated with current position, by removing
1724*088332b5SXin Li ** previous info and adding it again with new line.
1725*088332b5SXin Li */
luaK_fixline(FuncState * fs,int line)1726*088332b5SXin Li void luaK_fixline (FuncState *fs, int line) {
1727*088332b5SXin Li   removelastlineinfo(fs);
1728*088332b5SXin Li   savelineinfo(fs, fs->f, line);
1729*088332b5SXin Li }
1730*088332b5SXin Li 
1731*088332b5SXin Li 
luaK_settablesize(FuncState * fs,int pc,int ra,int asize,int hsize)1732*088332b5SXin Li void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) {
1733*088332b5SXin Li   Instruction *inst = &fs->f->code[pc];
1734*088332b5SXin Li   int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0;  /* hash size */
1735*088332b5SXin Li   int extra = asize / (MAXARG_C + 1);  /* higher bits of array size */
1736*088332b5SXin Li   int rc = asize % (MAXARG_C + 1);  /* lower bits of array size */
1737*088332b5SXin Li   int k = (extra > 0);  /* true iff needs extra argument */
1738*088332b5SXin Li   *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k);
1739*088332b5SXin Li   *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra);
1740*088332b5SXin Li }
1741*088332b5SXin Li 
1742*088332b5SXin Li 
1743*088332b5SXin Li /*
1744*088332b5SXin Li ** Emit a SETLIST instruction.
1745*088332b5SXin Li ** 'base' is register that keeps table;
1746*088332b5SXin Li ** 'nelems' is #table plus those to be stored now;
1747*088332b5SXin Li ** 'tostore' is number of values (in registers 'base + 1',...) to add to
1748*088332b5SXin Li ** table (or LUA_MULTRET to add up to stack top).
1749*088332b5SXin Li */
luaK_setlist(FuncState * fs,int base,int nelems,int tostore)1750*088332b5SXin Li void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
1751*088332b5SXin Li   lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
1752*088332b5SXin Li   if (tostore == LUA_MULTRET)
1753*088332b5SXin Li     tostore = 0;
1754*088332b5SXin Li   if (nelems <= MAXARG_C)
1755*088332b5SXin Li     luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems);
1756*088332b5SXin Li   else {
1757*088332b5SXin Li     int extra = nelems / (MAXARG_C + 1);
1758*088332b5SXin Li     nelems %= (MAXARG_C + 1);
1759*088332b5SXin Li     luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1);
1760*088332b5SXin Li     codeextraarg(fs, extra);
1761*088332b5SXin Li   }
1762*088332b5SXin Li   fs->freereg = base + 1;  /* free registers with list values */
1763*088332b5SXin Li }
1764*088332b5SXin Li 
1765*088332b5SXin Li 
1766*088332b5SXin Li /*
1767*088332b5SXin Li ** return the final target of a jump (skipping jumps to jumps)
1768*088332b5SXin Li */
finaltarget(Instruction * code,int i)1769*088332b5SXin Li static int finaltarget (Instruction *code, int i) {
1770*088332b5SXin Li   int count;
1771*088332b5SXin Li   for (count = 0; count < 100; count++) {  /* avoid infinite loops */
1772*088332b5SXin Li     Instruction pc = code[i];
1773*088332b5SXin Li     if (GET_OPCODE(pc) != OP_JMP)
1774*088332b5SXin Li       break;
1775*088332b5SXin Li      else
1776*088332b5SXin Li        i += GETARG_sJ(pc) + 1;
1777*088332b5SXin Li   }
1778*088332b5SXin Li   return i;
1779*088332b5SXin Li }
1780*088332b5SXin Li 
1781*088332b5SXin Li 
1782*088332b5SXin Li /*
1783*088332b5SXin Li ** Do a final pass over the code of a function, doing small peephole
1784*088332b5SXin Li ** optimizations and adjustments.
1785*088332b5SXin Li */
luaK_finish(FuncState * fs)1786*088332b5SXin Li void luaK_finish (FuncState *fs) {
1787*088332b5SXin Li   int i;
1788*088332b5SXin Li   Proto *p = fs->f;
1789*088332b5SXin Li   for (i = 0; i < fs->pc; i++) {
1790*088332b5SXin Li     Instruction *pc = &p->code[i];
1791*088332b5SXin Li     lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc));
1792*088332b5SXin Li     switch (GET_OPCODE(*pc)) {
1793*088332b5SXin Li       case OP_RETURN0: case OP_RETURN1: {
1794*088332b5SXin Li         if (!(fs->needclose || p->is_vararg))
1795*088332b5SXin Li           break;  /* no extra work */
1796*088332b5SXin Li         /* else use OP_RETURN to do the extra work */
1797*088332b5SXin Li         SET_OPCODE(*pc, OP_RETURN);
1798*088332b5SXin Li       }  /* FALLTHROUGH */
1799*088332b5SXin Li       case OP_RETURN: case OP_TAILCALL: {
1800*088332b5SXin Li         if (fs->needclose)
1801*088332b5SXin Li           SETARG_k(*pc, 1);  /* signal that it needs to close */
1802*088332b5SXin Li         if (p->is_vararg)
1803*088332b5SXin Li           SETARG_C(*pc, p->numparams + 1);  /* signal that it is vararg */
1804*088332b5SXin Li         break;
1805*088332b5SXin Li       }
1806*088332b5SXin Li       case OP_JMP: {
1807*088332b5SXin Li         int target = finaltarget(p->code, i);
1808*088332b5SXin Li         fixjump(fs, i, target);
1809*088332b5SXin Li         break;
1810*088332b5SXin Li       }
1811*088332b5SXin Li       default: break;
1812*088332b5SXin Li     }
1813*088332b5SXin Li   }
1814*088332b5SXin Li }
1815