diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 15:16:52 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 15:16:52 -0200 |
commit | 2d2d45976ce41de04e9007c8a78a8ba244d1fdc5 (patch) | |
tree | 0573761b205be9aa1471364159e559a2d5e80f9e /ldo.c | |
parent | 0050d983fc2f3cc56442cadd73a93823643ac53d (diff) | |
download | lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.gz lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.tar.bz2 lua-2d2d45976ce41de04e9007c8a78a8ba244d1fdc5.zip |
separated control over C recursion level
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 31 |
1 files changed, 19 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.206 2002/11/21 15:46:44 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.207 2002/11/21 17:19:11 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 | */ |
@@ -126,7 +126,7 @@ void luaD_reallocstack (lua_State *L, int newsize) { | |||
126 | void luaD_reallocCI (lua_State *L, int newsize) { | 126 | void luaD_reallocCI (lua_State *L, int newsize) { |
127 | CallInfo *oldci = L->base_ci; | 127 | CallInfo *oldci = L->base_ci; |
128 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | 128 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); |
129 | L->size_ci = newsize; | 129 | L->size_ci = cast(unsigned short, newsize); |
130 | L->ci = (L->ci - oldci) + L->base_ci; | 130 | L->ci = (L->ci - oldci) + L->base_ci; |
131 | L->end_ci = L->base_ci + L->size_ci; | 131 | L->end_ci = L->base_ci + L->size_ci; |
132 | } | 132 | } |
@@ -288,15 +288,18 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | |||
288 | ** function position. | 288 | ** function position. |
289 | */ | 289 | */ |
290 | void luaD_call (lua_State *L, StkId func, int nResults) { | 290 | void luaD_call (lua_State *L, StkId func, int nResults) { |
291 | StkId firstResult = luaD_precall(L, func); | 291 | StkId firstResult; |
292 | if (firstResult == NULL) { /* is a Lua function? */ | 292 | if (++L->nCcalls >= LUA_MAXCCALLS) { |
293 | firstResult = luaV_execute(L); /* call it */ | 293 | if (L->nCcalls == LUA_MAXCCALLS) |
294 | if (firstResult == NULL) { | 294 | luaG_runerror(L, "stack overflow"); |
295 | luaD_poscall(L, 0, L->top); | 295 | else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) |
296 | luaG_runerror(L, "attempt to yield across tag-method/C-call boundary"); | 296 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ |
297 | } | ||
298 | } | 297 | } |
298 | firstResult = luaD_precall(L, func); | ||
299 | if (firstResult == NULL) /* is a Lua function? */ | ||
300 | firstResult = luaV_execute(L); /* call it */ | ||
299 | luaD_poscall(L, nResults, firstResult); | 301 | luaD_poscall(L, nResults, firstResult); |
302 | L->nCcalls--; | ||
300 | } | 303 | } |
301 | 304 | ||
302 | 305 | ||
@@ -337,11 +340,12 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
337 | lu_byte old_allowhooks; | 340 | lu_byte old_allowhooks; |
338 | lua_lock(L); | 341 | lua_lock(L); |
339 | old_allowhooks = L->allowhook; | 342 | old_allowhooks = L->allowhook; |
340 | lua_assert(L->errfunc == 0); | 343 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); |
341 | status = luaD_rawrunprotected(L, resume, &nargs); | 344 | status = luaD_rawrunprotected(L, resume, &nargs); |
342 | if (status != 0) { /* error? */ | 345 | if (status != 0) { /* error? */ |
343 | L->ci = L->base_ci; /* go back to initial level */ | 346 | L->ci = L->base_ci; /* go back to initial level */ |
344 | L->base = L->ci->base; | 347 | L->base = L->ci->base; |
348 | L->nCcalls = 0; | ||
345 | luaF_close(L, L->base); /* close eventual pending closures */ | 349 | luaF_close(L, L->base); /* close eventual pending closures */ |
346 | seterrorobj(L, status, L->base); | 350 | seterrorobj(L, status, L->base); |
347 | L->allowhook = old_allowhooks; | 351 | L->allowhook = old_allowhooks; |
@@ -356,6 +360,8 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
356 | CallInfo *ci; | 360 | CallInfo *ci; |
357 | lua_lock(L); | 361 | lua_lock(L); |
358 | ci = L->ci; | 362 | ci = L->ci; |
363 | if (L->nCcalls > 0) | ||
364 | luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); | ||
359 | if (ci->state & CI_C) { /* usual yield */ | 365 | if (ci->state & CI_C) { /* usual yield */ |
360 | if ((ci-1)->state & CI_C) | 366 | if ((ci-1)->state & CI_C) |
361 | luaG_runerror(L, "cannot yield a C function"); | 367 | luaG_runerror(L, "cannot yield a C function"); |
@@ -365,8 +371,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
365 | setobjs2s(L->base + i, L->top - nresults + i); | 371 | setobjs2s(L->base + i, L->top - nresults + i); |
366 | L->top = L->base + nresults; | 372 | L->top = L->base + nresults; |
367 | } | 373 | } |
368 | } | 374 | } /* else it's an yield inside a hook: nothing to do */ |
369 | /* else it's an yield inside a hook: nothing to do */ | ||
370 | ci->state |= CI_YIELD; | 375 | ci->state |= CI_YIELD; |
371 | lua_unlock(L); | 376 | lua_unlock(L); |
372 | return -1; | 377 | return -1; |
@@ -391,6 +396,7 @@ static void f_call (lua_State *L, void *ud) { | |||
391 | int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { | 396 | int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { |
392 | struct CallS c; | 397 | struct CallS c; |
393 | int status; | 398 | int status; |
399 | unsigned short oldnCcalls = L->nCcalls; | ||
394 | ptrdiff_t old_top = savestack(L, L->top); | 400 | ptrdiff_t old_top = savestack(L, L->top); |
395 | ptrdiff_t old_ci = saveci(L, L->ci); | 401 | ptrdiff_t old_ci = saveci(L, L->ci); |
396 | lu_byte old_allowhooks = L->allowhook; | 402 | lu_byte old_allowhooks = L->allowhook; |
@@ -403,6 +409,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { | |||
403 | StkId oldtop = restorestack(L, old_top) - (nargs+1); | 409 | StkId oldtop = restorestack(L, old_top) - (nargs+1); |
404 | luaF_close(L, oldtop); /* close eventual pending closures */ | 410 | luaF_close(L, oldtop); /* close eventual pending closures */ |
405 | seterrorobj(L, status, oldtop); | 411 | seterrorobj(L, status, oldtop); |
412 | L->nCcalls = oldnCcalls; | ||
406 | L->ci = restoreci(L, old_ci); | 413 | L->ci = restoreci(L, old_ci); |
407 | L->base = L->ci->base; | 414 | L->base = L->ci->base; |
408 | L->allowhook = old_allowhooks; | 415 | L->allowhook = old_allowhooks; |