History

Lua 5.0

Lua Team committed 23 years ago

Commit 488a64b1 parent c2bb718138 files · +16186 −12300Browse files

Showing the changes to src/lcode.c (1 of 138 files). Show all

Unified · Split

src/lcode.c+530−517
@@ -1,66 +1,84 @@
11 /*
2−** $Id: lcode.c,v 1.51 2000/09/29 12:42:13 roberto Exp $
2+** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp $
33 ** Code generator for Lua
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include "stdlib.h"
8+#include <stdlib.h>
9+
10+#define lcode_c
911
1012 #include "lua.h"
1113
1214 #include "lcode.h"
15+#include "ldebug.h"
1316 #include "ldo.h"
1417 #include "llex.h"
1518 #include "lmem.h"
1619 #include "lobject.h"
1720 #include "lopcodes.h"
1821 #include "lparser.h"
22+#include "ltable.h"
1923
2024
21−void luaK_error (LexState *ls, const char *msg) {
22− luaX_error(ls, msg, ls->t.token);
23−}
25+#define hasjumps(e) ((e)->t != (e)->f)
2426
2527
26−/*
27−** Returns the the previous instruction, for optimizations.
28−** If there is a jump target between this and the current instruction,
29−** returns a dummy instruction to avoid wrong optimizations.
30−*/
31−static Instruction previous_instruction (FuncState *fs) {
32− if (fs->pc > fs->lasttarget) /* no jumps to current position? */
33− return fs->f->code[fs->pc-1]; /* returns previous instruction */
34− else
35− return CREATE_0(OP_END); /* no optimizations after an `END' */
28+void luaK_nil (FuncState *fs, int from, int n) {
29+ Instruction *previous;
30+ if (fs->pc > fs->lasttarget && /* no jumps to current position? */
31+ GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
32+ int pfrom = GETARG_A(*previous);
33+ int pto = GETARG_B(*previous);
34+ if (pfrom <= from && from <= pto+1) { /* can connect both? */
35+ if (from+n-1 > pto)
36+ SETARG_B(*previous, from+n-1);
37+ return;
38+ }
39+ }
40+ luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
3641 }
3742
3843
3944 int luaK_jump (FuncState *fs) {
40− int j = luaK_code1(fs, OP_JMP, NO_JUMP);
41− if (j == fs->lasttarget) { /* possible jumps to this jump? */
42− luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
43− fs->jlt = NO_JUMP;
44− }
45+ int jpc = fs->jpc; /* save list of jumps to here */
46+ int j;
47+ fs->jpc = NO_JUMP;
48+ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
49+ luaK_concat(fs, &j, jpc); /* keep them on hold */
4550 return j;
4651 }
4752
4853
54+static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
55+ luaK_codeABC(fs, op, A, B, C);
56+ return luaK_jump(fs);
57+}
58+
59+
4960 static void luaK_fixjump (FuncState *fs, int pc, int dest) {
5061 Instruction *jmp = &fs->f->code[pc];
51− if (dest == NO_JUMP)
52− SETARG_S(*jmp, NO_JUMP); /* point to itself to represent end of list */
53− else { /* jump is relative to position following jump instruction */
54− int offset = dest-(pc+1);
55− if (abs(offset) > MAXARG_S)
56− luaK_error(fs->ls, "control structure too long");
57− SETARG_S(*jmp, offset);
58− }
62+ int offset = dest-(pc+1);
63+ lua_assert(dest != NO_JUMP);
64+ if (abs(offset) > MAXARG_sBx)
65+ luaX_syntaxerror(fs->ls, "control structure too long");
66+ SETARG_sBx(*jmp, offset);
67+}
68+
69+
70+/*
71+** returns current `pc' and marks it as a jump target (to avoid wrong
72+** optimizations with consecutive instructions not in the same basic block).
73+*/
74+int luaK_getlabel (FuncState *fs) {
75+ fs->lasttarget = fs->pc;
76+ return fs->pc;
5977 }
6078
6179
6280 static int luaK_getjump (FuncState *fs, int pc) {
63− int offset = GETARG_S(fs->f->code[pc]);
81+ int offset = GETARG_sBx(fs->f->code[pc]);
6482 if (offset == NO_JUMP) /* point to itself represents end of list */
6583 return NO_JUMP; /* end of list */
6684 else
@@ -68,634 +86,629 @@ static int luaK_getjump (FuncState *fs, int pc) { · 1 unmodified line
6886 }
6987
7088
89+static Instruction *getjumpcontrol (FuncState *fs, int pc) {
90+ Instruction *pi = &fs->f->code[pc];
91+ if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
92+ return pi-1;
93+ else
94+ return pi;
95+}
96+
97+
7198 /*
72−** returns current `pc' and marks it as a jump target (to avoid wrong
73−** optimizations with consecutive instructions not in the same basic block).
74−** discharge list of jumps to last target.
99+** check whether list has any jump that do not produce a value
100+** (or produce an inverted value)
75101 */
76−int luaK_getlabel (FuncState *fs) {
77− if (fs->pc != fs->lasttarget) {
78− int lasttarget = fs->lasttarget;
79− fs->lasttarget = fs->pc;
80− luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
81− fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */
102+static int need_value (FuncState *fs, int list, int cond) {
103+ for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
104+ Instruction i = *getjumpcontrol(fs, list);
105+ if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
82106 }
83− return fs->pc;
107+ return 0; /* not found */
84108 }
85109
86110
87−void luaK_deltastack (FuncState *fs, int delta) {
88− fs->stacklevel += delta;
89− if (fs->stacklevel > fs->f->maxstacksize) {
90− if (fs->stacklevel > MAXSTACK)
91− luaK_error(fs->ls, "function or expression too complex");
92− fs->f->maxstacksize = fs->stacklevel;
93− }
111+static void patchtestreg (Instruction *i, int reg) {
112+ if (reg == NO_REG) reg = GETARG_B(*i);
113+ SETARG_A(*i, reg);
94114 }
95115
96116
97−void luaK_kstr (LexState *ls, int c) {
98− luaK_code1(ls->fs, OP_PUSHSTRING, c);
117+static void luaK_patchlistaux (FuncState *fs, int list,
118+ int ttarget, int treg, int ftarget, int freg, int dtarget) {
119+ while (list != NO_JUMP) {
120+ int next = luaK_getjump(fs, list);
121+ Instruction *i = getjumpcontrol(fs, list);
122+ if (GET_OPCODE(*i) != OP_TEST) {
123+ lua_assert(dtarget != NO_JUMP);
124+ luaK_fixjump(fs, list, dtarget); /* jump to default target */
125+ }
126+ else {
127+ if (GETARG_C(*i)) {
128+ lua_assert(ttarget != NO_JUMP);
129+ patchtestreg(i, treg);
130+ luaK_fixjump(fs, list, ttarget);
131+ }
132+ else {
133+ lua_assert(ftarget != NO_JUMP);
134+ patchtestreg(i, freg);
135+ luaK_fixjump(fs, list, ftarget);
136+ }
137+ }
138+ list = next;
139+ }
99140 }
100141
101142
102−static int number_constant (FuncState *fs, Number r) {
103− /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
104− Proto *f = fs->f;
105− int c = f->nknum;
106− int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
107− while (--c >= lim)
108− if (f->knum[c] == r) return c;
109− /* not found; create a new entry */
110− luaM_growvector(fs->L, f->knum, f->nknum, 1, Number,
111− "constant table overflow", MAXARG_U);
112− c = f->nknum++;
113− f->knum[c] = r;
114− return c;
115−}
116−
117−
118−void luaK_number (FuncState *fs, Number f) {
119− if (f <= (Number)MAXARG_S && (Number)(int)f == f)
120− luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */
121− else
122− luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));
143+static void luaK_dischargejpc (FuncState *fs) {
144+ luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
145+ fs->jpc = NO_JUMP;
123146 }
124147
125148
126−void luaK_adjuststack (FuncState *fs, int n) {
127− if (n > 0)
128− luaK_code1(fs, OP_POP, n);
129− else
130− luaK_code1(fs, OP_PUSHNIL, -n);
149+void luaK_patchlist (FuncState *fs, int list, int target) {
150+ if (target == fs->pc)
151+ luaK_patchtohere(fs, list);
152+ else {
153+ lua_assert(target < fs->pc);
154+ luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
155+ }
131156 }
132157
133158
134−int luaK_lastisopen (FuncState *fs) {
135− /* check whether last instruction is an open function call */
136− Instruction i = previous_instruction(fs);
137− if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
138− return 1;
139− else return 0;
159+void luaK_patchtohere (FuncState *fs, int list) {
160+ luaK_getlabel(fs);
161+ luaK_concat(fs, &fs->jpc, list);
140162 }
141163
142164
143−void luaK_setcallreturns (FuncState *fs, int nresults) {
144− if (luaK_lastisopen(fs)) { /* expression is an open function call? */
145− SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */
146− luaK_deltastack(fs, nresults); /* push results */
165+void luaK_concat (FuncState *fs, int *l1, int l2) {
166+ if (l2 == NO_JUMP) return;
167+ else if (*l1 == NO_JUMP)
168+ *l1 = l2;
169+ else {
170+ int list = *l1;
171+ int next;
172+ while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */
173+ list = next;
174+ luaK_fixjump(fs, list, l2);
147175 }
148176 }
149177
150178
151−static int discharge (FuncState *fs, expdesc *var) {
152− switch (var->k) {
153− case VLOCAL:
154− luaK_code1(fs, OP_GETLOCAL, var->u.index);
155− break;
156− case VGLOBAL:
157− luaK_code1(fs, OP_GETGLOBAL, var->u.index);
158− break;
159− case VINDEXED:
160− luaK_code0(fs, OP_GETTABLE);
161− break;
162− case VEXP:
163− return 0; /* nothing to do */
179+void luaK_checkstack (FuncState *fs, int n) {
180+ int newstack = fs->freereg + n;
181+ if (newstack > fs->f->maxstacksize) {
182+ if (newstack >= MAXSTACK)
183+ luaX_syntaxerror(fs->ls, "function or expression too complex");
184+ fs->f->maxstacksize = cast(lu_byte, newstack);
164185 }
165− var->k = VEXP;
166− var->u.l.t = var->u.l.f = NO_JUMP;
167− return 1;
168186 }
169187
170188
171−static void discharge1 (FuncState *fs, expdesc *var) {
172− discharge(fs, var);
173− /* if it has jumps then it is already discharged */
174− if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP)
175− luaK_setcallreturns(fs, 1); /* call must return 1 value */
189+void luaK_reserveregs (FuncState *fs, int n) {
190+ luaK_checkstack(fs, n);
191+ fs->freereg += n;
176192 }
177193
178194
179−void luaK_storevar (LexState *ls, const expdesc *var) {
180− FuncState *fs = ls->fs;
181− switch (var->k) {
182− case VLOCAL:
183− luaK_code1(fs, OP_SETLOCAL, var->u.index);
184− break;
185− case VGLOBAL:
186− luaK_code1(fs, OP_SETGLOBAL, var->u.index);
187− break;
188− case VINDEXED: /* table is at top-3; pop 3 elements after operation */
189− luaK_code2(fs, OP_SETTABLE, 3, 3);
190− break;
191− default:
192− LUA_INTERNALERROR("invalid var kind to store");
195+static void freereg (FuncState *fs, int reg) {
196+ if (reg >= fs->nactvar && reg < MAXSTACK) {
197+ fs->freereg--;
198+ lua_assert(reg == fs->freereg);
193199 }
194200 }
195201
196202
197−static OpCode invertjump (OpCode op) {
198− switch (op) {
199− case OP_JMPNE: return OP_JMPEQ;
200− case OP_JMPEQ: return OP_JMPNE;
201− case OP_JMPLT: return OP_JMPGE;
202− case OP_JMPLE: return OP_JMPGT;
203− case OP_JMPGT: return OP_JMPLE;
204− case OP_JMPGE: return OP_JMPLT;
205− case OP_JMPT: case OP_JMPONT: return OP_JMPF;
206− case OP_JMPF: case OP_JMPONF: return OP_JMPT;
207− default:
208− LUA_INTERNALERROR("invalid jump instruction");
209− return OP_END; /* to avoid warnings */
210− }
203+static void freeexp (FuncState *fs, expdesc *e) {
204+ if (e->k == VNONRELOC)
205+ freereg(fs, e->info);
211206 }
212207
213208
214−static void luaK_patchlistaux (FuncState *fs, int list, int target,
215− OpCode special, int special_target) {
216− Instruction *code = fs->f->code;
217− while (list != NO_JUMP) {
218− int next = luaK_getjump(fs, list);
219− Instruction *i = &code[list];
220− OpCode op = GET_OPCODE(*i);
221− if (op == special) /* this `op' already has a value */
222− luaK_fixjump(fs, list, special_target);
223− else {
224− luaK_fixjump(fs, list, target); /* do the patch */
225− if (op == OP_JMPONT) /* remove eventual values */
226− SET_OPCODE(*i, OP_JMPT);
227− else if (op == OP_JMPONF)
228− SET_OPCODE(*i, OP_JMPF);
229− }
230− list = next;
209+static int addk (FuncState *fs, TObject *k, TObject *v) {
210+ const TObject *idx = luaH_get(fs->h, k);
211+ if (ttisnumber(idx)) {
212+ lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
213+ return cast(int, nvalue(idx));
214+ }
215+ else { /* constant not found; create a new entry */
216+ Proto *f = fs->f;
217+ luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
218+ MAXARG_Bx, "constant table overflow");
219+ setobj2n(&f->k[fs->nk], v);
220+ setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
221+ return fs->nk++;
231222 }
232223 }
233224
234225
235−void luaK_patchlist (FuncState *fs, int list, int target) {
236− if (target == fs->lasttarget) /* same target that list `jlt'? */
237− luaK_concat(fs, &fs->jlt, list); /* delay fixing */
238− else
239− luaK_patchlistaux(fs, list, target, OP_END, 0);
226+int luaK_stringK (FuncState *fs, TString *s) {
227+ TObject o;
228+ setsvalue(&o, s);
229+ return addk(fs, &o, &o);
240230 }
241231
242232
243−static int need_value (FuncState *fs, int list, OpCode hasvalue) {
244− /* check whether list has a jump without a value */
245− for (; list != NO_JUMP; list = luaK_getjump(fs, list))
246− if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;
247− return 0; /* not found */
233+int luaK_numberK (FuncState *fs, lua_Number r) {
234+ TObject o;
235+ setnvalue(&o, r);
236+ return addk(fs, &o, &o);
248237 }
249238
250239
251−void luaK_concat (FuncState *fs, int *l1, int l2) {
252− if (*l1 == NO_JUMP)
253− *l1 = l2;
254− else {
255− int list = *l1;
256− for (;;) { /* traverse `l1' */
257− int next = luaK_getjump(fs, list);
258− if (next == NO_JUMP) { /* end of list? */
259− luaK_fixjump(fs, list, l2);
260− return;
261− }
262− list = next;
263− }
264− }
240+static int nil_constant (FuncState *fs) {
241+ TObject k, v;
242+ setnilvalue(&v);
243+ sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */
244+ return addk(fs, &k, &v);
265245 }
266246
267247
268−static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
269− int prevpos; /* position of last instruction */
270− Instruction *previous;
271− int *golist, *exitlist;
272− if (!invert) {
273− golist = &v->u.l.f; /* go if false */
274− exitlist = &v->u.l.t; /* exit if true */
275− }
276− else {
277− golist = &v->u.l.t; /* go if true */
278− exitlist = &v->u.l.f; /* exit if false */
279− }
280− discharge1(fs, v);
281− prevpos = fs->pc-1;
282− previous = &fs->f->code[prevpos];
283− LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");
284− if (!ISJUMP(GET_OPCODE(*previous)))
285− prevpos = luaK_code1(fs, jump, NO_JUMP);
286− else { /* last instruction is already a jump */
287− if (invert)
288− SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
248+void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
249+ if (e->k == VCALL) { /* expression is an open function call? */
250+ SETARG_C(getcode(fs, e), nresults+1);
251+ if (nresults == 1) { /* `regular' expression? */
252+ e->k = VNONRELOC;
253+ e->info = GETARG_A(getcode(fs, e));
254+ }
289255 }
290− luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */
291− luaK_patchlist(fs, *golist, luaK_getlabel(fs));
292− *golist = NO_JUMP;
293256 }
294257
295258
296−void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
297− luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
259+void luaK_dischargevars (FuncState *fs, expdesc *e) {
260+ switch (e->k) {
261+ case VLOCAL: {
262+ e->k = VNONRELOC;
263+ break;
264+ }
265+ case VUPVAL: {
266+ e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
267+ e->k = VRELOCABLE;
268+ break;
269+ }
270+ case VGLOBAL: {
271+ e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
272+ e->k = VRELOCABLE;
273+ break;
274+ }
275+ case VINDEXED: {
276+ freereg(fs, e->aux);
277+ freereg(fs, e->info);
278+ e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
279+ e->k = VRELOCABLE;
280+ break;
281+ }
282+ case VCALL: {
283+ luaK_setcallreturns(fs, e, 1);
284+ break;
285+ }
286+ default: break; /* there is one value available (somewhere) */
287+ }
298288 }
299289
300290
301−static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
302− luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
291+static int code_label (FuncState *fs, int A, int b, int jump) {
292+ luaK_getlabel(fs); /* those instructions may be jump targets */
293+ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
303294 }
304295
305296
306−static int code_label (FuncState *fs, OpCode op, int arg) {
307− luaK_getlabel(fs); /* those instructions may be jump targets */
308− return luaK_code1(fs, op, arg);
309−}
310−
311−
312−void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
313− FuncState *fs = ls->fs;
314− if (!discharge(fs, v)) { /* `v' is an expression? */
315− OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
316− if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
317− /* expression has no jumps */
318− if (onlyone)
319− luaK_setcallreturns(fs, 1); /* call must return 1 value */
320− }
321− else { /* expression has jumps */
322− int final; /* position after whole expression */
323− int j = NO_JUMP; /* eventual jump over values */
324− int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */
325− int p_1 = NO_JUMP; /* position of an eventual PUSHINT */
326− if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF)
327− || need_value(fs, v->u.l.t, OP_JMPONT)) {
328− /* expression needs values */
329− if (ISJUMP(previous))
330− luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */
331− else {
332− j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */
333− /* correct stack for compiler and symbolic execution */
334− luaK_adjuststack(fs, 1);
335− }
336− p_nil = code_label(fs, OP_PUSHNILJMP, 0);
337− p_1 = code_label(fs, OP_PUSHINT, 1);
338− luaK_patchlist(fs, j, luaK_getlabel(fs));
339− }
340− final = luaK_getlabel(fs);
341− luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);
342− luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);
343− v->u.l.f = v->u.l.t = NO_JUMP;
297+static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
298+ luaK_dischargevars(fs, e);
299+ switch (e->k) {
300+ case VNIL: {
301+ luaK_nil(fs, reg, 1);
302+ break;
303+ }
304+ case VFALSE: case VTRUE: {
305+ luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
306+ break;
307+ }
308+ case VK: {
309+ luaK_codeABx(fs, OP_LOADK, reg, e->info);
310+ break;
311+ }
312+ case VRELOCABLE: {
313+ Instruction *pc = &getcode(fs, e);
314+ SETARG_A(*pc, reg);
315+ break;
316+ }
317+ case VNONRELOC: {
318+ if (reg != e->info)
319+ luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
320+ break;
321+ }
322+ default: {
323+ lua_assert(e->k == VVOID || e->k == VJMP);
324+ return; /* nothing to do... */
344325 }
345326 }
327+ e->info = reg;
328+ e->k = VNONRELOC;
346329 }
347330
348331
349−void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) {
350− FuncState *fs = ls->fs;
351− if (op == OPR_MINUS) {
352− luaK_tostack(ls, v, 1);
353− luaK_code0(fs, OP_MINUS);
332+static void discharge2anyreg (FuncState *fs, expdesc *e) {
333+ if (e->k != VNONRELOC) {
334+ luaK_reserveregs(fs, 1);
335+ discharge2reg(fs, e, fs->freereg-1);
354336 }
355− else { /* op == NOT */
356− Instruction *previous;
357− discharge1(fs, v);
358− previous = &fs->f->code[fs->pc-1];
359− if (ISJUMP(GET_OPCODE(*previous)))
360− SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
361− else
362− luaK_code0(fs, OP_NOT);
363− /* interchange true and false lists */
364− { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
337+}
338+
339+
340+static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
341+ discharge2reg(fs, e, reg);
342+ if (e->k == VJMP)
343+ luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
344+ if (hasjumps(e)) {
345+ int final; /* position after whole expression */
346+ int p_f = NO_JUMP; /* position of an eventual LOAD false */
347+ int p_t = NO_JUMP; /* position of an eventual LOAD true */
348+ if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
349+ int fj = NO_JUMP; /* first jump (over LOAD ops.) */
350+ if (e->k != VJMP)
351+ fj = luaK_jump(fs);
352+ p_f = code_label(fs, reg, 0, 1);
353+ p_t = code_label(fs, reg, 1, 0);
354+ luaK_patchtohere(fs, fj);
355+ }
356+ final = luaK_getlabel(fs);
357+ luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
358+ luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
365359 }
360+ e->f = e->t = NO_JUMP;
361+ e->info = reg;
362+ e->k = VNONRELOC;
366363 }
367364
368365
369−void luaK_infix (LexState *ls, BinOpr op, expdesc *v) {
370− FuncState *fs = ls->fs;
371− switch (op) {
372− case OPR_AND:
373− luaK_goiftrue(fs, v, 1);
374− break;
375− case OPR_OR:
376− luaK_goiffalse(fs, v, 1);
377− break;
378− default:
379− luaK_tostack(ls, v, 1); /* all other binary operators need a value */
366+void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
367+ luaK_dischargevars(fs, e);
368+ freeexp(fs, e);
369+ luaK_reserveregs(fs, 1);
370+ luaK_exp2reg(fs, e, fs->freereg - 1);
371+}
372+
373+
374+int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
375+ luaK_dischargevars(fs, e);
376+ if (e->k == VNONRELOC) {
377+ if (!hasjumps(e)) return e->info; /* exp is already in a register */
378+ if (e->info >= fs->nactvar) { /* reg. is not a local? */
379+ luaK_exp2reg(fs, e, e->info); /* put value on it */
380+ return e->info;
381+ }
380382 }
383+ luaK_exp2nextreg(fs, e); /* default */
384+ return e->info;
381385 }
382386
383387
388+void luaK_exp2val (FuncState *fs, expdesc *e) {
389+ if (hasjumps(e))
390+ luaK_exp2anyreg(fs, e);
391+ else
392+ luaK_dischargevars(fs, e);
393+}
384394
385−static const struct {
386− OpCode opcode; /* opcode for each binary operator */
387− int arg; /* default argument for the opcode */
388−} codes[] = { /* ORDER OPR */
389− {OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0},
390− {OP_POW, 0}, {OP_CONCAT, 2},
391− {OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP},
392− {OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP},
393− {OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP}
394−};
395395
396+int luaK_exp2RK (FuncState *fs, expdesc *e) {
397+ luaK_exp2val(fs, e);
398+ switch (e->k) {
399+ case VNIL: {
400+ if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */
401+ e->info = nil_constant(fs);
402+ e->k = VK;
403+ return e->info + MAXSTACK;
404+ }
405+ else break;
406+ }
407+ case VK: {
408+ if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */
409+ return e->info + MAXSTACK;
410+ else break;
411+ }
412+ default: break;
413+ }
414+ /* not a constant in the right range: put it in a register */
415+ return luaK_exp2anyreg(fs, e);
416+}
396417
397−void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) {
398− FuncState *fs = ls->fs;
399− switch (op) {
400− case OPR_AND: {
401− LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed");
402− discharge1(fs, v2);
403− v1->u.l.t = v2->u.l.t;
404− luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
418+
419+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
420+ switch (var->k) {
421+ case VLOCAL: {
422+ freeexp(fs, exp);
423+ luaK_exp2reg(fs, exp, var->info);
424+ return;
425+ }
426+ case VUPVAL: {
427+ int e = luaK_exp2anyreg(fs, exp);
428+ luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
405429 break;
406430 }
407− case OPR_OR: {
408− LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed");
409− discharge1(fs, v2);
410− v1->u.l.f = v2->u.l.f;
411− luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
431+ case VGLOBAL: {
432+ int e = luaK_exp2anyreg(fs, exp);
433+ luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
434+ break;
435+ }
436+ case VINDEXED: {
437+ int e = luaK_exp2RK(fs, exp);
438+ luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
412439 break;
413440 }
414441 default: {
415− luaK_tostack(ls, v2, 1); /* `v2' must be a value */
416− luaK_code1(fs, codes[op].opcode, codes[op].arg);
442+ lua_assert(0); /* invalid var kind to store */
443+ break;
417444 }
418445 }
446+ freeexp(fs, exp);
419447 }
420448
421449
422−static void codelineinfo (FuncState *fs) {
423− Proto *f = fs->f;
424− LexState *ls = fs->ls;
425− if (ls->lastline > fs->lastline) {
426− luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int,
427− "line info overflow", MAX_INT);
428− if (ls->lastline > fs->lastline+1)
429− f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
430− f->lineinfo[f->nlineinfo++] = fs->pc;
431− fs->lastline = ls->lastline;
432− }
450+void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
451+ int func;
452+ luaK_exp2anyreg(fs, e);
453+ freeexp(fs, e);
454+ func = fs->freereg;
455+ luaK_reserveregs(fs, 2);
456+ luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
457+ freeexp(fs, key);
458+ e->info = func;
459+ e->k = VNONRELOC;
433460 }
434461
435462
436−int luaK_code0 (FuncState *fs, OpCode o) {
437− return luaK_code2(fs, o, 0, 0);
463+static void invertjump (FuncState *fs, expdesc *e) {
464+ Instruction *pc = getjumpcontrol(fs, e->info);
465+ lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
466+ GET_OPCODE(*pc) != OP_TEST);
467+ SETARG_A(*pc, !(GETARG_A(*pc)));
438468 }
439469
440470
441−int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
442− return luaK_code2(fs, o, arg1, 0);
471+static int jumponcond (FuncState *fs, expdesc *e, int cond) {
472+ if (e->k == VRELOCABLE) {
473+ Instruction ie = getcode(fs, e);
474+ if (GET_OPCODE(ie) == OP_NOT) {
475+ fs->pc--; /* remove previous OP_NOT */
476+ return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
477+ }
478+ /* else go through */
479+ }
480+ discharge2anyreg(fs, e);
481+ freeexp(fs, e);
482+ return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
443483 }
444484
445485
446−int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
447− Instruction i = previous_instruction(fs);
448− int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
449− int optm = 0; /* 1 when there is an optimization */
450− switch (o) {
451− case OP_CLOSURE: {
452− delta = -arg2+1;
486+void luaK_goiftrue (FuncState *fs, expdesc *e) {
487+ int pc; /* pc of last jump */
488+ luaK_dischargevars(fs, e);
489+ switch (e->k) {
490+ case VK: case VTRUE: {
491+ pc = NO_JUMP; /* always true; do nothing */
453492 break;
454493 }
455− case OP_SETTABLE: {
456− delta = -arg2;
494+ case VFALSE: {
495+ pc = luaK_jump(fs); /* always jump */
457496 break;
458497 }
459− case OP_SETLIST: {
460− if (arg2 == 0) return NO_JUMP; /* nothing to do */
461− delta = -arg2;
498+ case VJMP: {
499+ invertjump(fs, e);
500+ pc = e->info;
462501 break;
463502 }
464− case OP_SETMAP: {
465− if (arg1 == 0) return NO_JUMP; /* nothing to do */
466− delta = -2*arg1;
503+ default: {
504+ pc = jumponcond(fs, e, 0);
467505 break;
468506 }
469− case OP_RETURN: {
470− if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
471− SET_OPCODE(i, OP_TAILCALL);
472− SETARG_B(i, arg1);
473− optm = 1;
474− }
507+ }
508+ luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
509+}
510+
511+
512+void luaK_goiffalse (FuncState *fs, expdesc *e) {
513+ int pc; /* pc of last jump */
514+ luaK_dischargevars(fs, e);
515+ switch (e->k) {
516+ case VNIL: case VFALSE: {
517+ pc = NO_JUMP; /* always false; do nothing */
475518 break;
476519 }
477− case OP_PUSHNIL: {
478− if (arg1 == 0) return NO_JUMP; /* nothing to do */
479− delta = arg1;
480− switch(GET_OPCODE(i)) {
481− case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
482− default: break;
483− }
520+ case VTRUE: {
521+ pc = luaK_jump(fs); /* always jump */
484522 break;
485523 }
486− case OP_POP: {
487− if (arg1 == 0) return NO_JUMP; /* nothing to do */
488− delta = -arg1;
489− switch(GET_OPCODE(i)) {
490− case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
491− default: break;
492− }
524+ case VJMP: {
525+ pc = e->info;
493526 break;
494527 }
495− case OP_GETTABLE: {
496− switch(GET_OPCODE(i)) {
497− case OP_PUSHSTRING: /* `t.x' */
498− SET_OPCODE(i, OP_GETDOTTED);
499− optm = 1;
500− break;
501− case OP_GETLOCAL: /* `t[i]' */
502− SET_OPCODE(i, OP_GETINDEXED);
503− optm = 1;
504− break;
505− default: break;
506− }
528+ default: {
529+ pc = jumponcond(fs, e, 1);
507530 break;
508531 }
509− case OP_ADD: {
510− switch(GET_OPCODE(i)) {
511− case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */
512− default: break;
513− }
532+ }
533+ luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
534+}
535+
536+
537+static void codenot (FuncState *fs, expdesc *e) {
538+ luaK_dischargevars(fs, e);
539+ switch (e->k) {
540+ case VNIL: case VFALSE: {
541+ e->k = VTRUE;
514542 break;
515543 }
516− case OP_SUB: {
517− switch(GET_OPCODE(i)) {
518− case OP_PUSHINT: /* `a-k' */
519− i = CREATE_S(OP_ADDI, -GETARG_S(i));
520− optm = 1;
521− break;
522− default: break;
523− }
544+ case VK: case VTRUE: {
545+ e->k = VFALSE;
524546 break;
525547 }
526− case OP_CONCAT: {
527− delta = -arg1+1;
528− switch(GET_OPCODE(i)) {
529− case OP_CONCAT: /* `a..b..c' */
530− SETARG_U(i, GETARG_U(i)+1);
531− optm = 1;
532− break;
533− default: break;
534− }
548+ case VJMP: {
549+ invertjump(fs, e);
535550 break;
536551 }
537− case OP_MINUS: {
538− switch(GET_OPCODE(i)) {
539− case OP_PUSHINT: /* `-k' */
540− SETARG_S(i, -GETARG_S(i));
541− optm = 1;
542− break;
543− case OP_PUSHNUM: /* `-k' */
544− SET_OPCODE(i, OP_PUSHNEGNUM);
545− optm = 1;
546− break;
547− default: break;
548− }
552+ case VRELOCABLE:
553+ case VNONRELOC: {
554+ discharge2anyreg(fs, e);
555+ freeexp(fs, e);
556+ e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
557+ e->k = VRELOCABLE;
549558 break;
550559 }
551− case OP_JMPNE: {
552− if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */
553− i = CREATE_S(OP_JMPT, NO_JUMP);
554− optm = 1;
555− }
560+ default: {
561+ lua_assert(0); /* cannot happen */
556562 break;
557563 }
558− case OP_JMPEQ: {
559− if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */
560− i = CREATE_0(OP_NOT);
561− delta = -1; /* just undo effect of previous PUSHNIL */
562− optm = 1;
563− }
564− break;
564+ }
565+ /* interchange true and false lists */
566+ { int temp = e->f; e->f = e->t; e->t = temp; }
567+}
568+
569+
570+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
571+ t->aux = luaK_exp2RK(fs, k);
572+ t->k = VINDEXED;
573+}
574+
575+
576+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
577+ if (op == OPR_MINUS) {
578+ luaK_exp2val(fs, e);
579+ if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
580+ e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
581+ else {
582+ luaK_exp2anyreg(fs, e);
583+ freeexp(fs, e);
584+ e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
585+ e->k = VRELOCABLE;
565586 }
566− case OP_JMPT:
567− case OP_JMPONT: {
568− switch (GET_OPCODE(i)) {
569− case OP_NOT: {
570− i = CREATE_S(OP_JMPF, NO_JUMP);
571− optm = 1;
572− break;
573− }
574− case OP_PUSHINT: {
575− if (o == OP_JMPT) { /* JMPONT must keep original integer value */
576− i = CREATE_S(OP_JMP, NO_JUMP);
577− optm = 1;
578− }
579− break;
580− }
581− case OP_PUSHNIL: {
582− if (GETARG_U(i) == 1) {
583− fs->pc--; /* erase previous instruction */
584− luaK_deltastack(fs, -1); /* correct stack */
585− return NO_JUMP;
586− }
587− break;
588− }
589− default: break;
590− }
587+ }
588+ else /* op == NOT */
589+ codenot(fs, e);
590+}
591+
592+
593+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
594+ switch (op) {
595+ case OPR_AND: {
596+ luaK_goiftrue(fs, v);
597+ luaK_patchtohere(fs, v->t);
598+ v->t = NO_JUMP;
591599 break;
592600 }
593− case OP_JMPF:
594− case OP_JMPONF: {
595− switch (GET_OPCODE(i)) {
596− case OP_NOT: {
597− i = CREATE_S(OP_JMPT, NO_JUMP);
598− optm = 1;
599− break;
600− }
601− case OP_PUSHINT: { /* `while 1 do ...' */
602− fs->pc--; /* erase previous instruction */
603− luaK_deltastack(fs, -1); /* correct stack */
604− return NO_JUMP;
605− }
606− case OP_PUSHNIL: { /* `repeat ... until nil' */
607− if (GETARG_U(i) == 1) {
608− i = CREATE_S(OP_JMP, NO_JUMP);
609− optm = 1;
610− }
611− break;
612− }
613− default: break;
614− }
601+ case OPR_OR: {
602+ luaK_goiffalse(fs, v);
603+ luaK_patchtohere(fs, v->f);
604+ v->f = NO_JUMP;
615605 break;
616606 }
617− case OP_GETDOTTED:
618− case OP_GETINDEXED:
619− case OP_TAILCALL:
620− case OP_ADDI: {
621− LUA_INTERNALERROR("instruction used only for optimizations");
607+ case OPR_CONCAT: {
608+ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
622609 break;
623610 }
624611 default: {
625− LUA_ASSERT(delta != VD, "invalid delta");
612+ luaK_exp2RK(fs, v);
626613 break;
627614 }
628615 }
629− luaK_deltastack(fs, delta);
630− if (optm) { /* optimize: put instruction in place of last one */
631− fs->f->code[fs->pc-1] = i; /* change previous instruction */
632− return fs->pc-1; /* do not generate new instruction */
616+}
617+
618+
619+static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
620+ int o1, int o2) {
621+ if (op <= OPR_POW) { /* arithmetic operator? */
622+ OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
623+ res->info = luaK_codeABC(fs, opc, 0, o1, o2);
624+ res->k = VRELOCABLE;
633625 }
634− /* else build new instruction */
635− switch ((enum Mode)luaK_opproperties[o].mode) {
636− case iO: i = CREATE_0(o); break;
637− case iU: i = CREATE_U(o, arg1); break;
638− case iS: i = CREATE_S(o, arg1); break;
639− case iAB: i = CREATE_AB(o, arg1, arg2); break;
626+ else { /* test operator */
627+ static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
628+ int cond = 1;
629+ if (op >= OPR_GT) { /* `>' or `>='? */
630+ int temp; /* exchange args and replace by `<' or `<=' */
631+ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
632+ }
633+ else if (op == OPR_NE) cond = 0;
634+ res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
635+ res->k = VJMP;
640636 }
641− codelineinfo(fs);
637+}
638+
639+
640+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
641+ switch (op) {
642+ case OPR_AND: {
643+ lua_assert(e1->t == NO_JUMP); /* list must be closed */
644+ luaK_dischargevars(fs, e2);
645+ luaK_concat(fs, &e1->f, e2->f);
646+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
647+ break;
648+ }
649+ case OPR_OR: {
650+ lua_assert(e1->f == NO_JUMP); /* list must be closed */
651+ luaK_dischargevars(fs, e2);
652+ luaK_concat(fs, &e1->t, e2->t);
653+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
654+ break;
655+ }
656+ case OPR_CONCAT: {
657+ luaK_exp2val(fs, e2);
658+ if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
659+ lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
660+ freeexp(fs, e1);
661+ SETARG_B(getcode(fs, e2), e1->info);
662+ e1->k = e2->k; e1->info = e2->info;
663+ }
664+ else {
665+ luaK_exp2nextreg(fs, e2);
666+ freeexp(fs, e2);
667+ freeexp(fs, e1);
668+ e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
669+ e1->k = VRELOCABLE;
670+ }
671+ break;
672+ }
673+ default: {
674+ int o1 = luaK_exp2RK(fs, e1);
675+ int o2 = luaK_exp2RK(fs, e2);
676+ freeexp(fs, e2);
677+ freeexp(fs, e1);
678+ codebinop(fs, e1, op, o1, o2);
679+ }
680+ }
681+}
682+
683+
684+void luaK_fixline (FuncState *fs, int line) {
685+ fs->f->lineinfo[fs->pc - 1] = line;
686+}
687+
688+
689+int luaK_code (FuncState *fs, Instruction i, int line) {
690+ Proto *f = fs->f;
691+ luaK_dischargejpc(fs); /* `pc' will change */
642692 /* put new instruction in code array */
643− luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
644− "code size overflow", MAX_INT);
645− fs->f->code[fs->pc] = i;
693+ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
694+ MAX_INT, "code size overflow");
695+ f->code[fs->pc] = i;
696+ /* save corresponding line information */
697+ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
698+ MAX_INT, "code size overflow");
699+ f->lineinfo[fs->pc] = line;
646700 return fs->pc++;
647701 }
648702
649703
650−const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
651− {iO, 0, 0}, /* OP_END */
652− {iU, 0, 0}, /* OP_RETURN */
653− {iAB, 0, 0}, /* OP_CALL */
654− {iAB, 0, 0}, /* OP_TAILCALL */
655− {iU, VD, 0}, /* OP_PUSHNIL */
656− {iU, VD, 0}, /* OP_POP */
657− {iS, 1, 0}, /* OP_PUSHINT */
658− {iU, 1, 0}, /* OP_PUSHSTRING */
659− {iU, 1, 0}, /* OP_PUSHNUM */
660− {iU, 1, 0}, /* OP_PUSHNEGNUM */
661− {iU, 1, 0}, /* OP_PUSHUPVALUE */
662− {iU, 1, 0}, /* OP_GETLOCAL */
663− {iU, 1, 0}, /* OP_GETGLOBAL */
664− {iO, 1, 2}, /* OP_GETTABLE */
665− {iU, 1, 1}, /* OP_GETDOTTED */
666− {iU, 1, 1}, /* OP_GETINDEXED */
667− {iU, 2, 1}, /* OP_PUSHSELF */
668− {iU, 1, 0}, /* OP_CREATETABLE */
669− {iU, 0, 1}, /* OP_SETLOCAL */
670− {iU, 0, 1}, /* OP_SETGLOBAL */
671− {iAB, VD, 0}, /* OP_SETTABLE */
672− {iAB, VD, 0}, /* OP_SETLIST */
673− {iU, VD, 0}, /* OP_SETMAP */
674− {iO, 1, 2}, /* OP_ADD */
675− {iS, 1, 1}, /* OP_ADDI */
676− {iO, 1, 2}, /* OP_SUB */
677− {iO, 1, 2}, /* OP_MULT */
678− {iO, 1, 2}, /* OP_DIV */
679− {iO, 1, 2}, /* OP_POW */
680− {iU, VD, 0}, /* OP_CONCAT */
681− {iO, 1, 1}, /* OP_MINUS */
682− {iO, 1, 1}, /* OP_NOT */
683− {iS, 0, 2}, /* OP_JMPNE */
684− {iS, 0, 2}, /* OP_JMPEQ */
685− {iS, 0, 2}, /* OP_JMPLT */
686− {iS, 0, 2}, /* OP_JMPLE */
687− {iS, 0, 2}, /* OP_JMPGT */
688− {iS, 0, 2}, /* OP_JMPGE */
689− {iS, 0, 1}, /* OP_JMPT */
690− {iS, 0, 1}, /* OP_JMPF */
691− {iS, 0, 1}, /* OP_JMPONT */
692− {iS, 0, 1}, /* OP_JMPONF */
693− {iS, 0, 0}, /* OP_JMP */
694− {iO, 0, 0}, /* OP_PUSHNILJMP */
695− {iS, 0, 0}, /* OP_FORPREP */
696− {iS, 0, 3}, /* OP_FORLOOP */
697− {iS, 2, 0}, /* OP_LFORPREP */
698− {iS, 0, 3}, /* OP_LFORLOOP */
699− {iAB, VD, 0} /* OP_CLOSURE */
700−};
704+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
705+ lua_assert(getOpMode(o) == iABC);
706+ return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
707+}
708+
709+
710+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
711+ lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
712+ return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
713+}
701714