aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-03 15:53:17 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-03 15:53:17 -0300
commitd1ea38580ae35a3a34e7122c41682af7f9901030 (patch)
treece7fa1568be9eb757805966b77ea1eac2bc604f6 /lcode.c
parent3c9d999424520c809e05bee11d81788b488434f6 (diff)
downloadlua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.gz
lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.bz2
lua-d1ea38580ae35a3a34e7122c41682af7f9901030.zip
change of code generation design (independent functions for each opcode)
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c223
1 files changed, 100 insertions, 123 deletions
diff --git a/lcode.c b/lcode.c
index cf9aee47..2d9c2285 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ 2** $Id: lcode.c,v 1.3 2000/03/03 14:58:26 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*/
@@ -20,12 +20,10 @@ void luaK_error (LexState *ls, const char *msg) {
20} 20}
21 21
22 22
23static Instruction *last_i (FuncState *fs) { 23static Instruction *last_i (LexState *ls, expdesc *v) {
24 static Instruction dummy = SET_OPCODE(0, ENDCODE); 24 FuncState *fs = ls->fs;
25 if (fs->last_pc < 0) 25 int last_pc = (v->info != NOJUMPS) ? v->info : fs->pc-1;
26 return &dummy; 26 return &fs->f->code[last_pc];
27 else
28 return &fs->f->code[fs->last_pc];
29} 27}
30 28
31 29
@@ -37,58 +35,64 @@ int luaK_primitivecode (LexState *ls, Instruction i) {
37} 35}
38 36
39 37
38static void luaK_minus (LexState *ls, expdesc *v) {
39 Instruction *last = last_i(ls, v);
40 switch(GET_OPCODE(*last)) {
41 case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); return;
42 case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); return;
43 case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); return;
44 default: luaK_primitivecode(ls, CREATE_0(MINUSOP));
45 }
46}
40 47
41int luaK_code (LexState *ls, Instruction i) {
42 FuncState *fs = ls->fs;
43 Instruction *last = last_i(fs);
44 switch (GET_OPCODE(i)) {
45
46 case MINUSOP:
47 switch(GET_OPCODE(*last)) {
48 case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break;
49 case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break;
50 case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break;
51 default: fs->last_pc = luaK_primitivecode(ls, i);
52 }
53 break;
54 48
55 case GETTABLE: 49static void luaK_gettable (LexState *ls, expdesc *v) {
56 switch(GET_OPCODE(*last)) { 50 Instruction *last = last_i(ls, v);
57 case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; 51 luaK_deltastack(ls, -1);
58 default: fs->last_pc = luaK_primitivecode(ls, i); 52 switch(GET_OPCODE(*last)) {
59 } 53 case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
60 break; 54 default: luaK_primitivecode(ls, CREATE_0(GETTABLE));
55 }
56}
61 57
62 case RETCODE:
63 switch(GET_OPCODE(*last)) {
64 case CALL:
65 *last = SET_OPCODE(*last, TAILCALL);
66 *last = SETARG_B(*last, GETARG_U(i));
67 break;
68 default: fs->last_pc = luaK_primitivecode(ls, i);
69 }
70 break;
71 58
72 case ADDOP: 59static void luaK_add (LexState *ls, expdesc *v) {
73 switch(GET_OPCODE(*last)) { 60 Instruction *last = last_i(ls, v);
74 case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; 61 luaK_deltastack(ls, -1);
75 default: fs->last_pc = luaK_primitivecode(ls, i); 62 switch(GET_OPCODE(*last)) {
76 } 63 case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
77 break; 64 default: luaK_primitivecode(ls, CREATE_0(ADDOP));
65 }
66}
67
78 68
79 case SUBOP: 69static void luaK_sub (LexState *ls, expdesc *v) {
80 switch(GET_OPCODE(*last)) { 70 Instruction *last = last_i(ls, v);
81 case PUSHINT: 71 luaK_deltastack(ls, -1);
82 *last = SET_OPCODE(*last, ADDI); 72 switch(GET_OPCODE(*last)) {
83 *last = SETARG_S(*last, -GETARG_S(*last)); 73 case PUSHINT:
84 break; 74 *last = SET_OPCODE(*last, ADDI);
85 default: fs->last_pc = luaK_primitivecode(ls, i); 75 *last = SETARG_S(*last, -GETARG_S(*last));
86 }
87 break; 76 break;
77 default: luaK_primitivecode(ls, CREATE_0(SUBOP));
78 }
79}
88 80
89 default: fs->last_pc = luaK_primitivecode(ls, i); 81
82void luaK_retcode (LexState *ls, int nlocals, listdesc *e) {
83 if (e->n > 0 && luaK_iscall(ls, e->info)) {
84 Instruction *last = &ls->fs->f->code[ls->fs->pc-1];
85 *last = SET_OPCODE(*last, TAILCALL);
86 *last = SETARG_B(*last, nlocals);
90 } 87 }
91 return fs->last_pc; 88 else
89 luaK_U(ls, RETCODE, nlocals, 0);
90}
91
92
93int luaK_code (LexState *ls, Instruction i, int delta) {
94 luaK_deltastack(ls, delta);
95 return luaK_primitivecode(ls, i);
92} 96}
93 97
94 98
@@ -97,7 +101,6 @@ void luaK_fixjump (LexState *ls, int pc, int dest) {
97 Instruction *jmp = &fs->f->code[pc]; 101 Instruction *jmp = &fs->f->code[pc];
98 /* jump is relative to position following jump instruction */ 102 /* jump is relative to position following jump instruction */
99 *jmp = SETARG_S(*jmp, dest-(pc+1)); 103 *jmp = SETARG_S(*jmp, dest-(pc+1));
100 fs->last_pc = pc;
101} 104}
102 105
103 106
@@ -112,38 +115,8 @@ void luaK_deltastack (LexState *ls, int delta) {
112} 115}
113 116
114 117
115static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { 118void luaK_kstr (LexState *ls, int c) {
116 luaK_deltastack(ls, delta); 119 luaK_U(ls, PUSHSTRING, c, 1);
117 return luaK_code(ls, SET_OPCODE(i, op));
118}
119
120
121int luaK_0 (LexState *ls, OpCode op, int delta) {
122 return aux_code(ls, op, 0, delta);
123}
124
125
126int luaK_U (LexState *ls, OpCode op, int u, int delta) {
127 Instruction i = SETARG_U(0, u);
128 return aux_code(ls, op, i, delta);
129}
130
131
132int luaK_S (LexState *ls, OpCode op, int s, int delta) {
133 Instruction i = SETARG_S(0, s);
134 return aux_code(ls, op, i, delta);
135}
136
137
138int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) {
139 Instruction i = SETARG_A(0, a);
140 i = SETARG_B(i, b);
141 return aux_code(ls, op, i, delta);
142}
143
144
145int luaK_kstr (LexState *ls, int c) {
146 return luaK_U(ls, PUSHSTRING, c, 1);
147} 120}
148 121
149 122
@@ -166,37 +139,40 @@ static int real_constant (LexState *ls, real r) {
166} 139}
167 140
168 141
169int luaK_number (LexState *ls, real f) { 142void luaK_number (LexState *ls, real f) {
170 if (f <= (real)MAXARG_S && (int)f == f) 143 if (f <= (real)MAXARG_S && (int)f == f)
171 return luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ 144 luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */
172 else 145 else
173 return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); 146 luaK_U(ls, PUSHNUM, real_constant(ls, f), 1);
174} 147}
175 148
176 149
177int luaK_adjuststack (LexState *ls, int n) { 150void luaK_adjuststack (LexState *ls, int n) {
178 if (n > 0) 151 if (n > 0)
179 return luaK_U(ls, POP, n, -n); 152 luaK_U(ls, POP, n, -n);
180 else if (n < 0) 153 else if (n < 0)
181 return luaK_U(ls, PUSHNIL, (-n)-1, -n); 154 luaK_U(ls, PUSHNIL, (-n)-1, -n);
182 else return 0;
183} 155}
184 156
185 157
186int luaK_iscall (LexState *ls, int pc) { 158int luaK_iscall (LexState *ls, int hasjumps) {
187 return (GET_OPCODE(ls->fs->f->code[pc]) == CALL); 159 if (hasjumps) return 0; /* a call cannot have internal jumps */
160 else /* check whether last instruction is a function call */
161 return (GET_OPCODE(ls->fs->f->code[ls->fs->pc-1]) == CALL);
188} 162}
189 163
190 164
191void luaK_setcallreturns (LexState *ls, int pc, int nresults) { 165void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults) {
192 if (luaK_iscall(ls, pc)) { /* expression is a function call? */ 166 if (!hasjumps) { /* if `hasjumps' cannot be a function call */
193 Instruction *i = &ls->fs->f->code[pc]; 167 Instruction *i = &ls->fs->f->code[ls->fs->pc-1];
194 int old_nresults = GETARG_B(*i); 168 if (GET_OPCODE(*i) == CALL) { /* expression is a function call? */
195 if (old_nresults != MULT_RET) 169 int old_nresults = GETARG_B(*i);
196 luaK_deltastack(ls, -old_nresults); /* pop old nresults */ 170 if (old_nresults != MULT_RET)
197 *i = SETARG_B(*i, nresults); /* set nresults */ 171 luaK_deltastack(ls, -old_nresults); /* pop old nresults */
198 if (nresults != MULT_RET) 172 *i = SETARG_B(*i, nresults); /* set nresults */
199 luaK_deltastack(ls, nresults); /* push results */ 173 if (nresults != MULT_RET)
174 luaK_deltastack(ls, nresults); /* push results */
175 }
200 } 176 }
201} 177}
202 178
@@ -209,20 +185,21 @@ static void assertglobal (LexState *ls, int index) {
209void luaK_2stack (LexState *ls, expdesc *var) { 185void luaK_2stack (LexState *ls, expdesc *var) {
210 switch (var->k) { 186 switch (var->k) {
211 case VLOCAL: 187 case VLOCAL:
212 var->info = luaK_U(ls, PUSHLOCAL, var->info, 1); 188 luaK_U(ls, PUSHLOCAL, var->info, 1);
213 break; 189 break;
214 case VGLOBAL: 190 case VGLOBAL:
191 luaK_U(ls, GETGLOBAL, var->info, 1);
215 assertglobal(ls, var->info); /* make sure that there is a global */ 192 assertglobal(ls, var->info); /* make sure that there is a global */
216 var->info = luaK_U(ls, GETGLOBAL, var->info, 1);
217 break; 193 break;
218 case VINDEXED: 194 case VINDEXED:
219 var->info = luaK_0(ls, GETTABLE, -1); 195 luaK_gettable(ls, var);
220 break; 196 break;
221 case VEXP: 197 case VEXP:
222 luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ 198 luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */
223 break; 199 return; /* does not change var->info */
224 } 200 }
225 var->k = VEXP; 201 var->k = VEXP;
202 var->info = NOJUMPS;
226} 203}
227 204
228 205
@@ -246,10 +223,9 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
246 223
247void luaK_prefix (LexState *ls, int op, expdesc *v) { 224void luaK_prefix (LexState *ls, int op, expdesc *v) {
248 luaK_2stack(ls, v); 225 luaK_2stack(ls, v);
249 if (op == '-') 226 if (op == '-') luaK_minus(ls, v);
250 v->info = luaK_0(ls, MINUSOP, 0); 227 else luaK_0(ls, NOTOP, 0);
251 else 228 v->info = NOJUMPS;
252 v->info = luaK_0(ls, NOTOP, 0);
253} 229}
254 230
255 231
@@ -267,19 +243,20 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
267 switch (op) { 243 switch (op) {
268 case AND: case OR: 244 case AND: case OR:
269 luaK_fixjump(ls, v1->info, ls->fs->pc); 245 luaK_fixjump(ls, v1->info, ls->fs->pc);
270 break; 246 return; /* keep v1->info != NOJUMPS */
271 case '+': v1->info = luaK_0(ls, ADDOP, -1); break; 247 case '+': luaK_add(ls, v2); break;
272 case '-': v1->info = luaK_0(ls, SUBOP, -1); break; 248 case '-': luaK_sub(ls, v2); break;
273 case '*': v1->info = luaK_0(ls, MULTOP, -1); break; 249 case '*': luaK_0(ls, MULTOP, -1); break;
274 case '/': v1->info = luaK_0(ls, DIVOP, -1); break; 250 case '/': luaK_0(ls, DIVOP, -1); break;
275 case '^': v1->info = luaK_0(ls, POWOP, -1); break; 251 case '^': luaK_0(ls, POWOP, -1); break;
276 case CONC: v1->info = luaK_0(ls, CONCOP, -1); break; 252 case CONC: luaK_0(ls, CONCOP, -1); break;
277 case EQ: v1->info = luaK_0(ls, EQOP, -1); break; 253 case EQ: luaK_0(ls, EQOP, -1); break;
278 case NE: v1->info = luaK_0(ls, NEQOP, -1); break; 254 case NE: luaK_0(ls, NEQOP, -1); break;
279 case '>': v1->info = luaK_0(ls, GTOP, -1); break; 255 case '>': luaK_0(ls, GTOP, -1); break;
280 case '<': v1->info = luaK_0(ls, LTOP, -1); break; 256 case '<': luaK_0(ls, LTOP, -1); break;
281 case GE: v1->info = luaK_0(ls, GEOP, -1); break; 257 case GE: luaK_0(ls, GEOP, -1); break;
282 case LE: v1->info = luaK_0(ls, LEOP, -1); break; 258 case LE: luaK_0(ls, LEOP, -1); break;
283 } 259 }
260 v1->info = NOJUMPS;
284} 261}
285 262