diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2026-01-11 15:36:03 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2026-01-11 15:36:03 -0300 |
| commit | 2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded (patch) | |
| tree | a99a8361664b0adda83186f04e2e9c98afd86b44 /ldo.c | |
| parent | 5cfc725a8b61a6f96c7324f60ac26739315095ba (diff) | |
| download | lua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.tar.gz lua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.tar.bz2 lua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.zip | |
Before calling a finalizer, Lua not only checks stack limits, but
actually ensures that a minimum number of slots are already allocated
for the call. (If it cannot ensure that, it postpones the finalizer.)
That avoids finalizers not running due to memory errors that the
programmer cannot control.
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 20 |
1 files changed, 14 insertions, 6 deletions
| @@ -221,13 +221,21 @@ l_noret luaD_errerr (lua_State *L) { | |||
| 221 | 221 | ||
| 222 | 222 | ||
| 223 | /* | 223 | /* |
| 224 | ** Check whether stack has enough space to run a simple function (such | 224 | ** Check whether stacks have enough space to run a simple function (such |
| 225 | ** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack and | 225 | ** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two |
| 226 | ** 2 slots in the C stack. | 226 | ** available CallInfos, and two "slots" in the C stack. |
| 227 | */ | 227 | */ |
| 228 | int luaD_checkminstack (lua_State *L) { | 228 | int luaD_checkminstack (lua_State *L) { |
| 229 | return ((stacksize(L) < MAXSTACK - BASIC_STACK_SIZE) && | 229 | if (getCcalls(L) >= LUAI_MAXCCALLS - 2) |
| 230 | (getCcalls(L) < LUAI_MAXCCALLS - 2)); | 230 | return 0; /* not enough C-stack slots */ |
| 231 | if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL) | ||
| 232 | return 0; /* unable to allocate first ci */ | ||
| 233 | if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL) | ||
| 234 | return 0; /* unable to allocate second ci */ | ||
| 235 | if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE) | ||
| 236 | return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */ | ||
| 237 | else /* try to grow stack to a size with enough free slots */ | ||
| 238 | return luaD_growstack(L, BASIC_STACK_SIZE, 0); | ||
| 231 | } | 239 | } |
| 232 | 240 | ||
| 233 | 241 | ||
| @@ -616,7 +624,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { | |||
| 616 | 624 | ||
| 617 | 625 | ||
| 618 | 626 | ||
| 619 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) | 627 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1)) |
| 620 | 628 | ||
| 621 | 629 | ||
| 622 | /* | 630 | /* |
