aboutsummaryrefslogtreecommitdiff
path: root/src/lua/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/ldo.c')
-rw-r--r--src/lua/ldo.c145
1 files changed, 90 insertions, 55 deletions
diff --git a/src/lua/ldo.c b/src/lua/ldo.c
index 5473815..5729b19 100644
--- a/src/lua/ldo.c
+++ b/src/lua/ldo.c
@@ -139,8 +139,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
139 139
140 140
141int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 141int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
142 global_State *g = G(L); 142 l_uint32 oldnCcalls = L->nCcalls;
143 l_uint32 oldnCcalls = g->Cstacklimit - (L->nCcalls + L->nci);
144 struct lua_longjmp lj; 143 struct lua_longjmp lj;
145 lj.status = LUA_OK; 144 lj.status = LUA_OK;
146 lj.previous = L->errorJmp; /* chain new error handler */ 145 lj.previous = L->errorJmp; /* chain new error handler */
@@ -149,7 +148,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
149 (*f)(L, ud); 148 (*f)(L, ud);
150 ); 149 );
151 L->errorJmp = lj.previous; /* restore old error handler */ 150 L->errorJmp = lj.previous; /* restore old error handler */
152 L->nCcalls = g->Cstacklimit - oldnCcalls - L->nci; 151 L->nCcalls = oldnCcalls;
153 return lj.status; 152 return lj.status;
154} 153}
155 154
@@ -183,10 +182,10 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
183 182
184 183
185int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { 184int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
186 int lim = L->stacksize; 185 int lim = stacksize(L);
187 StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); 186 StkId newstack = luaM_reallocvector(L, L->stack,
187 lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue);
188 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 188 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
189 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
190 if (unlikely(newstack == NULL)) { /* reallocation failed? */ 189 if (unlikely(newstack == NULL)) { /* reallocation failed? */
191 if (raiseerror) 190 if (raiseerror)
192 luaM_error(L); 191 luaM_error(L);
@@ -196,8 +195,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
196 setnilvalue(s2v(newstack + lim)); /* erase new segment */ 195 setnilvalue(s2v(newstack + lim)); /* erase new segment */
197 correctstack(L, L->stack, newstack); 196 correctstack(L, L->stack, newstack);
198 L->stack = newstack; 197 L->stack = newstack;
199 L->stacksize = newsize; 198 L->stack_last = L->stack + newsize;
200 L->stack_last = L->stack + newsize - EXTRA_STACK;
201 return 1; 199 return 1;
202} 200}
203 201
@@ -207,51 +205,73 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
207** is true, raises any error; otherwise, return 0 in case of errors. 205** is true, raises any error; otherwise, return 0 in case of errors.
208*/ 206*/
209int luaD_growstack (lua_State *L, int n, int raiseerror) { 207int luaD_growstack (lua_State *L, int n, int raiseerror) {
210 int size = L->stacksize; 208 int size = stacksize(L);
211 int newsize = 2 * size; /* tentative new size */ 209 if (unlikely(size > LUAI_MAXSTACK)) {
212 if (unlikely(size > LUAI_MAXSTACK)) { /* need more space after extra size? */ 210 /* if stack is larger than maximum, thread is already using the
211 extra space reserved for errors, that is, thread is handling
212 a stack error; cannot grow further than that. */
213 lua_assert(stacksize(L) == ERRORSTACKSIZE);
213 if (raiseerror) 214 if (raiseerror)
214 luaD_throw(L, LUA_ERRERR); /* error inside message handler */ 215 luaD_throw(L, LUA_ERRERR); /* error inside message handler */
215 else return 0; 216 return 0; /* if not 'raiseerror', just signal it */
216 } 217 }
217 else { 218 else {
218 int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; 219 int newsize = 2 * size; /* tentative new size */
220 int needed = cast_int(L->top - L->stack) + n;
219 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ 221 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
220 newsize = LUAI_MAXSTACK; 222 newsize = LUAI_MAXSTACK;
221 if (newsize < needed) /* but must respect what was asked for */ 223 if (newsize < needed) /* but must respect what was asked for */
222 newsize = needed; 224 newsize = needed;
223 if (unlikely(newsize > LUAI_MAXSTACK)) { /* stack overflow? */ 225 if (likely(newsize <= LUAI_MAXSTACK))
226 return luaD_reallocstack(L, newsize, raiseerror);
227 else { /* stack overflow */
224 /* add extra size to be able to handle the error message */ 228 /* add extra size to be able to handle the error message */
225 luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); 229 luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
226 if (raiseerror) 230 if (raiseerror)
227 luaG_runerror(L, "stack overflow"); 231 luaG_runerror(L, "stack overflow");
228 else return 0; 232 return 0;
229 } 233 }
230 } /* else no errors */ 234 }
231 return luaD_reallocstack(L, newsize, raiseerror);
232} 235}
233 236
234 237
235static int stackinuse (lua_State *L) { 238static int stackinuse (lua_State *L) {
236 CallInfo *ci; 239 CallInfo *ci;
240 int res;
237 StkId lim = L->top; 241 StkId lim = L->top;
238 for (ci = L->ci; ci != NULL; ci = ci->previous) { 242 for (ci = L->ci; ci != NULL; ci = ci->previous) {
239 if (lim < ci->top) lim = ci->top; 243 if (lim < ci->top) lim = ci->top;
240 } 244 }
241 lua_assert(lim <= L->stack_last); 245 lua_assert(lim <= L->stack_last);
242 return cast_int(lim - L->stack) + 1; /* part of stack in use */ 246 res = cast_int(lim - L->stack) + 1; /* part of stack in use */
247 if (res < LUA_MINSTACK)
248 res = LUA_MINSTACK; /* ensure a minimum size */
249 return res;
243} 250}
244 251
245 252
253/*
254** If stack size is more than 3 times the current use, reduce that size
255** to twice the current use. (So, the final stack size is at most 2/3 the
256** previous size, and half of its entries are empty.)
257** As a particular case, if stack was handling a stack overflow and now
258** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than
259** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack
260** will be reduced to a "regular" size.
261*/
246void luaD_shrinkstack (lua_State *L) { 262void luaD_shrinkstack (lua_State *L) {
247 int inuse = stackinuse(L); 263 int inuse = stackinuse(L);
248 int goodsize = inuse + BASIC_STACK_SIZE; 264 int nsize = inuse * 2; /* proposed new size */
249 if (goodsize > LUAI_MAXSTACK) 265 int max = inuse * 3; /* maximum "reasonable" size */
250 goodsize = LUAI_MAXSTACK; /* respect stack limit */ 266 if (max > LUAI_MAXSTACK) {
267 max = LUAI_MAXSTACK; /* respect stack limit */
268 if (nsize > LUAI_MAXSTACK)
269 nsize = LUAI_MAXSTACK;
270 }
251 /* if thread is currently not handling a stack overflow and its 271 /* if thread is currently not handling a stack overflow and its
252 good size is smaller than current size, shrink its stack */ 272 size is larger than maximum "reasonable" size, shrink it */
253 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize) 273 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
254 luaD_reallocstack(L, goodsize, 0); /* ok if that fails */ 274 luaD_reallocstack(L, nsize, 0); /* ok if that fails */
255 else /* don't change stack */ 275 else /* don't change stack */
256 condmovestack(L,{},{}); /* (change only for debugging) */ 276 condmovestack(L,{},{}); /* (change only for debugging) */
257 luaE_shrinkCI(L); /* shrink CI list */ 277 luaE_shrinkCI(L); /* shrink CI list */
@@ -348,7 +368,7 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
348 368
349/* 369/*
350** Check whether 'func' has a '__call' metafield. If so, put it in the 370** Check whether 'func' has a '__call' metafield. If so, put it in the
351** stack, below original 'func', so that 'luaD_call' can call it. Raise 371** stack, below original 'func', so that 'luaD_precall' can call it. Raise
352** an error if there is no '__call' metafield. 372** an error if there is no '__call' metafield.
353*/ 373*/
354void luaD_tryfuncTM (lua_State *L, StkId func) { 374void luaD_tryfuncTM (lua_State *L, StkId func) {
@@ -449,12 +469,14 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
449 469
450 470
451/* 471/*
452** Call a function (C or Lua). The function to be called is at *func. 472** Prepares the call to a function (C or Lua). For C functions, also do
453** The arguments are on the stack, right after the function. 473** the call. The function to be called is at '*func'. The arguments
454** When returns, all the results are on the stack, starting at the original 474** are on the stack, right after the function. Returns the CallInfo
455** function position. 475** to be executed, if it was a Lua function. Otherwise (a C function)
476** returns NULL, with all the results on the stack, starting at the
477** original function position.
456*/ 478*/
457void luaD_call (lua_State *L, StkId func, int nresults) { 479CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
458 lua_CFunction f; 480 lua_CFunction f;
459 retry: 481 retry:
460 switch (ttypetag(s2v(func))) { 482 switch (ttypetag(s2v(func))) {
@@ -482,7 +504,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
482 lua_lock(L); 504 lua_lock(L);
483 api_checknelems(L, n); 505 api_checknelems(L, n);
484 luaD_poscall(L, ci, n); 506 luaD_poscall(L, ci, n);
485 break; 507 return NULL;
486 } 508 }
487 case LUA_VLCL: { /* Lua function */ 509 case LUA_VLCL: { /* Lua function */
488 CallInfo *ci; 510 CallInfo *ci;
@@ -494,15 +516,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
494 L->ci = ci = next_ci(L); 516 L->ci = ci = next_ci(L);
495 ci->nresults = nresults; 517 ci->nresults = nresults;
496 ci->u.l.savedpc = p->code; /* starting point */ 518 ci->u.l.savedpc = p->code; /* starting point */
497 ci->callstatus = 0;
498 ci->top = func + 1 + fsize; 519 ci->top = func + 1 + fsize;
499 ci->func = func; 520 ci->func = func;
500 L->ci = ci; 521 L->ci = ci;
501 for (; narg < nfixparams; narg++) 522 for (; narg < nfixparams; narg++)
502 setnilvalue(s2v(L->top++)); /* complete missing arguments */ 523 setnilvalue(s2v(L->top++)); /* complete missing arguments */
503 lua_assert(ci->top <= L->stack_last); 524 lua_assert(ci->top <= L->stack_last);
504 luaV_execute(L, ci); /* run the function */ 525 return ci;
505 break;
506 } 526 }
507 default: { /* not a function */ 527 default: { /* not a function */
508 checkstackGCp(L, 1, func); /* space for metamethod */ 528 checkstackGCp(L, 1, func); /* space for metamethod */
@@ -514,16 +534,36 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
514 534
515 535
516/* 536/*
537** Call a function (C or Lua). 'inc' can be 1 (increment number
538** of recursive invocations in the C stack) or nyci (the same plus
539** increment number of non-yieldable calls).
540*/
541static void docall (lua_State *L, StkId func, int nResults, int inc) {
542 CallInfo *ci;
543 L->nCcalls += inc;
544 if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
545 luaE_checkcstack(L);
546 if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
547 ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
548 luaV_execute(L, ci); /* call it */
549 }
550 L->nCcalls -= inc;
551}
552
553
554/*
555** External interface for 'docall'
556*/
557void luaD_call (lua_State *L, StkId func, int nResults) {
558 return docall(L, func, nResults, 1);
559}
560
561
562/*
517** Similar to 'luaD_call', but does not allow yields during the call. 563** Similar to 'luaD_call', but does not allow yields during the call.
518*/ 564*/
519void luaD_callnoyield (lua_State *L, StkId func, int nResults) { 565void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
520 incXCcalls(L); 566 return docall(L, func, nResults, nyci);
521 if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */
522 luaE_exitCcall(L); /* to compensate decrement in next call */
523 luaE_enterCcall(L); /* check properly */
524 }
525 luaD_call(L, func, nResults);
526 decXCcalls(L);
527} 567}
528 568
529 569
@@ -601,12 +641,12 @@ static int recover (lua_State *L, int status) {
601 if (ci == NULL) return 0; /* no recovery point */ 641 if (ci == NULL) return 0; /* no recovery point */
602 /* "finish" luaD_pcall */ 642 /* "finish" luaD_pcall */
603 oldtop = restorestack(L, ci->u2.funcidx); 643 oldtop = restorestack(L, ci->u2.funcidx);
604 luaF_close(L, oldtop, status); /* may change the stack */
605 oldtop = restorestack(L, ci->u2.funcidx);
606 luaD_seterrorobj(L, status, oldtop);
607 L->ci = ci; 644 L->ci = ci;
608 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 645 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
609 luaD_shrinkstack(L); 646 status = luaF_close(L, oldtop, status); /* may change the stack */
647 oldtop = restorestack(L, ci->u2.funcidx);
648 luaD_seterrorobj(L, status, oldtop);
649 luaD_shrinkstack(L); /* restore stack size in case of overflow */
610 L->errfunc = ci->u.c.old_errfunc; 650 L->errfunc = ci->u.c.old_errfunc;
611 return 1; /* continue running the coroutine */ 651 return 1; /* continue running the coroutine */
612} 652}
@@ -637,12 +677,12 @@ static void resume (lua_State *L, void *ud) {
637 int n = *(cast(int*, ud)); /* number of arguments */ 677 int n = *(cast(int*, ud)); /* number of arguments */
638 StkId firstArg = L->top - n; /* first argument */ 678 StkId firstArg = L->top - n; /* first argument */
639 CallInfo *ci = L->ci; 679 CallInfo *ci = L->ci;
640 if (L->status == LUA_OK) { /* starting a coroutine? */ 680 if (L->status == LUA_OK) /* starting a coroutine? */
641 luaD_call(L, firstArg - 1, LUA_MULTRET); 681 docall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
642 }
643 else { /* resuming from previous yield */ 682 else { /* resuming from previous yield */
644 lua_assert(L->status == LUA_YIELD); 683 lua_assert(L->status == LUA_YIELD);
645 L->status = LUA_OK; /* mark that it is running (again) */ 684 L->status = LUA_OK; /* mark that it is running (again) */
685 luaE_incCstack(L); /* control the C stack */
646 if (isLua(ci)) /* yielded inside a hook? */ 686 if (isLua(ci)) /* yielded inside a hook? */
647 luaV_execute(L, ci); /* just continue running Lua code */ 687 luaV_execute(L, ci); /* just continue running Lua code */
648 else { /* 'common' yield */ 688 else { /* 'common' yield */
@@ -670,12 +710,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
670 } 710 }
671 else if (L->status != LUA_YIELD) /* ended with errors? */ 711 else if (L->status != LUA_YIELD) /* ended with errors? */
672 return resume_error(L, "cannot resume dead coroutine", nargs); 712 return resume_error(L, "cannot resume dead coroutine", nargs);
673 if (from == NULL) 713 L->nCcalls = (from) ? getCcalls(from) : 0;
674 L->nCcalls = CSTACKTHREAD;
675 else /* correct 'nCcalls' for this thread */
676 L->nCcalls = getCcalls(from) - L->nci - CSTACKCF;
677 if (L->nCcalls <= CSTACKERR)
678 return resume_error(L, "C stack overflow", nargs);
679 luai_userstateresume(L, nargs); 714 luai_userstateresume(L, nargs);
680 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); 715 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
681 status = luaD_rawrunprotected(L, resume, &nargs); 716 status = luaD_rawrunprotected(L, resume, &nargs);
@@ -754,7 +789,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
754 status = luaF_close(L, oldtop, status); 789 status = luaF_close(L, oldtop, status);
755 oldtop = restorestack(L, old_top); /* previous call may change stack */ 790 oldtop = restorestack(L, old_top); /* previous call may change stack */
756 luaD_seterrorobj(L, status, oldtop); 791 luaD_seterrorobj(L, status, oldtop);
757 luaD_shrinkstack(L); 792 luaD_shrinkstack(L); /* restore stack size in case of overflow */
758 } 793 }
759 L->errfunc = old_errfunc; 794 L->errfunc = old_errfunc;
760 return status; 795 return status;