aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-16 11:26:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-16 11:26:56 -0300
commite5146fb01f1ccb40c2663e745feffbf642cbf862 (patch)
tree7015808b9b2bcd6c45f2042074459ce766fa0bd8 /ldo.c
parentce6b930464edd621ec95ddab2ce9ccb7ddae605a (diff)
downloadlua-e5146fb01f1ccb40c2663e745feffbf642cbf862.tar.gz
lua-e5146fb01f1ccb40c2663e745feffbf642cbf862.tar.bz2
lua-e5146fb01f1ccb40c2663e745feffbf642cbf862.zip
CallInfo has different fields for C functions and Lua functions
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c63
1 files changed, 32 insertions, 31 deletions
diff --git a/ldo.c b/ldo.c
index e2511bde..55f7958f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.186 2002/07/08 18:21:33 roberto Exp roberto $ 2** $Id: ldo.c,v 1.187 2002/07/09 18:19: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*/
@@ -60,10 +60,10 @@ static void correctstack (lua_State *L, TObject *oldstack) {
60 for (ci = L->base_ci; ci <= L->ci; ci++) { 60 for (ci = L->base_ci; ci <= L->ci; ci++) {
61 ci->base = (ci->base - oldstack) + L->stack; 61 ci->base = (ci->base - oldstack) + L->stack;
62 ci->top = (ci->top - oldstack) + L->stack; 62 ci->top = (ci->top - oldstack) + L->stack;
63 if (ci->pc) { /* entry is of an active Lua function? */ 63 if (isLua(ci) && /* is a Lua function... */
64 if (ci->pc != (ci-1)->pc) 64 !(isLua(ci-1) && /* and next is not a Lua function... */
65 *ci->pb = (*ci->pb - oldstack) + L->stack; 65 ci->u.l.pc == (ci-1)->u.l.pc)) /* sharing the same C frame? */
66 } 66 *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */
67 } 67 }
68} 68}
69 69
@@ -134,10 +134,6 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
134 ar.event = event; 134 ar.event = event;
135 ar.currentline = line; 135 ar.currentline = line;
136 ar.i_ci = L->ci - L->base_ci; 136 ar.i_ci = L->ci - L->base_ci;
137 if (event <= LUA_HOOKRET) { /* `call' or `return' event? */
138 L->ci->pc = NULL; /* function is not active */
139 L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
140 }
141 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 137 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
142 L->ci->top = L->top + LUA_MINSTACK; 138 L->ci->top = L->top + LUA_MINSTACK;
143 setallowhook(L, 0); /* cannot call hooks inside a hook */ 139 setallowhook(L, 0); /* cannot call hooks inside a hook */
@@ -152,11 +148,11 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
152} 148}
153 149
154 150
155static void adjust_varargs (lua_State *L, int nfixargs) { 151static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
156 int i; 152 int i;
157 Table *htab; 153 Table *htab;
158 TObject nname; 154 TObject nname;
159 int actual = L->top - L->ci->base; /* actual number of arguments */ 155 int actual = L->top - base; /* actual number of arguments */
160 if (actual < nfixargs) { 156 if (actual < nfixargs) {
161 luaD_checkstack(L, nfixargs - actual); 157 luaD_checkstack(L, nfixargs - actual);
162 for (; actual < nfixargs; ++actual) 158 for (; actual < nfixargs; ++actual)
@@ -178,49 +174,52 @@ static void adjust_varargs (lua_State *L, int nfixargs) {
178static StkId tryfuncTM (lua_State *L, StkId func) { 174static StkId tryfuncTM (lua_State *L, StkId func) {
179 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); 175 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
180 StkId p; 176 StkId p;
181 if (ttype(tm) != LUA_TFUNCTION) { 177 ptrdiff_t funcr = savestack(L, func);
182 L->ci--; /* undo increment (no function here) */ 178 if (ttype(tm) != LUA_TFUNCTION)
183 luaG_typeerror(L, func, "call"); 179 luaG_typeerror(L, func, "call");
184 }
185 /* Open a hole inside the stack at `func' */ 180 /* Open a hole inside the stack at `func' */
186 for (p = L->top; p > func; p--) setobj(p, p-1); 181 for (p = L->top; p > func; p--) setobj(p, p-1);
187 incr_top(L); 182 incr_top(L);
188 func = L->ci->base - 1; /* previous call may change stack */ 183 func = restorestack(L, funcr); /* previous call may change stack */
189 setobj(func, tm); /* tag method is the new function to be called */ 184 setobj(func, tm); /* tag method is the new function to be called */
190 return func; 185 return func;
191} 186}
192 187
193 188
194StkId luaD_precall (lua_State *L, StkId func) { 189StkId luaD_precall (lua_State *L, StkId func) {
195 CallInfo *ci;
196 LClosure *cl; 190 LClosure *cl;
197 if (++L->ci == L->end_ci) luaD_growCI(L); 191 ptrdiff_t funcr = savestack(L, func);
198 ci = L->ci;
199 ci->base = func+1;
200 ci->pc = NULL;
201 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ 192 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
202 func = tryfuncTM(L, func); /* check the `function' tag method */ 193 func = tryfuncTM(L, func); /* check the `function' tag method */
194 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
203 cl = &clvalue(func)->l; 195 cl = &clvalue(func)->l;
204 if (L->hookmask & LUA_MASKCALL) {
205 luaD_callhook(L, LUA_HOOKCALL, -1);
206 ci = L->ci; /* previous call may realocate `ci' */
207 }
208 if (!cl->isC) { /* Lua function? prepare its call */ 196 if (!cl->isC) { /* Lua function? prepare its call */
197 CallInfo *ci;
209 Proto *p = cl->p; 198 Proto *p = cl->p;
210 ci->savedpc = p->code; /* starting point */
211 if (p->is_vararg) /* varargs? */ 199 if (p->is_vararg) /* varargs? */
212 adjust_varargs(L, p->numparams); 200 adjust_varargs(L, p->numparams, func+1);
213 luaD_checkstack(L, p->maxstacksize); 201 luaD_checkstack(L, p->maxstacksize);
202 ci = ++L->ci; /* now `enter' new function */
203 ci->base = restorestack(L, funcr) + 1;
214 ci->top = ci->base + p->maxstacksize; 204 ci->top = ci->base + p->maxstacksize;
205 ci->savedpc = p->code; /* starting point */
215 while (L->top < ci->top) 206 while (L->top < ci->top)
216 setnilvalue(L->top++); 207 setnilvalue(L->top++);
217 L->top = ci->top; 208 L->top = ci->top;
218 return NULL; 209 return NULL;
219 } 210 }
220 else { /* if is a C function, call it */ 211 else { /* if is a C function, call it */
212 CallInfo *ci;
221 int n; 213 int n;
222 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 214 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
215 ci = ++L->ci; /* now `enter' new function */
216 ci->base = restorestack(L, funcr) + 1;
223 ci->top = L->top + LUA_MINSTACK; 217 ci->top = L->top + LUA_MINSTACK;
218 ci->savedpc = NULL; /* not a Lua function */
219 if (L->hookmask & LUA_MASKCALL) {
220 luaD_callhook(L, LUA_HOOKCALL, -1);
221 ci = L->ci; /* previous call may realocate `ci' */
222 }
224 lua_unlock(L); 223 lua_unlock(L);
225#if LUA_COMPATUPVALUES 224#if LUA_COMPATUPVALUES
226 lua_pushupvalues(L); 225 lua_pushupvalues(L);
@@ -296,9 +295,10 @@ struct ResS {
296static void resume (lua_State *L, void *ud) { 295static void resume (lua_State *L, void *ud) {
297 StkId firstResult; 296 StkId firstResult;
298 CallInfo *ci = L->ci; 297 CallInfo *ci = L->ci;
299 if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ 298 if (!isLua(ci)) { /* not first time? */
300 /* finish interupted execution of `OP_CALL' */ 299 /* finish interrupted execution of `OP_CALL' */
301 int nresults; 300 int nresults;
301 lua_assert(isLua(ci - 1));
302 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); 302 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL);
303 nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; 303 nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1;
304 luaD_poscall(L, nresults, L->top); /* complete it */ 304 luaD_poscall(L, nresults, L->top); /* complete it */
@@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) {
306 } 306 }
307 firstResult = luaV_execute(L); 307 firstResult = luaV_execute(L);
308 if (firstResult == NULL) /* yield? */ 308 if (firstResult == NULL) /* yield? */
309 cast(struct ResS *, ud)->numres = L->ci->yield_results; 309 cast(struct ResS *, ud)->numres = L->ci->u.c.yield_results;
310 else { /* return */ 310 else { /* return */
311 cast(struct ResS *, ud)->numres = L->top - firstResult; 311 cast(struct ResS *, ud)->numres = L->top - firstResult;
312 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 312 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
@@ -338,9 +338,10 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
338 CallInfo *ci; 338 CallInfo *ci;
339 lua_lock(L); 339 lua_lock(L);
340 ci = L->ci; 340 ci = L->ci;
341 if (ci_func(ci-1)->c.isC) 341 if (!isLua(ci-1))
342 luaG_runerror(L, "cannot yield a C function"); 342 luaG_runerror(L, "cannot yield a C function");
343 ci->yield_results = nresults; 343 lua_assert(!isLua(ci));
344 ci->u.c.yield_results = nresults;
344 lua_unlock(L); 345 lua_unlock(L);
345 return -1; 346 return -1;
346} 347}