diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-12-15 14:17:20 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-12-15 14:17:20 -0200 |
commit | 45e533599f08d849951b49bcab0be4fd735a966d (patch) | |
tree | b8e3b175989f694391dd3da4191894f5df1e7d75 /ldo.c | |
parent | 94144a7821c0fa412d5d228ab5197a8ebaaa3c25 (diff) | |
download | lua-45e533599f08d849951b49bcab0be4fd735a966d.tar.gz lua-45e533599f08d849951b49bcab0be4fd735a966d.tar.bz2 lua-45e533599f08d849951b49bcab0be4fd735a966d.zip |
optimization: closures without upvalues don't need to be closures
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 68 |
1 files changed, 37 insertions, 31 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.13 1997/11/27 18:25:14 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.14 1997/12/09 13:35:19 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -44,13 +44,6 @@ static void stderrorim (void) | |||
44 | } | 44 | } |
45 | 45 | ||
46 | 46 | ||
47 | static void initCfunc (TObject *o, lua_CFunction f) | ||
48 | { | ||
49 | ttype(o) = LUA_T_CPROTO; | ||
50 | fvalue(o) = f; | ||
51 | luaF_simpleclosure(o); | ||
52 | } | ||
53 | |||
54 | 47 | ||
55 | #define STACK_UNIT 128 | 48 | #define STACK_UNIT 128 |
56 | 49 | ||
@@ -60,7 +53,8 @@ void luaD_init (void) | |||
60 | L->stack.stack = luaM_newvector(STACK_UNIT, TObject); | 53 | L->stack.stack = luaM_newvector(STACK_UNIT, TObject); |
61 | L->stack.top = L->stack.stack; | 54 | L->stack.top = L->stack.stack; |
62 | L->stack.last = L->stack.stack+(STACK_UNIT-1); | 55 | L->stack.last = L->stack.stack+(STACK_UNIT-1); |
63 | initCfunc(&L->errorim, stderrorim); | 56 | ttype(&L->errorim) = LUA_T_CPROTO; |
57 | fvalue(&L->errorim) = stderrorim; | ||
64 | } | 58 | } |
65 | 59 | ||
66 | 60 | ||
@@ -122,7 +116,7 @@ void luaD_lineHook (int line) | |||
122 | } | 116 | } |
123 | 117 | ||
124 | 118 | ||
125 | void luaD_callHook (StkId base, lua_Type type, int isreturn) | 119 | void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) |
126 | { | 120 | { |
127 | struct C_Lua_Stack oldCLS = L->Cstack; | 121 | struct C_Lua_Stack oldCLS = L->Cstack; |
128 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; | 122 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; |
@@ -131,9 +125,8 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) | |||
131 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); | 125 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); |
132 | else { | 126 | else { |
133 | TObject *f = L->stack.stack+base-1; | 127 | TObject *f = L->stack.stack+base-1; |
134 | if (type == LUA_T_PROTO) | 128 | if (tf) |
135 | (*lua_callhook)(Ref(f), tfvalue(protovalue(f))->fileName->str, | 129 | (*lua_callhook)(Ref(f), tf->fileName->str, tf->lineDefined); |
136 | tfvalue(protovalue(f))->lineDefined); | ||
137 | else | 130 | else |
138 | (*lua_callhook)(Ref(f), "(C)", -1); | 131 | (*lua_callhook)(Ref(f), "(C)", -1); |
139 | } | 132 | } |
@@ -147,13 +140,13 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) | |||
147 | ** Cstack.num is the number of arguments; Cstack.lua2C points to the | 140 | ** Cstack.num is the number of arguments; Cstack.lua2C points to the |
148 | ** first argument. Returns an index to the first result from C. | 141 | ** first argument. Returns an index to the first result from C. |
149 | */ | 142 | */ |
150 | static StkId callC (struct Closure *cl, StkId base) | 143 | static StkId callC (struct Closure *cl, lua_CFunction f, StkId base) |
151 | { | 144 | { |
152 | struct C_Lua_Stack *CS = &L->Cstack; | 145 | struct C_Lua_Stack *CS = &L->Cstack; |
153 | struct C_Lua_Stack oldCLS = *CS; | 146 | struct C_Lua_Stack oldCLS = *CS; |
154 | StkId firstResult; | 147 | StkId firstResult; |
155 | int numarg = (L->stack.top-L->stack.stack) - base; | 148 | int numarg = (L->stack.top-L->stack.stack) - base; |
156 | if (cl->nelems > 0) { /* are there upvalues? */ | 149 | if (cl) { /* are there upvalues? */ |
157 | int i; | 150 | int i; |
158 | luaD_checkstack(cl->nelems); | 151 | luaD_checkstack(cl->nelems); |
159 | for (i=1; i<=numarg; i++) /* open space */ | 152 | for (i=1; i<=numarg; i++) /* open space */ |
@@ -167,10 +160,10 @@ static StkId callC (struct Closure *cl, StkId base) | |||
167 | CS->lua2C = base; | 160 | CS->lua2C = base; |
168 | CS->base = base+numarg; /* == top-stack */ | 161 | CS->base = base+numarg; /* == top-stack */ |
169 | if (lua_callhook) | 162 | if (lua_callhook) |
170 | luaD_callHook(base, LUA_T_CPROTO, 0); | 163 | luaD_callHook(base, NULL, 0); |
171 | (*(fvalue(cl->consts)))(); /* do the actual call */ | 164 | (*f)(); /* do the actual call */ |
172 | if (lua_callhook) /* func may have changed lua_callhook */ | 165 | if (lua_callhook) /* func may have changed lua_callhook */ |
173 | luaD_callHook(base, LUA_T_CPROTO, 1); | 166 | luaD_callHook(base, NULL, 1); |
174 | firstResult = CS->base; | 167 | firstResult = CS->base; |
175 | *CS = oldCLS; | 168 | *CS = oldCLS; |
176 | return firstResult; | 169 | return firstResult; |
@@ -196,19 +189,32 @@ void luaD_call (StkId base, int nResults) | |||
196 | StkId firstResult; | 189 | StkId firstResult; |
197 | TObject *func = L->stack.stack+base-1; | 190 | TObject *func = L->stack.stack+base-1; |
198 | int i; | 191 | int i; |
199 | if (ttype(func) == LUA_T_FUNCTION) { | 192 | switch (ttype(func)) { |
200 | TObject *proto = protovalue(func); | 193 | case LUA_T_CPROTO: |
201 | ttype(func) = LUA_T_MARK; | 194 | ttype(func) = LUA_T_CMARK; |
202 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? callC(clvalue(func), base) | 195 | firstResult = callC(NULL, fvalue(func), base); |
203 | : luaV_execute(func->value.cl, base); | 196 | break; |
204 | } | 197 | case LUA_T_PROTO: |
205 | else { /* func is not a function */ | 198 | ttype(func) = LUA_T_PMARK; |
206 | /* Check the tag method for invalid functions */ | 199 | firstResult = luaV_execute(NULL, tfvalue(func), base); |
207 | TObject *im = luaT_getimbyObj(func, IM_FUNCTION); | 200 | break; |
208 | if (ttype(im) == LUA_T_NIL) | 201 | case LUA_T_CLOSURE: { |
209 | lua_error("call expression not a function"); | 202 | Closure *c = clvalue(func); |
210 | luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults); | 203 | TObject *proto = &(c->consts[0]); |
211 | return; | 204 | ttype(func) = LUA_T_CLMARK; |
205 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? | ||
206 | callC(c, fvalue(proto), base) : | ||
207 | luaV_execute(c, tfvalue(proto), base); | ||
208 | break; | ||
209 | } | ||
210 | default: { /* func is not a function */ | ||
211 | /* Check the tag method for invalid functions */ | ||
212 | TObject *im = luaT_getimbyObj(func, IM_FUNCTION); | ||
213 | if (ttype(im) == LUA_T_NIL) | ||
214 | lua_error("call expression not a function"); | ||
215 | luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults); | ||
216 | return; | ||
217 | } | ||
212 | } | 218 | } |
213 | /* adjust the number of results */ | 219 | /* adjust the number of results */ |
214 | if (nResults != MULT_RET) | 220 | if (nResults != MULT_RET) |