diff options
Diffstat (limited to '')
-rw-r--r-- | src/3rdParty/lua/ldo.c | 125 |
1 files changed, 77 insertions, 48 deletions
diff --git a/src/3rdParty/lua/ldo.c b/src/3rdParty/lua/ldo.c index 88b20f9..f282a77 100644 --- a/src/3rdParty/lua/ldo.c +++ b/src/3rdParty/lua/ldo.c | |||
@@ -388,9 +388,10 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { | |||
388 | ** an error if there is no '__call' metafield. | 388 | ** an error if there is no '__call' metafield. |
389 | */ | 389 | */ |
390 | StkId luaD_tryfuncTM (lua_State *L, StkId func) { | 390 | StkId luaD_tryfuncTM (lua_State *L, StkId func) { |
391 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); | 391 | const TValue *tm; |
392 | StkId p; | 392 | StkId p; |
393 | checkstackGCp(L, 1, func); /* space for metamethod */ | 393 | checkstackGCp(L, 1, func); /* space for metamethod */ |
394 | tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ | ||
394 | if (l_unlikely(ttisnil(tm))) | 395 | if (l_unlikely(ttisnil(tm))) |
395 | luaG_callerror(L, s2v(func)); /* nothing to call */ | 396 | luaG_callerror(L, s2v(func)); /* nothing to call */ |
396 | for (p = L->top; p > func; p--) /* open space for metamethod */ | 397 | for (p = L->top; p > func; p--) /* open space for metamethod */ |
@@ -475,30 +476,6 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { | |||
475 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) | 476 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) |
476 | 477 | ||
477 | 478 | ||
478 | /* | ||
479 | ** Prepare a function for a tail call, building its call info on top | ||
480 | ** of the current call info. 'narg1' is the number of arguments plus 1 | ||
481 | ** (so that it includes the function itself). | ||
482 | */ | ||
483 | void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | ||
484 | Proto *p = clLvalue(s2v(func))->p; | ||
485 | int fsize = p->maxstacksize; /* frame size */ | ||
486 | int nfixparams = p->numparams; | ||
487 | int i; | ||
488 | for (i = 0; i < narg1; i++) /* move down function and arguments */ | ||
489 | setobjs2s(L, ci->func + i, func + i); | ||
490 | checkstackGC(L, fsize); | ||
491 | func = ci->func; /* moved-down function */ | ||
492 | for (; narg1 <= nfixparams; narg1++) | ||
493 | setnilvalue(s2v(func + narg1)); /* complete missing arguments */ | ||
494 | ci->top = func + 1 + fsize; /* top for new function */ | ||
495 | lua_assert(ci->top <= L->stack_last); | ||
496 | ci->u.l.savedpc = p->code; /* starting point */ | ||
497 | ci->callstatus |= CIST_TAIL; | ||
498 | L->top = func + narg1; /* set top */ | ||
499 | } | ||
500 | |||
501 | |||
502 | l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, | 479 | l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, |
503 | int mask, StkId top) { | 480 | int mask, StkId top) { |
504 | CallInfo *ci = L->ci = next_ci(L); /* new frame */ | 481 | CallInfo *ci = L->ci = next_ci(L); /* new frame */ |
@@ -511,6 +488,73 @@ l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, | |||
511 | 488 | ||
512 | 489 | ||
513 | /* | 490 | /* |
491 | ** precall for C functions | ||
492 | */ | ||
493 | l_sinline int precallC (lua_State *L, StkId func, int nresults, | ||
494 | lua_CFunction f) { | ||
495 | int n; /* number of returns */ | ||
496 | CallInfo *ci; | ||
497 | checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | ||
498 | L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, | ||
499 | L->top + LUA_MINSTACK); | ||
500 | lua_assert(ci->top <= L->stack_last); | ||
501 | if (l_unlikely(L->hookmask & LUA_MASKCALL)) { | ||
502 | int narg = cast_int(L->top - func) - 1; | ||
503 | luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); | ||
504 | } | ||
505 | lua_unlock(L); | ||
506 | n = (*f)(L); /* do the actual call */ | ||
507 | lua_lock(L); | ||
508 | api_checknelems(L, n); | ||
509 | luaD_poscall(L, ci, n); | ||
510 | return n; | ||
511 | } | ||
512 | |||
513 | |||
514 | /* | ||
515 | ** Prepare a function for a tail call, building its call info on top | ||
516 | ** of the current call info. 'narg1' is the number of arguments plus 1 | ||
517 | ** (so that it includes the function itself). Return the number of | ||
518 | ** results, if it was a C function, or -1 for a Lua function. | ||
519 | */ | ||
520 | int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, | ||
521 | int narg1, int delta) { | ||
522 | retry: | ||
523 | switch (ttypetag(s2v(func))) { | ||
524 | case LUA_VCCL: /* C closure */ | ||
525 | return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f); | ||
526 | case LUA_VLCF: /* light C function */ | ||
527 | return precallC(L, func, LUA_MULTRET, fvalue(s2v(func))); | ||
528 | case LUA_VLCL: { /* Lua function */ | ||
529 | Proto *p = clLvalue(s2v(func))->p; | ||
530 | int fsize = p->maxstacksize; /* frame size */ | ||
531 | int nfixparams = p->numparams; | ||
532 | int i; | ||
533 | ci->func -= delta; /* restore 'func' (if vararg) */ | ||
534 | for (i = 0; i < narg1; i++) /* move down function and arguments */ | ||
535 | setobjs2s(L, ci->func + i, func + i); | ||
536 | checkstackGC(L, fsize); | ||
537 | func = ci->func; /* moved-down function */ | ||
538 | for (; narg1 <= nfixparams; narg1++) | ||
539 | setnilvalue(s2v(func + narg1)); /* complete missing arguments */ | ||
540 | ci->top = func + 1 + fsize; /* top for new function */ | ||
541 | lua_assert(ci->top <= L->stack_last); | ||
542 | ci->u.l.savedpc = p->code; /* starting point */ | ||
543 | ci->callstatus |= CIST_TAIL; | ||
544 | L->top = func + narg1; /* set top */ | ||
545 | return -1; | ||
546 | } | ||
547 | default: { /* not a function */ | ||
548 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | ||
549 | /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ | ||
550 | narg1++; | ||
551 | goto retry; /* try again */ | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | |||
556 | |||
557 | /* | ||
514 | ** Prepares the call to a function (C or Lua). For C functions, also do | 558 | ** Prepares the call to a function (C or Lua). For C functions, also do |
515 | ** the call. The function to be called is at '*func'. The arguments | 559 | ** the call. The function to be called is at '*func'. The arguments |
516 | ** are on the stack, right after the function. Returns the CallInfo | 560 | ** are on the stack, right after the function. Returns the CallInfo |
@@ -519,32 +563,14 @@ l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, | |||
519 | ** original function position. | 563 | ** original function position. |
520 | */ | 564 | */ |
521 | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { | 565 | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { |
522 | lua_CFunction f; | ||
523 | retry: | 566 | retry: |
524 | switch (ttypetag(s2v(func))) { | 567 | switch (ttypetag(s2v(func))) { |
525 | case LUA_VCCL: /* C closure */ | 568 | case LUA_VCCL: /* C closure */ |
526 | f = clCvalue(s2v(func))->f; | 569 | precallC(L, func, nresults, clCvalue(s2v(func))->f); |
527 | goto Cfunc; | 570 | return NULL; |
528 | case LUA_VLCF: /* light C function */ | 571 | case LUA_VLCF: /* light C function */ |
529 | f = fvalue(s2v(func)); | 572 | precallC(L, func, nresults, fvalue(s2v(func))); |
530 | Cfunc: { | ||
531 | int n; /* number of returns */ | ||
532 | CallInfo *ci; | ||
533 | checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | ||
534 | L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, | ||
535 | L->top + LUA_MINSTACK); | ||
536 | lua_assert(ci->top <= L->stack_last); | ||
537 | if (l_unlikely(L->hookmask & LUA_MASKCALL)) { | ||
538 | int narg = cast_int(L->top - func) - 1; | ||
539 | luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); | ||
540 | } | ||
541 | lua_unlock(L); | ||
542 | n = (*f)(L); /* do the actual call */ | ||
543 | lua_lock(L); | ||
544 | api_checknelems(L, n); | ||
545 | luaD_poscall(L, ci, n); | ||
546 | return NULL; | 573 | return NULL; |
547 | } | ||
548 | case LUA_VLCL: { /* Lua function */ | 574 | case LUA_VLCL: { /* Lua function */ |
549 | CallInfo *ci; | 575 | CallInfo *ci; |
550 | Proto *p = clLvalue(s2v(func))->p; | 576 | Proto *p = clLvalue(s2v(func))->p; |
@@ -561,6 +587,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { | |||
561 | } | 587 | } |
562 | default: { /* not a function */ | 588 | default: { /* not a function */ |
563 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | 589 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ |
590 | /* return luaD_precall(L, func, nresults); */ | ||
564 | goto retry; /* try again with metamethod */ | 591 | goto retry; /* try again with metamethod */ |
565 | } | 592 | } |
566 | } | 593 | } |
@@ -733,11 +760,10 @@ static void resume (lua_State *L, void *ud) { | |||
733 | StkId firstArg = L->top - n; /* first argument */ | 760 | StkId firstArg = L->top - n; /* first argument */ |
734 | CallInfo *ci = L->ci; | 761 | CallInfo *ci = L->ci; |
735 | if (L->status == LUA_OK) /* starting a coroutine? */ | 762 | if (L->status == LUA_OK) /* starting a coroutine? */ |
736 | ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ | 763 | ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ |
737 | else { /* resuming from previous yield */ | 764 | else { /* resuming from previous yield */ |
738 | lua_assert(L->status == LUA_YIELD); | 765 | lua_assert(L->status == LUA_YIELD); |
739 | L->status = LUA_OK; /* mark that it is running (again) */ | 766 | L->status = LUA_OK; /* mark that it is running (again) */ |
740 | luaE_incCstack(L); /* control the C stack */ | ||
741 | if (isLua(ci)) { /* yielded inside a hook? */ | 767 | if (isLua(ci)) { /* yielded inside a hook? */ |
742 | L->top = firstArg; /* discard arguments */ | 768 | L->top = firstArg; /* discard arguments */ |
743 | luaV_execute(L, ci); /* just continue running Lua code */ | 769 | luaV_execute(L, ci); /* just continue running Lua code */ |
@@ -788,6 +814,9 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
788 | else if (L->status != LUA_YIELD) /* ended with errors? */ | 814 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
789 | return resume_error(L, "cannot resume dead coroutine", nargs); | 815 | return resume_error(L, "cannot resume dead coroutine", nargs); |
790 | L->nCcalls = (from) ? getCcalls(from) : 0; | 816 | L->nCcalls = (from) ? getCcalls(from) : 0; |
817 | if (getCcalls(L) >= LUAI_MAXCCALLS) | ||
818 | return resume_error(L, "C stack overflow", nargs); | ||
819 | L->nCcalls++; | ||
791 | luai_userstateresume(L, nargs); | 820 | luai_userstateresume(L, nargs); |
792 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 821 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
793 | status = luaD_rawrunprotected(L, resume, &nargs); | 822 | status = luaD_rawrunprotected(L, resume, &nargs); |