aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-23 14:41:16 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-23 14:41:16 -0200
commit196c87c9cecfacf978f37de4ec69eba0a5971256 (patch)
treece434c8a63228cf1f25adcc2210ba741ee899887 /ldo.c
parent39f26b1480502cc2f75a5af6e06e5410e06634ba (diff)
downloadlua-196c87c9cecfacf978f37de4ec69eba0a5971256.tar.gz
lua-196c87c9cecfacf978f37de4ec69eba0a5971256.tar.bz2
lua-196c87c9cecfacf978f37de4ec69eba0a5971256.zip
no more 'stackless' implementation; 'luaV_execute' calls itself
recursively to execute function calls. 'unroll' continues all executions suspended by an yield (through a long jump)
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c66
1 files changed, 18 insertions, 48 deletions
diff --git a/ldo.c b/ldo.c
index 30954123..6b8162d2 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.172 2017/11/13 15:36:52 roberto Exp roberto $ 2** $Id: ldo.c,v 2.173 2017/11/21 14:17:35 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*/
@@ -135,7 +135,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
135 135
136 136
137int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 137int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
138 unsigned short oldnCcalls = L->nCcalls; 138 unsigned short oldnCcalls = L->nCcalls - L->nci;
139 struct lua_longjmp lj; 139 struct lua_longjmp lj;
140 lj.status = LUA_OK; 140 lj.status = LUA_OK;
141 lj.previous = L->errorJmp; /* chain new error handler */ 141 lj.previous = L->errorJmp; /* chain new error handler */
@@ -144,7 +144,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
144 (*f)(L, ud); 144 (*f)(L, ud);
145 ); 145 );
146 L->errorJmp = lj.previous; /* restore old error handler */ 146 L->errorJmp = lj.previous; /* restore old error handler */
147 L->nCcalls = oldnCcalls; 147 L->nCcalls = oldnCcalls + L->nci;
148 return lj.status; 148 return lj.status;
149} 149}
150 150
@@ -299,7 +299,7 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
299 299
300/* 300/*
301** Check whether __call metafield of 'func' is a function. If so, put 301** Check whether __call metafield of 'func' is a function. If so, put
302** it in stack below original 'func' so that 'luaD_precall' can call 302** it in stack below original 'func' so that 'luaD_call' can call
303** it. Raise an error if __call metafield is not a function. 303** it. Raise an error if __call metafield is not a function.
304*/ 304*/
305StkId luaD_tryfuncTM (lua_State *L, StkId func) { 305StkId luaD_tryfuncTM (lua_State *L, StkId func) {
@@ -417,13 +417,12 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n) {
417 417
418 418
419/* 419/*
420** Prepares a function call: checks the stack, creates a new CallInfo 420** Call a function (C or Lua). The function to be called is at *func.
421** entry, fills in the relevant information, calls hook if needed. 421** The arguments are on the stack, right after the function.
422** If function is a C function, does the call, too. (Otherwise, leave 422** When returns, all the results are on the stack, starting at the original
423** the execution ('luaV_execute') to the caller, to allow stackless 423** function position.
424** calls.) Returns true iff function has been executed (C function).
425*/ 424*/
426int luaD_precall (lua_State *L, StkId func, int nresults) { 425void luaD_call (lua_State *L, StkId func, int nresults) {
427 lua_CFunction f; 426 lua_CFunction f;
428 TValue *funcv = s2v(func); 427 TValue *funcv = s2v(func);
429 CallInfo *ci; 428 CallInfo *ci;
@@ -449,7 +448,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
449 lua_lock(L); 448 lua_lock(L);
450 api_checknelems(L, n); 449 api_checknelems(L, n);
451 luaD_poscall(L, ci, L->top - n, n); 450 luaD_poscall(L, ci, L->top - n, n);
452 return 1; 451 break;
453 } 452 }
454 case LUA_TLCL: { /* Lua function: prepare its call */ 453 case LUA_TLCL: { /* Lua function: prepare its call */
455 Proto *p = clLvalue(funcv)->p; 454 Proto *p = clLvalue(funcv)->p;
@@ -469,47 +468,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
469 ci->callstatus = CIST_LUA; 468 ci->callstatus = CIST_LUA;
470 if (L->hookmask) 469 if (L->hookmask)
471 callhook(L, ci, 0); 470 callhook(L, ci, 0);
472 return 0; 471 luaV_execute(L); /* run the function */
472 break;
473 } 473 }
474 default: { /* not a function */ 474 default: { /* not a function */
475 func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ 475 func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
476 return luaD_precall(L, func, nresults); /* now it must be a function */ 476 luaD_call(L, func, nresults); /* now it must be a function */
477 break;
477 } 478 }
478 } 479 }
479} 480}
480 481
481 482
482/* 483/*
483** Check appropriate error for stack overflow ("regular" overflow or
484** overflow while handling stack overflow). If 'nCalls' is larger than
485** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
486** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
487** allow overflow handling to work)
488*/
489static void stackerror (lua_State *L) {
490 if (L->nCcalls == LUAI_MAXCCALLS)
491 luaG_runerror(L, "C stack overflow");
492 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
493 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
494}
495
496
497/*
498** Call a function (C or Lua). The function to be called is at *func.
499** The arguments are on the stack, right after the function.
500** When returns, all the results are on the stack, starting at the original
501** function position.
502*/
503void luaD_call (lua_State *L, StkId func, int nResults) {
504 if (++L->nCcalls >= LUAI_MAXCCALLS)
505 stackerror(L);
506 if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
507 luaV_execute(L); /* call it */
508 L->nCcalls--;
509}
510
511
512/*
513** Similar to 'luaD_call', but does not allow yields during the call 484** Similar to 'luaD_call', but does not allow yields during the call
514*/ 485*/
515void luaD_callnoyield (lua_State *L, StkId func, int nResults) { 486void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
@@ -541,7 +512,7 @@ static void finishCcall (lua_State *L, int status) {
541 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ 512 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
542 lua_lock(L); 513 lua_lock(L);
543 api_checknelems(L, n); 514 api_checknelems(L, n);
544 luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ 515 luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_call' */
545} 516}
546 517
547 518
@@ -629,8 +600,7 @@ static void resume (lua_State *L, void *ud) {
629 StkId firstArg = L->top - n; /* first argument */ 600 StkId firstArg = L->top - n; /* first argument */
630 CallInfo *ci = L->ci; 601 CallInfo *ci = L->ci;
631 if (L->status == LUA_OK) { /* starting a coroutine? */ 602 if (L->status == LUA_OK) { /* starting a coroutine? */
632 if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ 603 luaD_call(L, firstArg - 1, LUA_MULTRET);
633 luaV_execute(L); /* call it */
634 } 604 }
635 else { /* resuming from previous yield */ 605 else { /* resuming from previous yield */
636 lua_assert(L->status == LUA_YIELD); 606 lua_assert(L->status == LUA_YIELD);
@@ -645,7 +615,7 @@ static void resume (lua_State *L, void *ud) {
645 api_checknelems(L, n); 615 api_checknelems(L, n);
646 firstArg = L->top - n; /* yield results come from continuation */ 616 firstArg = L->top - n; /* yield results come from continuation */
647 } 617 }
648 luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ 618 luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_call' */
649 } 619 }
650 unroll(L, NULL); /* run continuation */ 620 unroll(L, NULL); /* run continuation */
651 } 621 }
@@ -688,7 +658,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
688 : L->top - (L->ci->func + 1); 658 : L->top - (L->ci->func + 1);
689 L->nny = oldnny; /* restore 'nny' */ 659 L->nny = oldnny; /* restore 'nny' */
690 L->nCcalls--; 660 L->nCcalls--;
691 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); 661 // lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
692 lua_unlock(L); 662 lua_unlock(L);
693 return status; 663 return status;
694} 664}