summaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-15 14:17:20 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-15 14:17:20 -0200
commit45e533599f08d849951b49bcab0be4fd735a966d (patch)
treeb8e3b175989f694391dd3da4191894f5df1e7d75 /ldo.c
parent94144a7821c0fa412d5d228ab5197a8ebaaa3c25 (diff)
downloadlua-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.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/ldo.c b/ldo.c
index f813922e..5362a0fb 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
47static 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
125void luaD_callHook (StkId base, lua_Type type, int isreturn) 119void 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*/
150static StkId callC (struct Closure *cl, StkId base) 143static 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)