aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-07 16:35:20 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-04-07 16:35:20 -0300
commit54dd5cc7fd42a8b073f64b7d16efdb1ed01e2dd5 (patch)
tree01c0e573c486173dcafc3ea0d0d45185f52aa19a
parent031978798cc404c2c6757c564675d43a7da129ee (diff)
downloadlua-54dd5cc7fd42a8b073f64b7d16efdb1ed01e2dd5.tar.gz
lua-54dd5cc7fd42a8b073f64b7d16efdb1ed01e2dd5.tar.bz2
lua-54dd5cc7fd42a8b073f64b7d16efdb1ed01e2dd5.zip
reorganization of lcode.c
-rw-r--r--lcode.c460
-rw-r--r--lcode.h11
-rw-r--r--lparser.c33
3 files changed, 252 insertions, 252 deletions
diff --git a/lcode.c b/lcode.c
index 157724d1..c1bcc980 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.21 2000/04/06 17:36:52 roberto Exp roberto $ 2** $Id: lcode.c,v 1.22 2000/04/07 13:13:11 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,8 +23,9 @@ void luaK_error (LexState *ls, const char *msg) {
23 luaX_error(ls, msg, ls->token); 23 luaX_error(ls, msg, ls->token);
24} 24}
25 25
26
26/* 27/*
27** Returns the the previous instruction, for optimizations. 28** Returns the the previous instruction, for optimizations.
28** If there is a jump target between this and the current instruction, 29** If there is a jump target between this and the current instruction,
29** returns a dummy instruction to avoid wrong optimizations. 30** returns a dummy instruction to avoid wrong optimizations.
30*/ 31*/
@@ -36,154 +37,8 @@ static Instruction previous_instruction (FuncState *fs) {
36} 37}
37 38
38 39
39int luaK_code (FuncState *fs, Instruction i, int delta) {
40 luaK_deltastack(fs, delta);
41 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
42 fs->f->code[fs->pc] = i;
43 return fs->pc++;
44}
45
46int luaK_0(FuncState *fs, OpCode o, int d) {
47 return luaK_code(fs, CREATE_0(o), d);
48}
49
50int luaK_U(FuncState *fs, OpCode o, int u, int d) {
51 return luaK_code(fs, CREATE_U(o,u), d);
52}
53
54int luaK_S(FuncState *fs, OpCode o, int s, int d) {
55 return luaK_code(fs, CREATE_S(o,s), d);
56}
57
58int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d) {
59 return luaK_code(fs, CREATE_AB(o,a,b), d);
60}
61
62
63static Instruction prepare (FuncState *fs, Instruction i, int delta) {
64 Instruction previous = previous_instruction(fs);
65 luaK_code(fs, i, delta);
66 return previous;
67}
68
69
70static void setprevious (FuncState *fs, Instruction i) {
71 fs->pc--; /* remove last instruction */
72 fs->f->code[fs->pc-1] = i; /* change previous instruction */
73}
74
75
76static void luaK_minus (FuncState *fs) {
77 /* PUSHINT s; MINUS -> PUSHINT -s (-k) */
78 /* PUSHNUM u; MINUS -> PUSHNEGNUM u (-k) */
79 Instruction previous = prepare(fs, CREATE_0(OP_MINUS), 0);
80 switch(GET_OPCODE(previous)) {
81 case OP_PUSHINT: SETARG_S(previous, -GETARG_S(previous)); break;
82 case OP_PUSHNUM: SET_OPCODE(previous, OP_PUSHNEGNUM); break;
83 default: return;
84 }
85 setprevious(fs, previous);
86}
87
88
89static void luaK_gettable (FuncState *fs) {
90 /* PUSHSTRING u; GETTABLE -> GETDOTTED u (t.x) */
91 /* GETLOCAL u; GETTABLE -> GETINDEXED u (t[i]) */
92 Instruction previous = prepare(fs, CREATE_0(OP_GETTABLE), -1);
93 switch(GET_OPCODE(previous)) {
94 case OP_PUSHSTRING: SET_OPCODE(previous, OP_GETDOTTED); break;
95 case OP_GETLOCAL: SET_OPCODE(previous, OP_GETINDEXED); break;
96 default: return;
97 }
98 setprevious(fs, previous);
99}
100
101
102static void luaK_add (FuncState *fs) {
103 /* PUSHINT s; ADD -> ADDI s (a+k) */
104 Instruction previous = prepare(fs, CREATE_0(OP_ADD), -1);
105 switch(GET_OPCODE(previous)) {
106 case OP_PUSHINT: SET_OPCODE(previous, OP_ADDI); break;
107 default: return;
108 }
109 setprevious(fs, previous);
110}
111
112
113static void luaK_sub (FuncState *fs) {
114 /* PUSHINT s; SUB -> ADDI -s (a-k) */
115 Instruction previous = prepare(fs, CREATE_0(OP_SUB), -1);
116 switch(GET_OPCODE(previous)) {
117 case OP_PUSHINT:
118 SET_OPCODE(previous, OP_ADDI);
119 SETARG_S(previous, -GETARG_S(previous));
120 break;
121 default: return;
122 }
123 setprevious(fs, previous);
124}
125
126
127static void luaK_conc (FuncState *fs) {
128 /* CONCAT u; CONCAT 2 -> CONCAT u+1 (a..b..c) */
129 Instruction previous = prepare(fs, CREATE_U(OP_CONCAT, 2), -1);
130 switch(GET_OPCODE(previous)) {
131 case OP_CONCAT: SETARG_U(previous, GETARG_U(previous)+1); break;
132 default: return;
133 }
134 setprevious(fs, previous);
135}
136
137
138static void luaK_getlocal (FuncState *fs, int l) {
139 /* SETLOCAL l 1; GETLOCAL l -> SETLOCAL l 0 */
140 Instruction previous = prepare(fs, CREATE_U(OP_GETLOCAL, l), 1);
141 if (previous == CREATE_AB(OP_SETLOCAL, l, 1)) {
142 SETARG_B(previous, 0);
143 setprevious(fs, previous);
144 }
145}
146
147
148static void luaK_setlocal (FuncState *fs, int l) {
149 /* GETLOCAL l; ADDI k, SETLOCAL l -> INCLOCAL k, l ((local)a=a+k) */
150 Instruction *code = fs->f->code;
151 int pc = fs->pc;
152 if (pc-1 > fs->lasttarget && /* no jumps in-between instructions? */
153 code[pc-2] == CREATE_U(OP_GETLOCAL, l) &&
154 GET_OPCODE(code[pc-1]) == OP_ADDI &&
155 abs(GETARG_S(code[pc-1])) <= MAXARG_sA) {
156 int inc = GETARG_S(code[pc-1]);
157 fs->pc = pc-1;
158 code[pc-2] = CREATE_sAB(OP_INCLOCAL, inc, l);
159 luaK_deltastack(fs, -1);
160 }
161 else
162 luaK_AB(fs, OP_SETLOCAL, l, 1, -1);
163}
164
165
166static void luaK_eq (FuncState *fs) {
167 /* PUSHNIL 1; JMPEQ -> NOT (a==nil) */
168 Instruction previous = prepare(fs, CREATE_S(OP_JMPEQ, NO_JUMP), -2);
169 if (previous == CREATE_U(OP_PUSHNIL, 1)) {
170 setprevious(fs, CREATE_0(OP_NOT));
171 luaK_deltastack(fs, 1); /* undo delta from `prepare' */
172 }
173}
174
175
176static void luaK_neq (FuncState *fs) {
177 /* PUSHNIL 1; JMPNE -> JMPT (a~=nil) */
178 Instruction previous = prepare(fs, CREATE_S(OP_JMPNE, NO_JUMP), -2);
179 if (previous == CREATE_U(OP_PUSHNIL, 1)) {
180 setprevious(fs, CREATE_S(OP_JMPT, NO_JUMP));
181 }
182}
183
184
185int luaK_jump (FuncState *fs) { 40int luaK_jump (FuncState *fs) {
186 int j = luaK_S(fs, OP_JMP, NO_JUMP, 0); 41 int j = luaK_code1(fs, OP_JMP, NO_JUMP);
187 if (j == fs->lasttarget) { /* possible jumps to this jump? */ 42 if (j == fs->lasttarget) { /* possible jumps to this jump? */
188 luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ 43 luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
189 fs->jlt = NO_JUMP; 44 fs->jlt = NO_JUMP;
@@ -192,38 +47,6 @@ int luaK_jump (FuncState *fs) {
192} 47}
193 48
194 49
195void luaK_retcode (FuncState *fs, int nlocals, int nexps) {
196 Instruction previous = prepare(fs, CREATE_U(OP_RETURN, nlocals), 0);
197 if (nexps > 0 && GET_OPCODE(previous) == OP_CALL) {
198 LUA_ASSERT(fs->L, GETARG_B(previous) == MULT_RET, "call should be open");
199 SET_OPCODE(previous, OP_TAILCALL);
200 SETARG_B(previous, nlocals);
201 setprevious(fs, previous);
202 }
203}
204
205
206static void luaK_pushnil (FuncState *fs, int n) {
207 Instruction previous = prepare(fs, CREATE_U(OP_PUSHNIL, n), n);
208 switch(GET_OPCODE(previous)) {
209 case OP_PUSHNIL: SETARG_U(previous, GETARG_U(previous)+n); break;
210 default: return;
211 }
212 setprevious(fs, previous);
213}
214
215
216static void luaK_pop (FuncState *fs, int n) {
217 Instruction previous = prepare(fs, CREATE_U(OP_POP, n), -n);
218 switch(GET_OPCODE(previous)) {
219 case OP_SETTABLE: SETARG_B(previous, GETARG_B(previous)+n); break;
220 case OP_SETLOCAL: SETARG_B(previous, GETARG_B(previous)+n); break;
221 default: return;
222 }
223 setprevious(fs, previous);
224}
225
226
227static void luaK_fixjump (FuncState *fs, int pc, int dest) { 50static void luaK_fixjump (FuncState *fs, int pc, int dest) {
228 Instruction *jmp = &fs->f->code[pc]; 51 Instruction *jmp = &fs->f->code[pc];
229 if (dest == NO_JUMP) 52 if (dest == NO_JUMP)
@@ -274,7 +97,7 @@ void luaK_deltastack (FuncState *fs, int delta) {
274 97
275 98
276void luaK_kstr (LexState *ls, int c) { 99void luaK_kstr (LexState *ls, int c) {
277 luaK_U(ls->fs, OP_PUSHSTRING, c, 1); 100 luaK_code1(ls->fs, OP_PUSHSTRING, c);
278} 101}
279 102
280 103
@@ -295,17 +118,17 @@ static int real_constant (FuncState *fs, Number r) {
295 118
296void luaK_number (FuncState *fs, Number f) { 119void luaK_number (FuncState *fs, Number f) {
297 if (f <= (Number)MAXARG_S && (int)f == f) 120 if (f <= (Number)MAXARG_S && (int)f == f)
298 luaK_S(fs, OP_PUSHINT, (int)f, 1); /* f has a short integer value */ 121 luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */
299 else 122 else
300 luaK_U(fs, OP_PUSHNUM, real_constant(fs, f), 1); 123 luaK_code1(fs, OP_PUSHNUM, real_constant(fs, f));
301} 124}
302 125
303 126
304void luaK_adjuststack (FuncState *fs, int n) { 127void luaK_adjuststack (FuncState *fs, int n) {
305 if (n > 0) 128 if (n > 0)
306 luaK_pop(fs, n); 129 luaK_code1(fs, OP_POP, n);
307 else if (n < 0) 130 else if (n < 0)
308 luaK_pushnil(fs, -n); 131 luaK_code1(fs, OP_PUSHNIL, -n);
309} 132}
310 133
311 134
@@ -334,14 +157,14 @@ static void assertglobal (FuncState *fs, int index) {
334static int discharge (FuncState *fs, expdesc *var) { 157static int discharge (FuncState *fs, expdesc *var) {
335 switch (var->k) { 158 switch (var->k) {
336 case VLOCAL: 159 case VLOCAL:
337 luaK_getlocal(fs, var->u.index); 160 luaK_code1(fs, OP_GETLOCAL, var->u.index);
338 break; 161 break;
339 case VGLOBAL: 162 case VGLOBAL:
340 luaK_U(fs, OP_GETGLOBAL, var->u.index, 1); 163 luaK_code1(fs, OP_GETGLOBAL, var->u.index);
341 assertglobal(fs, var->u.index); /* make sure that there is a global */ 164 assertglobal(fs, var->u.index); /* make sure that there is a global */
342 break; 165 break;
343 case VINDEXED: 166 case VINDEXED:
344 luaK_gettable(fs); 167 luaK_code0(fs, OP_GETTABLE);
345 break; 168 break;
346 case VEXP: 169 case VEXP:
347 return 0; /* nothing to do */ 170 return 0; /* nothing to do */
@@ -358,20 +181,20 @@ static void discharge1 (FuncState *fs, expdesc *var) {
358 if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) 181 if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP)
359 luaK_setcallreturns(fs, 1); /* call must return 1 value */ 182 luaK_setcallreturns(fs, 1); /* call must return 1 value */
360} 183}
361 184
362 185
363void luaK_storevar (LexState *ls, const expdesc *var) { 186void luaK_storevar (LexState *ls, const expdesc *var) {
364 FuncState *fs = ls->fs; 187 FuncState *fs = ls->fs;
365 switch (var->k) { 188 switch (var->k) {
366 case VLOCAL: 189 case VLOCAL:
367 luaK_setlocal(fs, var->u.index); 190 luaK_code1(fs, OP_SETLOCAL, var->u.index);
368 break; 191 break;
369 case VGLOBAL: 192 case VGLOBAL:
370 luaK_U(fs, OP_SETGLOBAL, var->u.index, -1); 193 luaK_code1(fs, OP_SETGLOBAL, var->u.index);
371 assertglobal(fs, var->u.index); /* make sure that there is a global */ 194 assertglobal(fs, var->u.index); /* make sure that there is a global */
372 break; 195 break;
373 case VINDEXED: /* table is at top-3; pop 3 elements after operation */ 196 case VINDEXED: /* table is at top-3; pop 3 elements after operation */
374 luaK_AB(fs, OP_SETTABLE, 3, 3, -3); 197 luaK_code2(fs, OP_SETTABLE, 3, 3);
375 break; 198 break;
376 default: 199 default:
377 LUA_INTERNALERROR(ls->L, "invalid var kind to store"); 200 LUA_INTERNALERROR(ls->L, "invalid var kind to store");
@@ -396,16 +219,6 @@ static OpCode invertjump (OpCode op) {
396} 219}
397 220
398 221
399static void luaK_condjump (FuncState *fs, OpCode jump) {
400 Instruction previous = prepare(fs, CREATE_S(jump, NO_JUMP), -1);
401 switch (GET_OPCODE(previous)) {
402 case OP_NOT: previous = CREATE_S(invertjump(jump), NO_JUMP); break;
403 default: return;
404 }
405 setprevious(fs, previous);
406}
407
408
409static void luaK_patchlistaux (FuncState *fs, int list, int target, 222static void luaK_patchlistaux (FuncState *fs, int list, int target,
410 OpCode special, int special_target) { 223 OpCode special, int special_target) {
411 Instruction *code = fs->f->code; 224 Instruction *code = fs->f->code;
@@ -475,7 +288,7 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
475 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); 288 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
476 } 289 }
477 else 290 else
478 luaK_condjump(fs, jump); 291 luaK_code0(fs, jump);
479 luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ 292 luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */
480 luaK_patchlist(fs, *golist, luaK_getlabel(fs)); 293 luaK_patchlist(fs, *golist, luaK_getlabel(fs));
481 *golist = NO_JUMP; 294 *golist = NO_JUMP;
@@ -508,23 +321,25 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
508 int final; /* position after whole expression */ 321 int final; /* position after whole expression */
509 if (ISJUMP(previous)) { 322 if (ISJUMP(previous)) {
510 luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in true list */ 323 luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in true list */
511 p_nil = luaK_0(fs, OP_PUSHNILJMP, 0); 324 p_nil = luaK_code0(fs, OP_PUSHNILJMP);
512 p_1 = luaK_S(fs, OP_PUSHINT, 1, 1); 325 p_1 = luaK_code1(fs, OP_PUSHINT, 1);
513 } 326 }
514 else { /* still may need a PUSHNIL or a PUSHINT */ 327 else { /* still may need a PUSHNIL or a PUSHINT */
515 int need_nil = need_value(fs, v->u.l.f, OP_JMPONF); 328 int need_nil = need_value(fs, v->u.l.f, OP_JMPONF);
516 int need_1 = need_value(fs, v->u.l.t, OP_JMPONT); 329 int need_1 = need_value(fs, v->u.l.t, OP_JMPONT);
517 if (need_nil && need_1) { 330 if (need_nil && need_1) {
518 luaK_S(fs, OP_JMP, 2, 0); /* skip both pushes */ 331 luaK_code1(fs, OP_JMP, 2); /* skip both pushes */
519 p_nil = luaK_0(fs, OP_PUSHNILJMP, 0); 332 p_nil = luaK_code0(fs, OP_PUSHNILJMP);
520 p_1 = luaK_S(fs, OP_PUSHINT, 1, 0); 333 p_1 = luaK_code1(fs, OP_PUSHINT, 1);
334 luaK_deltastack(fs, -1); /* previous PUSHINT may be skipped */
521 } 335 }
522 else if (need_nil || need_1) { 336 else if (need_nil || need_1) {
523 luaK_S(fs, OP_JMP, 1, 0); /* skip one push */ 337 luaK_code1(fs, OP_JMP, 1); /* skip one push */
524 if (need_nil) 338 if (need_nil)
525 p_nil = luaK_U(fs, OP_PUSHNIL, 1, 0); 339 p_nil = luaK_code1(fs, OP_PUSHNIL, 1);
526 else /* need_1 */ 340 else /* need_1 */
527 p_1 = luaK_S(fs, OP_PUSHINT, 1, 0); 341 p_1 = luaK_code1(fs, OP_PUSHINT, 1);
342 luaK_deltastack(fs, -1); /* previous PUSHs may be skipped */
528 } 343 }
529 } 344 }
530 final = luaK_getlabel(fs); 345 final = luaK_getlabel(fs);
@@ -540,7 +355,7 @@ void luaK_prefix (LexState *ls, int op, expdesc *v) {
540 FuncState *fs = ls->fs; 355 FuncState *fs = ls->fs;
541 if (op == '-') { 356 if (op == '-') {
542 luaK_tostack(ls, v, 1); 357 luaK_tostack(ls, v, 1);
543 luaK_minus(fs); 358 luaK_code0(fs, OP_MINUS);
544 } 359 }
545 else { /* op == NOT */ 360 else { /* op == NOT */
546 Instruction *previous; 361 Instruction *previous;
@@ -549,7 +364,7 @@ void luaK_prefix (LexState *ls, int op, expdesc *v) {
549 if (ISJUMP(GET_OPCODE(*previous))) 364 if (ISJUMP(GET_OPCODE(*previous)))
550 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); 365 SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
551 else 366 else
552 luaK_0(fs, OP_NOT, 0); 367 luaK_code0(fs, OP_NOT);
553 /* interchange true and false lists */ 368 /* interchange true and false lists */
554 { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; } 369 { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
555 } 370 }
@@ -564,7 +379,7 @@ void luaK_infix (LexState *ls, int op, expdesc *v) {
564 luaK_goiffalse(fs, v, 1); 379 luaK_goiffalse(fs, v, 1);
565 else 380 else
566 luaK_tostack(ls, v, 1); /* all other binary operators need a value */ 381 luaK_tostack(ls, v, 1); /* all other binary operators need a value */
567} 382}
568 383
569 384
570void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { 385void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
@@ -584,19 +399,210 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
584 else { 399 else {
585 luaK_tostack(ls, v2, 1); /* `v2' must be a value */ 400 luaK_tostack(ls, v2, 1); /* `v2' must be a value */
586 switch (op) { 401 switch (op) {
587 case '+': luaK_add(fs); break; 402 case '+': luaK_code0(fs, OP_ADD); break;
588 case '-': luaK_sub(fs); break; 403 case '-': luaK_code0(fs, OP_SUB); break;
589 case '*': luaK_0(fs, OP_MULT, -1); break; 404 case '*': luaK_code0(fs, OP_MULT); break;
590 case '/': luaK_0(fs, OP_DIV, -1); break; 405 case '/': luaK_code0(fs, OP_DIV); break;
591 case '^': luaK_0(fs, OP_POW, -1); break; 406 case '^': luaK_code0(fs, OP_POW); break;
592 case TK_CONCAT: luaK_conc(fs); break; 407 case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break;
593 case TK_EQ: luaK_eq(fs); break; 408 case TK_EQ: luaK_code0(fs, OP_JMPEQ); break;
594 case TK_NE: luaK_neq(fs); break; 409 case TK_NE: luaK_code0(fs, OP_JMPNE); break;
595 case '>': luaK_S(fs, OP_JMPGT, NO_JUMP, -2); break; 410 case '>': luaK_code0(fs, OP_JMPGT); break;
596 case '<': luaK_S(fs, OP_JMPLT, NO_JUMP, -2); break; 411 case '<': luaK_code0(fs, OP_JMPLT); break;
597 case TK_GE: luaK_S(fs, OP_JMPGE, NO_JUMP, -2); break; 412 case TK_GE: luaK_code0(fs, OP_JMPGE); break;
598 case TK_LE: luaK_S(fs, OP_JMPLE, NO_JUMP, -2); break; 413 case TK_LE: luaK_code0(fs, OP_JMPLE); break;
599 } 414 }
600 } 415 }
601} 416}
602 417
418
419int luaK_code0 (FuncState *fs, OpCode o) {
420 return luaK_code2(fs, o, 0, 0);
421}
422
423
424int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
425 return luaK_code2(fs, o, arg1, 0);
426}
427
428
429
430int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
431 Instruction i = previous_instruction(fs);
432 int delta = 0;
433 enum {iO, iU, iS, iAB, iP} mode; /* instruction format (or iP to optimize) */
434 mode = iP;
435 switch (o) {
436
437 case OP_JMP: delta = 0; mode = iS; break;
438 case OP_CLOSURE: delta = -arg2+1; mode = iAB; break;
439 case OP_SETLINE: mode = iU; break;
440 case OP_CALL: mode = iAB; break;
441 case OP_PUSHINT: delta = 1; mode = iS; break;
442 case OP_SETGLOBAL: delta = -1; mode = iU; break;
443 case OP_SETTABLE: delta = -arg2; mode = iAB; break;
444 case OP_SETLIST: delta = -(arg2+1); mode = iAB; break;
445 case OP_SETMAP: delta = -2*(arg1+1); mode = iU; break;
446
447 case OP_END: case OP_PUSHNILJMP: case OP_NOT:
448 mode = iO; break;
449
450 case OP_PUSHSTRING: case OP_PUSHNUM:
451 case OP_PUSHNEGNUM: case OP_PUSHUPVALUE:
452 case OP_GETGLOBAL: case OP_PUSHSELF: case OP_CREATETABLE:
453 delta = 1; mode = iU; break;
454
455 case OP_JMPLT: case OP_JMPLE: case OP_JMPGT: case OP_JMPGE:
456 delta = -2; arg1 = NO_JUMP; mode = iS; break;
457
458 case OP_MULT: case OP_DIV: case OP_POW:
459 delta = -1; mode = iO; break;
460
461 case OP_RETURN:
462 if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
463 SET_OPCODE(i, OP_TAILCALL);
464 SETARG_B(i, arg1);
465 }
466 else mode = iU;
467 break;
468
469 case OP_PUSHNIL:
470 delta = arg1;
471 switch(GET_OPCODE(i)) {
472 case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); break;
473 default: mode = iU; break;
474 }
475 break;
476
477 case OP_POP:
478 delta = -arg1;
479 switch(GET_OPCODE(i)) {
480 case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); break;
481 case OP_SETLOCAL: SETARG_B(i, GETARG_B(i)+arg1); break;
482 default: mode = iU; break;
483 }
484 break;
485
486 case OP_GETLOCAL:
487 delta = 1;
488 if (i == CREATE_AB(OP_SETLOCAL, arg1, 1))
489 SETARG_B(i, 0);
490 else mode = iU;
491 break;
492
493 case OP_GETTABLE:
494 delta = -1;
495 switch(GET_OPCODE(i)) {
496 case OP_PUSHSTRING: SET_OPCODE(i, OP_GETDOTTED); break; /* `t.x' */
497 case OP_GETLOCAL: SET_OPCODE(i, OP_GETINDEXED); break; /* `t[i]' */
498 default: mode = iO; break;
499 }
500 break;
501
502 case OP_SETLOCAL: {
503 int pc = fs->pc;
504 Instruction *code = fs->f->code;
505 delta = -1;
506 if (pc-1 > fs->lasttarget && /* no jumps in-between instructions? */
507 code[pc-2] == CREATE_U(OP_GETLOCAL, arg1) &&
508 GET_OPCODE(i) == OP_ADDI && abs(GETARG_S(i)) <= MAXARG_sA) {
509 /* `local=local+k' */
510 fs->pc = pc-1;
511 code[pc-2] = CREATE_sAB(OP_INCLOCAL, GETARG_S(i), arg1);
512 luaK_deltastack(fs, delta);
513 return pc-1;
514 }
515 else {
516 arg2 = 1; /* `setlocal' default pops one value */
517 mode = iAB;
518 }
519 break;
520 }
521
522 case OP_ADD:
523 delta = -1;
524 switch(GET_OPCODE(i)) {
525 case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); break; /* `a+k' */
526 default: mode = iO; break;
527 }
528 break;
529
530 case OP_SUB:
531 delta = -1;
532 switch(GET_OPCODE(i)) {
533 case OP_PUSHINT: i = CREATE_S(OP_ADDI, -GETARG_S(i)); break; /* `a-k' */
534 default: mode = iO; break;
535 }
536 break;
537
538 case OP_CONCAT:
539 delta = -arg1+1;
540 switch(GET_OPCODE(i)) {
541 case OP_CONCAT: SETARG_U(i, GETARG_U(i)+1); break; /* `a..b..c' */
542 default: mode = iU; break;
543 }
544 break;
545
546 case OP_MINUS:
547 switch(GET_OPCODE(i)) {
548 case OP_PUSHINT: SETARG_S(i, -GETARG_S(i)); break; /* `-k' */
549 case OP_PUSHNUM: SET_OPCODE(i, OP_PUSHNEGNUM); break; /* `-k' */
550 default: mode = iO; break;
551 }
552 break;
553
554 case OP_JMPNE:
555 delta = -2;
556 if (i == CREATE_U(OP_PUSHNIL, 1)) /* `a~=nil' */
557 i = CREATE_S(OP_JMPT, NO_JUMP);
558 else {
559 arg1 = NO_JUMP;
560 mode = iS;
561 }
562 break;
563
564 case OP_JMPEQ:
565 delta = -2;
566 if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */
567 i = CREATE_0(OP_NOT);
568 delta = -1; /* just undo effect of previous PUSHNIL */
569 }
570 else {
571 arg1 = NO_JUMP;
572 mode = iS;
573 }
574 break;
575
576 case OP_JMPT: case OP_JMPF: case OP_JMPONT: case OP_JMPONF:
577 delta = -1;
578 arg1 = NO_JUMP;
579 switch (GET_OPCODE(i)) {
580 case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); break;
581 default: mode = iS; break;
582 }
583 break;
584
585 case OP_GETDOTTED: case OP_GETINDEXED:
586 case OP_TAILCALL: case OP_INCLOCAL:
587 case OP_ADDI:
588 LUA_INTERNALERROR(L, "instruction used only for optimizations");
589 return 0; /* to avoid warnings */
590
591 }
592 luaK_deltastack(fs, delta);
593 switch (mode) { /* handle instruction formats */
594 case iO: i = CREATE_0(o); break;
595 case iU: i = CREATE_U(o, arg1); break;
596 case iS: i = CREATE_S(o, arg1); break;
597 case iAB: i = CREATE_AB(o, arg1, arg2); break;
598 case iP: { /* optimize: put instruction in place of last one */
599 fs->f->code[fs->pc-1] = i; /* change previous instruction */
600 return fs->pc-1;
601 }
602 }
603 /* actually create the new instruction */
604 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
605 fs->f->code[fs->pc] = i;
606 return fs->pc++;
607}
608
diff --git a/lcode.h b/lcode.h
index 287977d2..60955615 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.9 2000/03/17 13:09:46 roberto Exp roberto $ 2** $Id: lcode.h,v 1.10 2000/04/05 17:51:58 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,12 +17,9 @@
17 17
18 18
19void luaK_error (LexState *ls, const char *msg); 19void luaK_error (LexState *ls, const char *msg);
20int luaK_0(FuncState *fs, OpCode o, int d); 20int luaK_code0 (FuncState *fs, OpCode o);
21int luaK_U(FuncState *fs, OpCode o, int u, int d); 21int luaK_code1 (FuncState *fs, OpCode o, int arg1);
22int luaK_S(FuncState *fs, OpCode o, int s, int d); 22int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
23int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d);
24int luaK_code (FuncState *fs, Instruction i, int delta);
25void luaK_retcode (FuncState *fs, int nlocals, int nexps);
26int luaK_jump (FuncState *fs); 23int luaK_jump (FuncState *fs);
27void luaK_patchlist (FuncState *fs, int list, int target); 24void luaK_patchlist (FuncState *fs, int list, int target);
28void luaK_concat (FuncState *fs, int *l1, int l2); 25void luaK_concat (FuncState *fs, int *l1, int l2);
diff --git a/lparser.c b/lparser.c
index 85799240..f49d6135 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.77 2000/04/06 17:36:52 roberto Exp roberto $ 2** $Id: lparser.c,v 1.78 2000/04/07 13:13:11 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -91,7 +91,7 @@ static void setline (LexState *ls) {
91 FuncState *fs = ls->fs; 91 FuncState *fs = ls->fs;
92 if (ls->L->debug && ls->linenumber != fs->lastsetline) { 92 if (ls->L->debug && ls->linenumber != fs->lastsetline) {
93 checklimit(ls, ls->linenumber, MAXARG_U, "lines in a chunk"); 93 checklimit(ls, ls->linenumber, MAXARG_U, "lines in a chunk");
94 luaK_U(fs, OP_SETLINE, ls->linenumber, 0); 94 luaK_code1(fs, OP_SETLINE, ls->linenumber);
95 fs->lastsetline = ls->linenumber; 95 fs->lastsetline = ls->linenumber;
96 } 96 }
97} 97}
@@ -260,7 +260,7 @@ static void pushupvalue (LexState *ls, TString *n) {
260 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); 260 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
261 if (aux_localname(ls->fs, n) >= 0) 261 if (aux_localname(ls->fs, n) >= 0)
262 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); 262 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
263 luaK_U(fs, OP_PUSHUPVALUE, indexupvalue(ls, n), 1); 263 luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, n));
264} 264}
265 265
266 266
@@ -339,8 +339,7 @@ static void func_onstack (LexState *ls, FuncState *func) {
339 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *, 339 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *,
340 constantEM, MAXARG_A); 340 constantEM, MAXARG_A);
341 f->kproto[f->nkproto++] = func->f; 341 f->kproto[f->nkproto++] = func->f;
342 luaK_deltastack(fs, 1); /* CLOSURE puts one extra element before popping */ 342 luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues);
343 luaK_AB(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues);
344} 343}
345 344
346 345
@@ -373,7 +372,7 @@ static void close_func (LexState *ls) {
373 lua_State *L = ls->L; 372 lua_State *L = ls->L;
374 FuncState *fs = ls->fs; 373 FuncState *fs = ls->fs;
375 Proto *f = fs->f; 374 Proto *f = fs->f;
376 luaK_0(fs, OP_END, 0); 375 luaK_code0(fs, OP_END);
377 luaK_getlabel(fs); /* close eventual list of pending jumps */ 376 luaK_getlabel(fs); /* close eventual list of pending jumps */
378 luaM_reallocvector(L, f->code, fs->pc, Instruction); 377 luaM_reallocvector(L, f->code, fs->pc, Instruction);
379 luaM_reallocvector(L, f->kstr, f->nkstr, TString *); 378 luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
@@ -469,7 +468,7 @@ static void funcargs (LexState *ls, int slf) {
469 break; 468 break;
470 } 469 }
471 fs->stacklevel = slevel; /* call will remove function and arguments */ 470 fs->stacklevel = slevel; /* call will remove function and arguments */
472 luaK_AB(fs, OP_CALL, slevel, MULT_RET, 0); 471 luaK_code2(fs, OP_CALL, slevel, MULT_RET);
473} 472}
474 473
475 474
@@ -496,7 +495,7 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
496 next(ls); 495 next(ls);
497 name = checkname(ls); 496 name = checkname(ls);
498 luaK_tostack(ls, v, 1); /* `v' must be on stack */ 497 luaK_tostack(ls, v, 1); /* `v' must be on stack */
499 luaK_U(ls->fs, OP_PUSHSELF, name, 1); 498 luaK_code1(ls->fs, OP_PUSHSELF, name);
500 funcargs(ls, 1); 499 funcargs(ls, 1);
501 v->k = VEXP; 500 v->k = VEXP;
502 v->u.l.t = v->u.l.f = NO_JUMP; 501 v->u.l.t = v->u.l.f = NO_JUMP;
@@ -569,12 +568,12 @@ static int recfields (LexState *ls) {
569 recfield(ls); 568 recfield(ls);
570 n++; 569 n++;
571 if (++mod_n == RFIELDS_PER_FLUSH) { 570 if (++mod_n == RFIELDS_PER_FLUSH) {
572 luaK_U(fs, OP_SETMAP, RFIELDS_PER_FLUSH-1, -2*RFIELDS_PER_FLUSH); 571 luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH-1);
573 mod_n = 0; 572 mod_n = 0;
574 } 573 }
575 } 574 }
576 if (mod_n) 575 if (mod_n)
577 luaK_U(fs, OP_SETMAP, mod_n-1, -2*mod_n); 576 luaK_code1(fs, OP_SETMAP, mod_n-1);
578 return n; 577 return n;
579} 578}
580 579
@@ -593,13 +592,12 @@ static int listfields (LexState *ls) {
593 checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, 592 checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH,
594 "items in a list initializer"); 593 "items in a list initializer");
595 if (++mod_n == LFIELDS_PER_FLUSH) { 594 if (++mod_n == LFIELDS_PER_FLUSH) {
596 luaK_AB(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1, 595 luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1);
597 -LFIELDS_PER_FLUSH);
598 mod_n = 0; 596 mod_n = 0;
599 } 597 }
600 } 598 }
601 if (mod_n > 0) 599 if (mod_n > 0)
602 luaK_AB(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1, -mod_n); 600 luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1);
603 return n; 601 return n;
604} 602}
605 603
@@ -649,7 +647,7 @@ static void constructor (LexState *ls) {
649 /* constructor -> '{' constructor_part [';' constructor_part] '}' */ 647 /* constructor -> '{' constructor_part [';' constructor_part] '}' */
650 FuncState *fs = ls->fs; 648 FuncState *fs = ls->fs;
651 int line = ls->linenumber; 649 int line = ls->linenumber;
652 int pc = luaK_U(fs, OP_CREATETABLE, 0, 1); 650 int pc = luaK_code1(fs, OP_CREATETABLE, 0);
653 int nelems; 651 int nelems;
654 Constdesc cd; 652 Constdesc cd;
655 check(ls, '{'); 653 check(ls, '{');
@@ -835,7 +833,7 @@ static int assignment (LexState *ls, expdesc *v, int nvars) {
835 if (v->k != VINDEXED) 833 if (v->k != VINDEXED)
836 luaK_storevar(ls, v); 834 luaK_storevar(ls, v);
837 else { /* there may be garbage between table-index and value */ 835 else { /* there may be garbage between table-index and value */
838 luaK_AB(ls->fs, OP_SETTABLE, left+nvars+2, 1, -1); 836 luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1);
839 left += 2; 837 left += 2;
840 } 838 }
841 return left; 839 return left;
@@ -1099,10 +1097,9 @@ static void ret (LexState *ls) {
1099 FuncState *fs = ls->fs; 1097 FuncState *fs = ls->fs;
1100 switch (ls->token) { 1098 switch (ls->token) {
1101 case TK_RETURN: { 1099 case TK_RETURN: {
1102 int nexps; /* number of expressions returned */
1103 setline_and_next(ls); /* skip RETURN */ 1100 setline_and_next(ls); /* skip RETURN */
1104 nexps = explist(ls); 1101 explist(ls);
1105 luaK_retcode(fs, ls->fs->nlocalvar, nexps); 1102 luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar);
1106 fs->stacklevel = fs->nlocalvar; /* removes all temp values */ 1103 fs->stacklevel = fs->nlocalvar; /* removes all temp values */
1107 optional(ls, ';'); 1104 optional(ls, ';');
1108 break; 1105 break;