aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-17 10:09:46 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-17 10:09:46 -0300
commit2c8e28d75a09fb6de3c3b16a64561a0103866cea (patch)
treef7adc9c14f45e3602390f74cc432be2fc6efb37d
parent4fb8e93c36f3a38bd5041650361d820898122532 (diff)
downloadlua-2c8e28d75a09fb6de3c3b16a64561a0103866cea.tar.gz
lua-2c8e28d75a09fb6de3c3b16a64561a0103866cea.tar.bz2
lua-2c8e28d75a09fb6de3c3b16a64561a0103866cea.zip
small changes
-rw-r--r--lcode.c182
-rw-r--r--lcode.h12
2 files changed, 101 insertions, 93 deletions
diff --git a/lcode.c b/lcode.c
index b04632e8..26a606ef 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.12 2000/03/15 20:50:33 roberto Exp roberto $ 2** $Id: lcode.c,v 1.13 2000/03/16 18:03:09 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*/
@@ -22,130 +22,147 @@ void luaK_error (LexState *ls, const char *msg) {
22} 22}
23 23
24 24
25int luaK_code (FuncState *fs, Instruction i, int delta) {
26 luaK_deltastack(fs, delta);
27 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
28 fs->f->code[fs->pc] = i;
29 return fs->pc++;
30}
31
32int luaK_0(FuncState *fs, OpCode o, int d) {
33 return luaK_code(fs, CREATE_0(o), d);
34}
35
36int luaK_U(FuncState *fs, OpCode o, int u, int d) {
37 return luaK_code(fs, CREATE_U(o,u), d);
38}
39
40int luaK_S(FuncState *fs, OpCode o, int s, int d) {
41 return luaK_code(fs, CREATE_S(o,s), d);
42}
43
44int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d) {
45 return luaK_code(fs, CREATE_AB(o,a,b), d);
46}
47
48
25/* 49/*
26** Returns the address of the previous instruction, for optimizations. 50** Returns the the previous instruction, for optimizations.
27** If there is a jump target between this and the current instruction, 51** If there is a jump target between this and the current instruction,
28** returns the address of a dummy instruction to avoid wrong optimizations. 52** returns a dummy instruction to avoid wrong optimizations.
29*/ 53*/
30static Instruction *previous_instruction (FuncState *fs) { 54static Instruction previous_instruction (FuncState *fs) {
31 if (fs->pc > fs->lasttarget) /* no jumps to current position? */ 55 if (fs->pc > fs->lasttarget) /* no jumps to current position? */
32 return &fs->f->code[fs->pc-1]; /* returns previous instruction */ 56 return fs->f->code[fs->pc-1]; /* returns previous instruction */
33 else { 57 else
34 static Instruction dummy = CREATE_0(OP_END); 58 return CREATE_0(OP_END); /* no optimizations after an `END' */
35 return &dummy; /* no optimizations after an `END' */
36 }
37} 59}
38 60
39 61
40static int luaK_primitivecode (FuncState *fs, Instruction i) { 62static Instruction prepare (FuncState *fs, Instruction i, int delta) {
41 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); 63 Instruction previous = previous_instruction(fs);
42 fs->f->code[fs->pc] = i; 64 luaK_code(fs, i, delta);
43 return fs->pc++; 65 return previous;
66}
67
68
69static void setprevious (FuncState *fs, Instruction i) {
70 fs->pc--; /* remove last instruction */
71 fs->f->code[fs->pc-1] = i; /* change previous instruction */
44} 72}
45 73
46 74
47static void luaK_minus (FuncState *fs) { 75static void luaK_minus (FuncState *fs) {
48 Instruction *previous = previous_instruction(fs); 76 Instruction previous = prepare(fs, CREATE_0(OP_MINUS), 0);
49 switch(GET_OPCODE(*previous)) { 77 switch(GET_OPCODE(previous)) {
50 case OP_PUSHINT: SETARG_S(*previous, -GETARG_S(*previous)); return; 78 case OP_PUSHINT: SETARG_S(previous, -GETARG_S(previous)); break;
51 case OP_PUSHNUM: SET_OPCODE(*previous, OP_PUSHNEGNUM); return; 79 case OP_PUSHNUM: SET_OPCODE(previous, OP_PUSHNEGNUM); break;
52 case OP_PUSHNEGNUM: SET_OPCODE(*previous, OP_PUSHNUM); return; 80 case OP_PUSHNEGNUM: SET_OPCODE(previous, OP_PUSHNUM); break;
53 default: luaK_primitivecode(fs, CREATE_0(OP_MINUS)); 81 default: return;
54 } 82 }
83 setprevious(fs, previous);
55} 84}
56 85
57 86
58static void luaK_gettable (FuncState *fs) { 87static void luaK_gettable (FuncState *fs) {
59 Instruction *previous = previous_instruction(fs); 88 Instruction previous = prepare(fs, CREATE_0(OP_GETTABLE), -1);
60 luaK_deltastack(fs, -1); 89 switch(GET_OPCODE(previous)) {
61 switch(GET_OPCODE(*previous)) { 90 case OP_PUSHSTRING: SET_OPCODE(previous, OP_GETDOTTED); break;
62 case OP_PUSHSTRING: SET_OPCODE(*previous, OP_GETDOTTED); break; 91 default: return;
63 default: luaK_primitivecode(fs, CREATE_0(OP_GETTABLE));
64 } 92 }
93 setprevious(fs, previous);
65} 94}
66 95
67 96
68static void luaK_add (FuncState *fs) { 97static void luaK_add (FuncState *fs) {
69 Instruction *previous = previous_instruction(fs); 98 Instruction previous = prepare(fs, CREATE_0(OP_ADD), -1);
70 luaK_deltastack(fs, -1); 99 switch(GET_OPCODE(previous)) {
71 switch(GET_OPCODE(*previous)) { 100 case OP_PUSHINT: SET_OPCODE(previous, OP_ADDI); break;
72 case OP_PUSHINT: SET_OPCODE(*previous, OP_ADDI); break; 101 default: return;
73 default: luaK_primitivecode(fs, CREATE_0(OP_ADD));
74 } 102 }
103 setprevious(fs, previous);
75} 104}
76 105
77 106
78static void luaK_sub (FuncState *fs) { 107static void luaK_sub (FuncState *fs) {
79 Instruction *previous = previous_instruction(fs); 108 Instruction previous = prepare(fs, CREATE_0(OP_SUB), -1);
80 luaK_deltastack(fs, -1); 109 switch(GET_OPCODE(previous)) {
81 switch(GET_OPCODE(*previous)) {
82 case OP_PUSHINT: 110 case OP_PUSHINT:
83 SET_OPCODE(*previous, OP_ADDI); 111 SET_OPCODE(previous, OP_ADDI);
84 SETARG_S(*previous, -GETARG_S(*previous)); 112 SETARG_S(previous, -GETARG_S(previous));
85 break; 113 break;
86 default: luaK_primitivecode(fs, CREATE_0(OP_SUB)); 114 default: return;
87 } 115 }
116 setprevious(fs, previous);
88} 117}
89 118
90 119
91static void luaK_conc (FuncState *fs) { 120static void luaK_conc (FuncState *fs) {
92 Instruction *previous = previous_instruction(fs); 121 Instruction previous = prepare(fs, CREATE_U(OP_CONC, 2), -1);
93 luaK_deltastack(fs, -1); 122 switch(GET_OPCODE(previous)) {
94 switch(GET_OPCODE(*previous)) { 123 case OP_CONC: SETARG_U(previous, GETARG_U(previous)+1); break;
95 case OP_CONC: SETARG_U(*previous, GETARG_U(*previous)+1); break; 124 default: return;
96 default: luaK_primitivecode(fs, CREATE_U(OP_CONC, 2));
97 } 125 }
126 setprevious(fs, previous);
98} 127}
99 128
100 129
101static void luaK_eq (FuncState *fs) { 130static void luaK_eq (FuncState *fs) {
102 Instruction *previous = previous_instruction(fs); 131 Instruction previous = prepare(fs, CREATE_S(OP_IFEQJMP, 0), -2);
103 if (*previous == CREATE_U(OP_PUSHNIL, 1)) { 132 if (previous == CREATE_U(OP_PUSHNIL, 1)) {
104 *previous = CREATE_0(OP_NOT); 133 setprevious(fs, CREATE_0(OP_NOT));
105 luaK_deltastack(fs, -1); /* undo effect of PUSHNIL */ 134 luaK_deltastack(fs, 1); /* undo delta from `prepare' */
106 } 135 }
107 else
108 luaK_S(fs, OP_IFEQJMP, 0, -2);
109} 136}
110 137
111 138
112static void luaK_neq (FuncState *fs) { 139static void luaK_neq (FuncState *fs) {
113 Instruction *previous = previous_instruction(fs); 140 Instruction previous = prepare(fs, CREATE_S(OP_IFNEQJMP, 0), -2);
114 if (*previous == CREATE_U(OP_PUSHNIL, 1)) { 141 if (previous == CREATE_U(OP_PUSHNIL, 1)) {
115 fs->pc--; /* remove PUSHNIL */ 142 fs->pc -= 2; /* remove PUSHNIL and IFNEQJMP */
116 luaK_deltastack(fs, -1); /* undo effect of PUSHNIL */ 143 luaK_deltastack(fs, 1); /* undo delta from `prepare' */
117 luaK_getlabel(fs); /* previous instruction could be a (closed) call */
118 } 144 }
119 else
120 luaK_S(fs, OP_IFNEQJMP, 0, -2);
121} 145}
122 146
123 147
124void luaK_retcode (FuncState *fs, int nlocals, int nexps) { 148void luaK_retcode (FuncState *fs, int nlocals, int nexps) {
125 Instruction *previous = previous_instruction(fs); 149 Instruction previous = prepare(fs, CREATE_U(OP_RETURN, nlocals), 0);
126 if (nexps > 0 && GET_OPCODE(*previous) == OP_CALL) { 150 if (nexps > 0 && GET_OPCODE(previous) == OP_CALL) {
127 LUA_ASSERT(fs->L, GETARG_B(*previous) == MULT_RET, "call should be open"); 151 LUA_ASSERT(fs->L, GETARG_B(previous) == MULT_RET, "call should be open");
128 SET_OPCODE(*previous, OP_TAILCALL); 152 SET_OPCODE(previous, OP_TAILCALL);
129 SETARG_B(*previous, nlocals); 153 SETARG_B(previous, nlocals);
154 setprevious(fs, previous);
130 } 155 }
131 else
132 luaK_primitivecode(fs, CREATE_U(OP_RETURN, nlocals));
133} 156}
134 157
135 158
136static void luaK_pushnil (FuncState *fs, int n) { 159static void luaK_pushnil (FuncState *fs, int n) {
137 Instruction *previous = previous_instruction(fs); 160 Instruction previous = prepare(fs, CREATE_U(OP_PUSHNIL, n), n);
138 luaK_deltastack(fs, n); 161 switch(GET_OPCODE(previous)) {
139 switch(GET_OPCODE(*previous)) { 162 case OP_PUSHNIL: SETARG_U(previous, GETARG_U(previous)+n); break;
140 case OP_PUSHNIL: SETARG_U(*previous, GETARG_U(*previous)+n); break; 163 default: return;
141 default: luaK_primitivecode(fs, CREATE_U(OP_PUSHNIL, n));
142 } 164 }
143} 165 setprevious(fs, previous);
144
145
146int luaK_code (FuncState *fs, Instruction i, int delta) {
147 luaK_deltastack(fs, delta);
148 return luaK_primitivecode(fs, i);
149} 166}
150 167
151 168
@@ -232,21 +249,17 @@ void luaK_adjuststack (FuncState *fs, int n) {
232 249
233 250
234int luaK_lastisopen (FuncState *fs) { 251int luaK_lastisopen (FuncState *fs) {
235 /* check whether last instruction is an (open) function call */ 252 /* check whether last instruction is an open function call */
236 Instruction *i = previous_instruction(fs); 253 Instruction i = previous_instruction(fs);
237 if (GET_OPCODE(*i) == OP_CALL) { 254 if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
238 LUA_ASSERT(fs->L, GETARG_B(*i) == MULT_RET, "call should be open");
239 return 1; 255 return 1;
240 }
241 else return 0; 256 else return 0;
242} 257}
243 258
244 259
245void luaK_setcallreturns (FuncState *fs, int nresults) { 260void luaK_setcallreturns (FuncState *fs, int nresults) {
246 Instruction *i = previous_instruction(fs); 261 if (luaK_lastisopen(fs)) { /* expression is an open function call? */
247 if (GET_OPCODE(*i) == OP_CALL) { /* expression is a function call? */ 262 SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */
248 LUA_ASSERT(fs->L, GETARG_B(*i) == MULT_RET, "call should be open");
249 SETARG_B(*i, nresults); /* set nresults */
250 luaK_deltastack(fs, nresults); /* push results */ 263 luaK_deltastack(fs, nresults); /* push results */
251 } 264 }
252} 265}
@@ -323,12 +336,9 @@ static OpCode invertjump (OpCode op) {
323 336
324 337
325static void luaK_jump (FuncState *fs, OpCode jump) { 338static void luaK_jump (FuncState *fs, OpCode jump) {
326 Instruction *previous = previous_instruction(fs); 339 Instruction previous = prepare(fs, CREATE_S(jump, 0), -1);
327 luaK_deltastack(fs, -1); 340 if (previous == CREATE_0(OP_NOT))
328 if (*previous == CREATE_0(OP_NOT)) 341 setprevious(fs, CREATE_S(invertjump(jump), 0));
329 *previous = CREATE_S(invertjump(jump), 0);
330 else
331 luaK_primitivecode(fs, CREATE_S(jump, 0));
332} 342}
333 343
334 344
diff --git a/lcode.h b/lcode.h
index 61c574cc..ce3901db 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.7 2000/03/13 20:37:16 roberto Exp roberto $ 2** $Id: lcode.h,v 1.8 2000/03/15 20:50:33 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*/
@@ -13,13 +13,11 @@
13#include "lparser.h" 13#include "lparser.h"
14 14
15 15
16#define luaK_0(ls,o,d) luaK_code(ls, CREATE_0(o), d)
17#define luaK_U(ls,o,u,d) luaK_code(ls, CREATE_U(o,u), d)
18#define luaK_S(ls,o,s,d) luaK_code(ls, CREATE_S(o,s), d)
19#define luaK_AB(ls,o,a,b,d) luaK_code(ls, CREATE_AB(o,a,b), d)
20
21
22void luaK_error (LexState *ls, const char *msg); 16void luaK_error (LexState *ls, const char *msg);
17int luaK_0(FuncState *fs, OpCode o, int d);
18int luaK_U(FuncState *fs, OpCode o, int u, int d);
19int luaK_S(FuncState *fs, OpCode o, int s, int d);
20int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d);
23int luaK_code (FuncState *fs, Instruction i, int delta); 21int luaK_code (FuncState *fs, Instruction i, int delta);
24void luaK_retcode (FuncState *fs, int nlocals, int nexps); 22void luaK_retcode (FuncState *fs, int nlocals, int nexps);
25void luaK_fixjump (FuncState *fs, int pc, int dest); 23void luaK_fixjump (FuncState *fs, int pc, int dest);