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