diff options
| -rwxr-xr-x | all | 2 | ||||
| -rw-r--r-- | ldblib.c | 5 | ||||
| -rw-r--r-- | ldo.c | 52 | ||||
| -rw-r--r-- | llimits.h | 11 | ||||
| -rw-r--r-- | lparser.c | 6 | ||||
| -rw-r--r-- | lstate.c | 45 | ||||
| -rw-r--r-- | lstate.h | 56 | ||||
| -rw-r--r-- | luaconf.h | 15 | ||||
| -rw-r--r-- | lvm.c | 6 | ||||
| -rw-r--r-- | manual/manual.of | 72 | ||||
| -rw-r--r-- | testes/cstack.lua | 137 | ||||
| -rw-r--r-- | testes/errors.lua | 3 |
12 files changed, 127 insertions, 283 deletions
| @@ -1,7 +1,7 @@ | |||
| 1 | make -s -j | 1 | make -s -j |
| 2 | cd testes/libs; make -s | 2 | cd testes/libs; make -s |
| 3 | cd .. # back to directory 'testes' | 3 | cd .. # back to directory 'testes' |
| 4 | ulimit -S -s 2000 | 4 | ulimit -S -s 1000 |
| 5 | if { ../lua -W all.lua; } then | 5 | if { ../lua -W all.lua; } then |
| 6 | echo -e "\n\n final OK!!!!\n\n" | 6 | echo -e "\n\n final OK!!!!\n\n" |
| 7 | else | 7 | else |
| @@ -440,10 +440,7 @@ static int db_traceback (lua_State *L) { | |||
| 440 | static int db_setcstacklimit (lua_State *L) { | 440 | static int db_setcstacklimit (lua_State *L) { |
| 441 | int limit = (int)luaL_checkinteger(L, 1); | 441 | int limit = (int)luaL_checkinteger(L, 1); |
| 442 | int res = lua_setcstacklimit(L, limit); | 442 | int res = lua_setcstacklimit(L, limit); |
| 443 | if (res == 0) | 443 | lua_pushinteger(L, res); |
| 444 | lua_pushboolean(L, 0); | ||
| 445 | else | ||
| 446 | lua_pushinteger(L, res); | ||
| 447 | return 1; | 444 | return 1; |
| 448 | } | 445 | } |
| 449 | 446 | ||
| @@ -448,10 +448,11 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | |||
| 448 | 448 | ||
| 449 | 449 | ||
| 450 | /* | 450 | /* |
| 451 | ** Call a function (C or Lua). The function to be called is at *func. | 451 | ** Prepares the call to a function (C or Lua). For C functions, also do |
| 452 | ** The arguments are on the stack, right after the function. | 452 | ** the call. The function to be called is at '*func'. The arguments are |
| 453 | ** When returns, all the results are on the stack, starting at the original | 453 | ** on the stack, right after the function. Returns true if the call was |
| 454 | ** function position. | 454 | ** made (it was a C function). When returns true, all the results are |
| 455 | ** on the stack, starting at the original function position. | ||
| 455 | */ | 456 | */ |
| 456 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 457 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 457 | lua_CFunction f; | 458 | lua_CFunction f; |
| @@ -511,32 +512,34 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 511 | } | 512 | } |
| 512 | 513 | ||
| 513 | 514 | ||
| 514 | static void stackerror (lua_State *L) { | 515 | /* |
| 515 | if (getCcalls(L) == LUAI_MAXCCALLS) | 516 | ** Call a function (C or Lua). 'inc' can be 1 (increment number |
| 516 | luaG_runerror(L, "C stack overflow"); | 517 | ** of recursive invocations in the C stack) or nyci (the same plus |
| 517 | else if (getCcalls(L) >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | 518 | ** increment number of non-yieldable calls). |
| 518 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | 519 | */ |
| 519 | } | 520 | static void docall (lua_State *L, StkId func, int nResults, int inc) { |
| 520 | 521 | L->nCcalls += inc; | |
| 521 | |||
| 522 | void luaD_call (lua_State *L, StkId func, int nResults) { | ||
| 523 | L->nCcalls++; | ||
| 524 | if (getCcalls(L) >= LUAI_MAXCCALLS) | 522 | if (getCcalls(L) >= LUAI_MAXCCALLS) |
| 525 | stackerror(L); | 523 | luaE_checkcstack(L); |
| 526 | if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ | 524 | if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ |
| 527 | luaV_execute(L, L->ci); /* call it */ | 525 | luaV_execute(L, L->ci); /* call it */ |
| 528 | L->nCcalls--; | 526 | L->nCcalls -= inc; |
| 529 | } | 527 | } |
| 530 | 528 | ||
| 531 | 529 | ||
| 530 | /* | ||
| 531 | ** External interface for 'docall' | ||
| 532 | */ | ||
| 533 | void luaD_call (lua_State *L, StkId func, int nResults) { | ||
| 534 | return docall(L, func, nResults, 1); | ||
| 535 | } | ||
| 536 | |||
| 532 | 537 | ||
| 533 | /* | 538 | /* |
| 534 | ** Similar to 'luaD_call', but does not allow yields during the call. | 539 | ** Similar to 'luaD_call', but does not allow yields during the call. |
| 535 | */ | 540 | */ |
| 536 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | 541 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { |
| 537 | incnny(L); | 542 | return docall(L, func, nResults, nyci); |
| 538 | luaD_call(L, func, nResults); | ||
| 539 | decnny(L); | ||
| 540 | } | 543 | } |
| 541 | 544 | ||
| 542 | 545 | ||
| @@ -650,13 +653,12 @@ static void resume (lua_State *L, void *ud) { | |||
| 650 | int n = *(cast(int*, ud)); /* number of arguments */ | 653 | int n = *(cast(int*, ud)); /* number of arguments */ |
| 651 | StkId firstArg = L->top - n; /* first argument */ | 654 | StkId firstArg = L->top - n; /* first argument */ |
| 652 | CallInfo *ci = L->ci; | 655 | CallInfo *ci = L->ci; |
| 653 | if (L->status == LUA_OK) { /* starting a coroutine? */ | 656 | if (L->status == LUA_OK) /* starting a coroutine? */ |
| 654 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 657 | docall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ |
| 655 | luaV_execute(L, L->ci); /* call it */ | ||
| 656 | } | ||
| 657 | else { /* resuming from previous yield */ | 658 | else { /* resuming from previous yield */ |
| 658 | lua_assert(L->status == LUA_YIELD); | 659 | lua_assert(L->status == LUA_YIELD); |
| 659 | L->status = LUA_OK; /* mark that it is running (again) */ | 660 | L->status = LUA_OK; /* mark that it is running (again) */ |
| 661 | luaE_incCstack(L); /* control the C stack */ | ||
| 660 | if (isLua(ci)) /* yielded inside a hook? */ | 662 | if (isLua(ci)) /* yielded inside a hook? */ |
| 661 | luaV_execute(L, ci); /* just continue running Lua code */ | 663 | luaV_execute(L, ci); /* just continue running Lua code */ |
| 662 | else { /* 'common' yield */ | 664 | else { /* 'common' yield */ |
| @@ -684,9 +686,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
| 684 | } | 686 | } |
| 685 | else if (L->status != LUA_YIELD) /* ended with errors? */ | 687 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
| 686 | return resume_error(L, "cannot resume dead coroutine", nargs); | 688 | return resume_error(L, "cannot resume dead coroutine", nargs); |
| 687 | L->nCcalls = (from) ? getCcalls(from) + 1 : 1; | 689 | L->nCcalls = (from) ? getCcalls(from) : 0; |
| 688 | if (getCcalls(L) >= LUAI_MAXCCALLS) | ||
| 689 | return resume_error(L, "C stack overflow", nargs); | ||
| 690 | luai_userstateresume(L, nargs); | 690 | luai_userstateresume(L, nargs); |
| 691 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 691 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
| 692 | status = luaD_rawrunprotected(L, resume, &nargs); | 692 | status = luaD_rawrunprotected(L, resume, &nargs); |
| @@ -235,6 +235,17 @@ typedef l_uint32 Instruction; | |||
| 235 | 235 | ||
| 236 | 236 | ||
| 237 | /* | 237 | /* |
| 238 | ** Maximum depth for nested C calls, syntactical nested non-terminals, | ||
| 239 | ** and other features implemented through recursion in C. (Value must | ||
| 240 | ** fit in a 16-bit unsigned integer. It must also be compatible with | ||
| 241 | ** the size of the C stack.) | ||
| 242 | */ | ||
| 243 | #if !defined(LUAI_MAXCCALLS) | ||
| 244 | #define LUAI_MAXCCALLS 200 | ||
| 245 | #endif | ||
| 246 | |||
| 247 | |||
| 248 | /* | ||
| 238 | ** macros that are executed whenever program enters the Lua core | 249 | ** macros that are executed whenever program enters the Lua core |
| 239 | ** ('lua_lock') and leaves the core ('lua_unlock') | 250 | ** ('lua_lock') and leaves the core ('lua_unlock') |
| 240 | */ | 251 | */ |
| @@ -489,11 +489,7 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | |||
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | 491 | ||
| 492 | static void enterlevel (LexState *ls) { | 492 | #define enterlevel(ls) luaE_incCstack(ls->L) |
| 493 | lua_State *L = ls->L; | ||
| 494 | L->nCcalls++; | ||
| 495 | checklimit(ls->fs, getCcalls(L), LUAI_MAXCCALLS, "C levels"); | ||
| 496 | } | ||
| 497 | 493 | ||
| 498 | 494 | ||
| 499 | #define leavelevel(ls) ((ls)->L->nCcalls--) | 495 | #define leavelevel(ls) ((ls)->L->nCcalls--) |
| @@ -97,25 +97,8 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
| 97 | 97 | ||
| 98 | 98 | ||
| 99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { | 99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { |
| 100 | global_State *g = G(L); | 100 | UNUSED(L); UNUSED(limit); |
| 101 | int ccalls; | 101 | return LUAI_MAXCCALLS; /* warning?? */ |
| 102 | luaE_freeCI(L); /* release unused CIs */ | ||
| 103 | ccalls = getCcalls(L); | ||
| 104 | if (limit >= 40000) | ||
| 105 | return 0; /* out of bounds */ | ||
| 106 | limit += CSTACKERR; | ||
| 107 | if (L != g-> mainthread) | ||
| 108 | return 0; /* only main thread can change the C stack */ | ||
| 109 | else if (ccalls <= CSTACKERR) | ||
| 110 | return 0; /* handling overflow */ | ||
| 111 | else { | ||
| 112 | int diff = limit - g->Cstacklimit; | ||
| 113 | if (ccalls + diff <= CSTACKERR) | ||
| 114 | return 0; /* new limit would cause an overflow */ | ||
| 115 | g->Cstacklimit = limit; /* set new limit */ | ||
| 116 | L->nCcalls += diff; /* correct 'nCcalls' */ | ||
| 117 | return limit - diff - CSTACKERR; /* success; return previous limit */ | ||
| 118 | } | ||
| 119 | } | 102 | } |
| 120 | 103 | ||
| 121 | 104 | ||
| @@ -172,6 +155,28 @@ void luaE_shrinkCI (lua_State *L) { | |||
| 172 | } | 155 | } |
| 173 | 156 | ||
| 174 | 157 | ||
| 158 | /* | ||
| 159 | ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. | ||
| 160 | ** If equal, raises an overflow error. If value is larger than | ||
| 161 | ** LUAI_MAXCCALLS (which means it is handling an overflow) but | ||
| 162 | ** not much larger, does not report an error (to allow overflow | ||
| 163 | ** handling to work). | ||
| 164 | */ | ||
| 165 | void luaE_checkcstack (lua_State *L) { | ||
| 166 | if (getCcalls(L) == LUAI_MAXCCALLS) | ||
| 167 | luaG_runerror(L, "C stack overflow"); | ||
| 168 | else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) | ||
| 169 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | ||
| 170 | } | ||
| 171 | |||
| 172 | |||
| 173 | LUAI_FUNC void luaE_incCstack (lua_State *L) { | ||
| 174 | L->nCcalls++; | ||
| 175 | if (getCcalls(L) >= LUAI_MAXCCALLS) | ||
| 176 | luaE_checkcstack(L); | ||
| 177 | } | ||
| 178 | |||
| 179 | |||
| 175 | static void stack_init (lua_State *L1, lua_State *L) { | 180 | static void stack_init (lua_State *L1, lua_State *L) { |
| 176 | int i; CallInfo *ci; | 181 | int i; CallInfo *ci; |
| 177 | /* initialize stack array */ | 182 | /* initialize stack array */ |
| @@ -357,7 +362,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 357 | preinit_thread(L, g); | 362 | preinit_thread(L, g); |
| 358 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ | 363 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ |
| 359 | L->next = NULL; | 364 | L->next = NULL; |
| 360 | g->Cstacklimit = L->nCcalls = 0; | 365 | L->nCcalls = 0; |
| 361 | incnny(L); /* main thread is always non yieldable */ | 366 | incnny(L); /* main thread is always non yieldable */ |
| 362 | g->frealloc = f; | 367 | g->frealloc = f; |
| 363 | g->ud = ud; | 368 | g->ud = ud; |
| @@ -87,48 +87,12 @@ | |||
| 87 | 87 | ||
| 88 | 88 | ||
| 89 | /* | 89 | /* |
| 90 | ** About 'nCcalls': each thread in Lua (a lua_State) keeps a count of | 90 | ** About 'nCcalls': This count has two parts: the lower 16 bits counts |
| 91 | ** how many "C calls" it still can do in the C stack, to avoid C-stack | 91 | ** the number of recursive invocations in the C stack; the higher |
| 92 | ** overflow. This count is very rough approximation; it considers only | 92 | ** 16 bits counts the number of non-yieldable calls in the stack. |
| 93 | ** recursive functions inside the interpreter, as non-recursive calls | 93 | ** (They are together so that we can change and save both with one |
| 94 | ** can be considered using a fixed (although unknown) amount of stack | 94 | ** instruction.) |
| 95 | ** space. | ||
| 96 | ** | ||
| 97 | ** The count has two parts: the lower part is the count itself; the | ||
| 98 | ** higher part counts the number of non-yieldable calls in the stack. | ||
| 99 | ** (They are together so that we can change both with one instruction.) | ||
| 100 | ** | ||
| 101 | ** Because calls to external C functions can use an unknown amount | ||
| 102 | ** of space (e.g., functions using an auxiliary buffer), calls | ||
| 103 | ** to these functions add more than one to the count (see CSTACKCF). | ||
| 104 | ** | ||
| 105 | ** The proper count excludes the number of CallInfo structures allocated | ||
| 106 | ** by Lua, as a kind of "potential" calls. So, when Lua calls a function | ||
| 107 | ** (and "consumes" one CallInfo), it needs neither to decrement nor to | ||
| 108 | ** check 'nCcalls', as its use of C stack is already accounted for. | ||
| 109 | */ | ||
| 110 | |||
| 111 | /* number of "C stack slots" used by an external C function */ | ||
| 112 | #define CSTACKCF 10 | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | ** The C-stack size is sliced in the following zones: | ||
| 117 | ** - larger than CSTACKERR: normal stack; | ||
| 118 | ** - [CSTACKMARK, CSTACKERR]: buffer zone to signal a stack overflow; | ||
| 119 | ** - [CSTACKCF, CSTACKERRMARK]: error-handling zone; | ||
| 120 | ** - below CSTACKERRMARK: buffer zone to signal overflow during overflow; | ||
| 121 | ** (Because the counter can be decremented CSTACKCF at once, we need | ||
| 122 | ** the so called "buffer zones", with at least that size, to properly | ||
| 123 | ** detect a change from one zone to the next.) | ||
| 124 | */ | 95 | */ |
| 125 | #define CSTACKERR (8 * CSTACKCF) | ||
| 126 | #define CSTACKMARK (CSTACKERR - (CSTACKCF + 2)) | ||
| 127 | #define CSTACKERRMARK (CSTACKCF + 2) | ||
| 128 | |||
| 129 | |||
| 130 | /* initial limit for the C-stack of threads */ | ||
| 131 | #define CSTACKTHREAD (2 * CSTACKERR) | ||
| 132 | 96 | ||
| 133 | 97 | ||
| 134 | /* true if this thread does not have non-yieldable calls in the stack */ | 98 | /* true if this thread does not have non-yieldable calls in the stack */ |
| @@ -144,7 +108,8 @@ | |||
| 144 | /* Decrement the number of non-yieldable calls */ | 108 | /* Decrement the number of non-yieldable calls */ |
| 145 | #define decnny(L) ((L)->nCcalls -= 0x10000) | 109 | #define decnny(L) ((L)->nCcalls -= 0x10000) |
| 146 | 110 | ||
| 147 | 111 | /* Non-yieldable call increment */ | |
| 112 | #define nyci (0x10000 | 1) | ||
| 148 | 113 | ||
| 149 | 114 | ||
| 150 | 115 | ||
| @@ -290,7 +255,6 @@ typedef struct global_State { | |||
| 290 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ | 255 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ |
| 291 | lua_WarnFunction warnf; /* warning function */ | 256 | lua_WarnFunction warnf; /* warning function */ |
| 292 | void *ud_warn; /* auxiliary data to 'warnf' */ | 257 | void *ud_warn; /* auxiliary data to 'warnf' */ |
| 293 | unsigned int Cstacklimit; /* current limit for the C stack */ | ||
| 294 | } global_State; | 258 | } global_State; |
| 295 | 259 | ||
| 296 | 260 | ||
| @@ -314,7 +278,7 @@ struct lua_State { | |||
| 314 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | 278 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ |
| 315 | volatile lua_Hook hook; | 279 | volatile lua_Hook hook; |
| 316 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 280 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
| 317 | l_uint32 nCcalls; /* number of allowed nested C calls - 'nci' */ | 281 | l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ |
| 318 | int oldpc; /* last pc traced */ | 282 | int oldpc; /* last pc traced */ |
| 319 | int stacksize; | 283 | int stacksize; |
| 320 | int basehookcount; | 284 | int basehookcount; |
| @@ -383,11 +347,11 @@ LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | |||
| 383 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 347 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
| 384 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 348 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
| 385 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | 349 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); |
| 350 | LUAI_FUNC void luaE_checkcstack (lua_State *L); | ||
| 351 | LUAI_FUNC void luaE_incCstack (lua_State *L); | ||
| 386 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); | 352 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); |
| 387 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); | 353 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); |
| 388 | 354 | ||
| 389 | 355 | ||
| 390 | #define luaE_exitCcall(L) ((L)->nCcalls++) | ||
| 391 | |||
| 392 | #endif | 356 | #endif |
| 393 | 357 | ||
| @@ -36,21 +36,6 @@ | |||
| 36 | ** ===================================================================== | 36 | ** ===================================================================== |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | /* >>> move back to llimits.h | ||
| 40 | @@ LUAI_MAXCCALLS defines the maximum depth for nested calls and | ||
| 41 | ** also limits the maximum depth of other recursive algorithms in | ||
| 42 | ** the implementation, such as syntactic analysis. A value too | ||
| 43 | ** large may allow the interpreter to crash (C-stack overflow). | ||
| 44 | ** The default value seems ok for regular machines, but may be | ||
| 45 | ** too high for restricted hardware. | ||
| 46 | ** The test file 'cstack.lua' may help finding a good limit. | ||
| 47 | ** (It will crash with a limit too high.) | ||
| 48 | */ | ||
| 49 | #if !defined(LUAI_MAXCCALLS) | ||
| 50 | #define LUAI_MAXCCALLS 200 | ||
| 51 | #endif | ||
| 52 | |||
| 53 | |||
| 54 | /* | 39 | /* |
| 55 | @@ LUA_USE_C89 controls the use of non-ISO-C89 features. | 40 | @@ LUA_USE_C89 controls the use of non-ISO-C89 features. |
| 56 | ** Define it if you want Lua to avoid the use of a few C99 features | 41 | ** Define it if you want Lua to avoid the use of a few C99 features |
| @@ -1124,7 +1124,7 @@ void luaV_finishOp (lua_State *L) { | |||
| 1124 | 1124 | ||
| 1125 | 1125 | ||
| 1126 | void luaV_execute (lua_State *L, CallInfo *ci) { | 1126 | void luaV_execute (lua_State *L, CallInfo *ci) { |
| 1127 | const CallInfo *origci = ci; | 1127 | CallInfo * const origci = ci; |
| 1128 | LClosure *cl; | 1128 | LClosure *cl; |
| 1129 | TValue *k; | 1129 | TValue *k; |
| 1130 | StkId base; | 1130 | StkId base; |
| @@ -1624,7 +1624,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1624 | vmcase(OP_TAILCALL) { | 1624 | vmcase(OP_TAILCALL) { |
| 1625 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ | 1625 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ |
| 1626 | int nparams1 = GETARG_C(i); | 1626 | int nparams1 = GETARG_C(i); |
| 1627 | /* delat is virtual 'func' - real 'func' (vararg functions) */ | 1627 | /* delta is virtual 'func' - real 'func' (vararg functions) */ |
| 1628 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; | 1628 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; |
| 1629 | if (b != 0) | 1629 | if (b != 0) |
| 1630 | L->top = ra + b; | 1630 | L->top = ra + b; |
| @@ -1648,7 +1648,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1648 | updatetrap(ci); | 1648 | updatetrap(ci); |
| 1649 | updatestack(ci); /* stack may have been relocated */ | 1649 | updatestack(ci); /* stack may have been relocated */ |
| 1650 | ci->func -= delta; | 1650 | ci->func -= delta; |
| 1651 | luaD_poscall(L, ci, cast_int(L->top - ra)); | 1651 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ |
| 1652 | goto ret; | 1652 | goto ret; |
| 1653 | } | 1653 | } |
| 1654 | ci->func -= delta; | 1654 | ci->func -= delta; |
diff --git a/manual/manual.of b/manual/manual.of index 8b34b5bd..86631bbc 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -2436,8 +2436,16 @@ When you interact with the Lua API, | |||
| 2436 | you are responsible for ensuring consistency. | 2436 | you are responsible for ensuring consistency. |
| 2437 | In particular, | 2437 | In particular, |
| 2438 | @emph{you are responsible for controlling stack overflow}. | 2438 | @emph{you are responsible for controlling stack overflow}. |
| 2439 | You can use the function @Lid{lua_checkstack} | 2439 | When you call any API function, |
| 2440 | to ensure that the stack has enough space for pushing new elements. | 2440 | you must ensure the stack has enough room to accommodate the results. |
| 2441 | |||
| 2442 | There is one exception to the above rule: | ||
| 2443 | When you call a Lua function | ||
| 2444 | without a fixed number of results @seeF{lua_call}, | ||
| 2445 | Lua ensures that the stack has enough space for all results. | ||
| 2446 | However, it does not ensure any extra space. | ||
| 2447 | So, before pushing anything on the stack after such a call | ||
| 2448 | you should use @Lid{lua_checkstack}. | ||
| 2441 | 2449 | ||
| 2442 | Whenever Lua calls C, | 2450 | Whenever Lua calls C, |
| 2443 | it ensures that the stack has space for | 2451 | it ensures that the stack has space for |
| @@ -2446,13 +2454,9 @@ that is, you can safely push up to @id{LUA_MINSTACK} values into it. | |||
| 2446 | @id{LUA_MINSTACK} is defined as 20, | 2454 | @id{LUA_MINSTACK} is defined as 20, |
| 2447 | so that usually you do not have to worry about stack space | 2455 | so that usually you do not have to worry about stack space |
| 2448 | unless your code has loops pushing elements onto the stack. | 2456 | unless your code has loops pushing elements onto the stack. |
| 2449 | 2457 | Whenever necessary, | |
| 2450 | When you call a Lua function | 2458 | you can use the function @Lid{lua_checkstack} |
| 2451 | without a fixed number of results @seeF{lua_call}, | 2459 | to ensure that the stack has enough space for pushing new elements. |
| 2452 | Lua ensures that the stack has enough space for all results, | ||
| 2453 | but it does not ensure any extra space. | ||
| 2454 | So, before pushing anything on the stack after such a call | ||
| 2455 | you should use @Lid{lua_checkstack}. | ||
| 2456 | 2460 | ||
| 2457 | } | 2461 | } |
| 2458 | 2462 | ||
| @@ -2695,7 +2699,7 @@ Therefore, if a @N{C function} @id{foo} calls an API function | |||
| 2695 | and this API function yields | 2699 | and this API function yields |
| 2696 | (directly or indirectly by calling another function that yields), | 2700 | (directly or indirectly by calling another function that yields), |
| 2697 | Lua cannot return to @id{foo} any more, | 2701 | Lua cannot return to @id{foo} any more, |
| 2698 | because the @id{longjmp} removes its frame from the C stack. | 2702 | because the @id{longjmp} removes its frame from the @N{C stack}. |
| 2699 | 2703 | ||
| 2700 | To avoid this kind of problem, | 2704 | To avoid this kind of problem, |
| 2701 | Lua raises an error whenever it tries to yield across an API call, | 2705 | Lua raises an error whenever it tries to yield across an API call, |
| @@ -2719,7 +2723,7 @@ After the thread resumes, | |||
| 2719 | it eventually will finish running the callee function. | 2723 | it eventually will finish running the callee function. |
| 2720 | However, | 2724 | However, |
| 2721 | the callee function cannot return to the original function, | 2725 | the callee function cannot return to the original function, |
| 2722 | because its frame in the C stack was destroyed by the yield. | 2726 | because its frame in the @N{C stack} was destroyed by the yield. |
| 2723 | Instead, Lua calls a @def{continuation function}, | 2727 | Instead, Lua calls a @def{continuation function}, |
| 2724 | which was given as an argument to the callee function. | 2728 | which was given as an argument to the callee function. |
| 2725 | As the name implies, | 2729 | As the name implies, |
| @@ -2841,7 +2845,7 @@ and therefore may raise any errors. | |||
| 2841 | 2845 | ||
| 2842 | Converts the @x{acceptable index} @id{idx} | 2846 | Converts the @x{acceptable index} @id{idx} |
| 2843 | into an equivalent @x{absolute index} | 2847 | into an equivalent @x{absolute index} |
| 2844 | (that is, one that does not depend on the stack top). | 2848 | (that is, one that does not depend on the stack size). |
| 2845 | 2849 | ||
| 2846 | } | 2850 | } |
| 2847 | 2851 | ||
| @@ -4340,7 +4344,7 @@ as if it was already marked. | |||
| 4340 | Note that, both in case of errors and of a regular return, | 4344 | Note that, both in case of errors and of a regular return, |
| 4341 | by the time the @idx{__close} metamethod runs, | 4345 | by the time the @idx{__close} metamethod runs, |
| 4342 | the @N{C stack} was already unwound, | 4346 | the @N{C stack} was already unwound, |
| 4343 | so that any automatic C variable declared in the calling function | 4347 | so that any automatic @N{C variable} declared in the calling function |
| 4344 | will be out of scope. | 4348 | will be out of scope. |
| 4345 | 4349 | ||
| 4346 | } | 4350 | } |
| @@ -4955,20 +4959,6 @@ calling @Lid{lua_yield} with @id{nresults} equal to zero | |||
| 4955 | 4959 | ||
| 4956 | } | 4960 | } |
| 4957 | 4961 | ||
| 4958 | @APIEntry{int (lua_setcstacklimit) (lua_State *L, unsigned int limit);| | ||
| 4959 | @apii{0,0,-} | ||
| 4960 | |||
| 4961 | Sets a new limit for the C stack. | ||
| 4962 | This limit controls how deeply nested calls can go in Lua, | ||
| 4963 | with the intent of avoiding a stack overflow. | ||
| 4964 | Returns the old limit in case of success, | ||
| 4965 | or zero in case of error. | ||
| 4966 | For more details about this function, | ||
| 4967 | see @Lid{debug.setcstacklimit}, | ||
| 4968 | its equivalent in the standard library. | ||
| 4969 | |||
| 4970 | } | ||
| 4971 | |||
| 4972 | @APIEntry{void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);| | 4962 | @APIEntry{void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);| |
| 4973 | @apii{0,0,-} | 4963 | @apii{0,0,-} |
| 4974 | 4964 | ||
| @@ -8756,34 +8746,6 @@ to the userdata @id{u} plus a boolean, | |||
| 8756 | 8746 | ||
| 8757 | } | 8747 | } |
| 8758 | 8748 | ||
| 8759 | @LibEntry{debug.setcstacklimit (limit)| | ||
| 8760 | |||
| 8761 | Sets a new limit for the C stack. | ||
| 8762 | This limit controls how deeply nested calls can go in Lua, | ||
| 8763 | with the intent of avoiding a stack overflow. | ||
| 8764 | A limit too small restricts recursive calls pointlessly; | ||
| 8765 | a limit too large exposes the interpreter to stack-overflow crashes. | ||
| 8766 | Unfortunately, there is no way to know a priori | ||
| 8767 | the maximum safe limit for a platform. | ||
| 8768 | |||
| 8769 | Each call made from Lua code counts one unit. | ||
| 8770 | Other operations (e.g., calls made from C to Lua or resuming a coroutine) | ||
| 8771 | may have a higher cost. | ||
| 8772 | |||
| 8773 | This function has the following restrictions: | ||
| 8774 | @description{ | ||
| 8775 | @item{It can only be called from the main coroutine (thread);} | ||
| 8776 | @item{It cannot be called while handling a stack-overflow error;} | ||
| 8777 | @item{@id{limit} must be less than 40000;} | ||
| 8778 | @item{@id{limit} cannot be less than the amount of C stack in use.} | ||
| 8779 | } | ||
| 8780 | If a call does not respect some restriction, | ||
| 8781 | it returns a false value. | ||
| 8782 | Otherwise, | ||
| 8783 | the call returns the old limit. | ||
| 8784 | |||
| 8785 | } | ||
| 8786 | |||
| 8787 | @LibEntry{debug.sethook ([thread,] hook, mask [, count])| | 8749 | @LibEntry{debug.sethook ([thread,] hook, mask [, count])| |
| 8788 | 8750 | ||
| 8789 | Sets the given function as the debug hook. | 8751 | Sets the given function as the debug hook. |
diff --git a/testes/cstack.lua b/testes/cstack.lua index c1177f3b..5767adf6 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua | |||
| @@ -1,75 +1,29 @@ | |||
| 1 | -- $Id: testes/cstack.lua $ | 1 | -- $Id: testes/cstack.lua $ |
| 2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
| 3 | 3 | ||
| 4 | do return end | ||
| 5 | |||
| 6 | local debug = require "debug" | ||
| 7 | 4 | ||
| 8 | print"testing C-stack overflow detection" | 5 | print"testing C-stack overflow detection" |
| 9 | print"If this test crashes, see its file ('cstack.lua')" | ||
| 10 | 6 | ||
| 11 | -- Segmentation faults in these tests probably result from a C-stack | 7 | -- Segmentation faults in these tests probably result from a C-stack |
| 12 | -- overflow. To avoid these errors, you can use the function | 8 | -- overflow. To avoid these errors, you should set a smaller limit for |
| 13 | -- 'debug.setcstacklimit' to set a smaller limit for the use of | 9 | -- the use of C stack by Lua, by changing the constant 'LUAI_MAXCCALLS'. |
| 14 | -- C stack by Lua. After finding a reliable limit, you might want | ||
| 15 | -- to recompile Lua with this limit as the value for | ||
| 16 | -- the constant 'LUAI_MAXCCALLS', which defines the default limit. | ||
| 17 | -- (The default limit is printed by this test.) | ||
| 18 | -- Alternatively, you can ensure a larger stack for the program. | 10 | -- Alternatively, you can ensure a larger stack for the program. |
| 19 | 11 | ||
| 20 | -- For Linux, a limit up to 30_000 seems Ok. Windows cannot go much | ||
| 21 | -- higher than 2_000. | ||
| 22 | |||
| 23 | |||
| 24 | -- get and print original limit | ||
| 25 | local origlimit <const> = debug.setcstacklimit(400) | ||
| 26 | print("default stack limit: " .. origlimit) | ||
| 27 | |||
| 28 | |||
| 29 | -- Do the tests using the original limit. Or else you may want to change | ||
| 30 | -- 'currentlimit' to lower values to avoid a seg. fault or to higher | ||
| 31 | -- values to check whether they are reliable. | ||
| 32 | local currentlimit <const> = origlimit | ||
| 33 | debug.setcstacklimit(currentlimit) | ||
| 34 | print("current stack limit: " .. currentlimit) | ||
| 35 | |||
| 36 | 12 | ||
| 37 | local function checkerror (msg, f, ...) | 13 | local function checkerror (msg, f, ...) |
| 38 | local s, err = pcall(f, ...) | 14 | local s, err = pcall(f, ...) |
| 39 | assert(not s and string.find(err, msg)) | 15 | assert(not s and string.find(err, msg)) |
| 40 | end | 16 | end |
| 41 | 17 | ||
| 42 | -- auxiliary function to keep 'count' on the screen even if the program | ||
| 43 | -- crashes. | ||
| 44 | local count | ||
| 45 | local back = string.rep("\b", 8) | ||
| 46 | local function progress () | ||
| 47 | count = count + 1 | ||
| 48 | local n = string.format("%-8d", count) | ||
| 49 | io.stderr:write(back, n) -- erase previous value and write new one | ||
| 50 | end | ||
| 51 | |||
| 52 | |||
| 53 | do print("testing simple recursion:") | ||
| 54 | count = 0 | ||
| 55 | local function foo () | ||
| 56 | progress() | ||
| 57 | foo() -- do recursive calls until a stack error (or crash) | ||
| 58 | end | ||
| 59 | checkerror("stack overflow", foo) | ||
| 60 | print("\tfinal count: ", count) | ||
| 61 | end | ||
| 62 | |||
| 63 | |||
| 64 | do print("testing stack overflow in message handling") | 18 | do print("testing stack overflow in message handling") |
| 65 | count = 0 | 19 | local count = 0 |
| 66 | local function loop (x, y, z) | 20 | local function loop (x, y, z) |
| 67 | progress() | 21 | count = count + 1 |
| 68 | return 1 + loop(x, y, z) | 22 | return 1 + loop(x, y, z) |
| 69 | end | 23 | end |
| 70 | local res, msg = xpcall(loop, loop) | 24 | local res, msg = xpcall(loop, loop) |
| 71 | assert(msg == "error in error handling") | 25 | assert(msg == "error in error handling") |
| 72 | print("\tfinal count: ", count) | 26 | print("final count: ", count) |
| 73 | end | 27 | end |
| 74 | 28 | ||
| 75 | 29 | ||
| @@ -82,97 +36,66 @@ do print("testing recursion inside pattern matching") | |||
| 82 | end | 36 | end |
| 83 | local m = f(80) | 37 | local m = f(80) |
| 84 | assert(#m == 80) | 38 | assert(#m == 80) |
| 85 | checkerror("too complex", f, 200000) | 39 | checkerror("too complex", f, 2000) |
| 86 | end | 40 | end |
| 87 | 41 | ||
| 88 | 42 | ||
| 89 | do print("testing stack-overflow in recursive 'gsub'") | 43 | do print("testing stack-overflow in recursive 'gsub'") |
| 90 | count = 0 | 44 | local count = 0 |
| 91 | local function foo () | 45 | local function foo () |
| 92 | progress() | 46 | count = count + 1 |
| 93 | string.gsub("a", ".", foo) | 47 | string.gsub("a", ".", foo) |
| 94 | end | 48 | end |
| 95 | checkerror("stack overflow", foo) | 49 | checkerror("stack overflow", foo) |
| 96 | print("\tfinal count: ", count) | 50 | print("final count: ", count) |
| 97 | 51 | ||
| 98 | print("testing stack-overflow in recursive 'gsub' with metatables") | 52 | print("testing stack-overflow in recursive 'gsub' with metatables") |
| 99 | count = 0 | 53 | local count = 0 |
| 100 | local t = setmetatable({}, {__index = foo}) | 54 | local t = setmetatable({}, {__index = foo}) |
| 101 | foo = function () | 55 | foo = function () |
| 102 | count = count + 1 | 56 | count = count + 1 |
| 103 | progress(count) | ||
| 104 | string.gsub("a", ".", t) | 57 | string.gsub("a", ".", t) |
| 105 | end | 58 | end |
| 106 | checkerror("stack overflow", foo) | 59 | checkerror("stack overflow", foo) |
| 107 | print("\tfinal count: ", count) | 60 | print("final count: ", count) |
| 108 | end | 61 | end |
| 109 | 62 | ||
| 63 | |||
| 110 | do -- bug in 5.4.0 | 64 | do -- bug in 5.4.0 |
| 111 | print("testing limits in coroutines inside deep calls") | 65 | print("testing limits in coroutines inside deep calls") |
| 112 | count = 0 | 66 | local count = 0 |
| 113 | local lim = 1000 | 67 | local lim = 1000 |
| 114 | local function stack (n) | 68 | local function stack (n) |
| 115 | progress() | ||
| 116 | if n > 0 then return stack(n - 1) + 1 | 69 | if n > 0 then return stack(n - 1) + 1 |
| 117 | else coroutine.wrap(function () | 70 | else coroutine.wrap(function () |
| 71 | count = count + 1 | ||
| 118 | stack(lim) | 72 | stack(lim) |
| 119 | end)() | 73 | end)() |
| 120 | end | 74 | end |
| 121 | end | 75 | end |
| 122 | 76 | ||
| 123 | print(xpcall(stack, function () return "ok" end, lim)) | 77 | local st, msg = xpcall(stack, function () return "ok" end, lim) |
| 78 | assert(not st and msg == "ok") | ||
| 79 | print("final count: ", count) | ||
| 124 | end | 80 | end |
| 125 | 81 | ||
| 126 | 82 | ||
| 127 | do print("testing changes in C-stack limit") | 83 | do |
| 84 | print("nesting of resuming yielded coroutines") | ||
| 85 | local count = 0 | ||
| 128 | 86 | ||
| 129 | -- Just an alternative limit, different from the current one | 87 | local function body () |
| 130 | -- (smaller to avoid stack overflows) | 88 | coroutine.yield() |
| 131 | local alterlimit <const> = currentlimit * 8 // 10 | 89 | local f = coroutine.wrap(body) |
| 132 | 90 | f(); -- start new coroutine (will stop in previous yield) | |
| 133 | assert(not debug.setcstacklimit(0)) -- limit too small | 91 | count = count + 1 |
| 134 | assert(not debug.setcstacklimit(50000)) -- limit too large | 92 | f() -- call it recursively |
| 135 | local co = coroutine.wrap (function () | ||
| 136 | return debug.setcstacklimit(alterlimit) | ||
| 137 | end) | ||
| 138 | assert(not co()) -- cannot change C stack inside coroutine | ||
| 139 | |||
| 140 | local n | ||
| 141 | local function foo () n = n + 1; foo () end | ||
| 142 | |||
| 143 | local function check () | ||
| 144 | n = 0 | ||
| 145 | pcall(foo) | ||
| 146 | return n | ||
| 147 | end | 93 | end |
| 148 | 94 | ||
| 149 | -- set limit to 'alterlimit' | 95 | local f = coroutine.wrap(body) |
| 150 | assert(debug.setcstacklimit(alterlimit) == currentlimit) | 96 | f() |
| 151 | local limalter <const> = check() | 97 | assert(not pcall(f)) |
| 152 | -- set a very low limit (given that there are already several active | 98 | print("final count: ", count) |
| 153 | -- calls to arrive here) | ||
| 154 | local lowlimit <const> = 38 | ||
| 155 | assert(debug.setcstacklimit(lowlimit) == alterlimit) | ||
| 156 | -- usable limit is much lower, due to active calls | ||
| 157 | local actuallow = check() | ||
| 158 | assert(actuallow < lowlimit - 30) | ||
| 159 | -- now, add 'lowlimit' extra slots, which should all be available | ||
| 160 | assert(debug.setcstacklimit(lowlimit + lowlimit) == lowlimit) | ||
| 161 | local lim2 <const> = check() | ||
| 162 | assert(lim2 == actuallow + lowlimit) | ||
| 163 | |||
| 164 | |||
| 165 | -- 'setcstacklimit' works inside protected calls. (The new stack | ||
| 166 | -- limit is kept when 'pcall' returns.) | ||
| 167 | assert(pcall(function () | ||
| 168 | assert(debug.setcstacklimit(alterlimit) == lowlimit * 2) | ||
| 169 | assert(check() <= limalter) | ||
| 170 | end)) | ||
| 171 | |||
| 172 | assert(check() == limalter) | ||
| 173 | -- restore original limit | ||
| 174 | assert(debug.setcstacklimit(origlimit) == alterlimit) | ||
| 175 | end | 99 | end |
| 176 | 100 | ||
| 177 | |||
| 178 | print'OK' | 101 | print'OK' |
diff --git a/testes/errors.lua b/testes/errors.lua index 88918df7..f975b3dd 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
| @@ -532,7 +532,8 @@ local function testrep (init, rep, close, repc, finalresult) | |||
| 532 | end | 532 | end |
| 533 | s = init .. string.rep(rep, 500) | 533 | s = init .. string.rep(rep, 500) |
| 534 | local res, msg = load(s) -- 500 levels not ok | 534 | local res, msg = load(s) -- 500 levels not ok |
| 535 | assert(not res and string.find(msg, "too many")) | 535 | assert(not res and (string.find(msg, "too many") or |
| 536 | string.find(msg, "overflow"))) | ||
| 536 | end | 537 | end |
| 537 | 538 | ||
| 538 | testrep("local a; a", ",a", "= 1", ",1") -- multiple assignment | 539 | testrep("local a; a", ",a", "= 1", ",1") -- multiple assignment |
