aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-04-23 17:58:55 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-04-23 17:58:55 -0300
commit4c5d5063a54c0088729b16fb25a333f0f9f836b0 (patch)
tree66cb68ffbc68a08b3327dcaf73404c7a2e7b412d
parent3228a97c6a953dcf397944161bb64b12f1ff5384 (diff)
downloadlua-4c5d5063a54c0088729b16fb25a333f0f9f836b0.tar.gz
lua-4c5d5063a54c0088729b16fb25a333f0f9f836b0.tar.bz2
lua-4c5d5063a54c0088729b16fb25a333f0f9f836b0.zip
'load' reader function doesn't need to preserve stack
-rw-r--r--lbaselib.c27
1 files changed, 9 insertions, 18 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 47f7bdec..3962ea53 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -366,33 +366,24 @@ static int luaB_loadfile (lua_State *L) {
366 366
367 367
368/* 368/*
369** reserved slot, above all arguments, to hold a copy of the returned 369** Reader for generic 'load' function.
370** string to avoid it being collected while parsed. 'load' has four
371** optional arguments (chunk, source name, mode, and environment).
372*/
373#define RESERVEDSLOT 5
374
375
376/*
377** Reader for generic 'load' function: 'lua_load' uses the
378** stack for internal stuff, so the reader cannot change the
379** stack top. Instead, it keeps its resulting string in a
380** reserved slot inside the stack.
381*/ 370*/
382static const char *generic_reader (lua_State *L, void *ud, size_t *size) { 371static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
383 (void)(ud); /* not used */ 372 int *firstcall = cast(int *, ud);
384 luaL_checkstack(L, 2, "too many nested functions"); 373 luaL_checkstack(L, 2, "too many nested functions");
374 if (*firstcall)
375 *firstcall = 0;
376 else
377 lua_pop(L, 1); /* remove previous result */
385 lua_pushvalue(L, 1); /* get function */ 378 lua_pushvalue(L, 1); /* get function */
386 lua_call(L, 0, 1); /* call it */ 379 lua_call(L, 0, 1); /* call it */
387 if (lua_isnil(L, -1)) { 380 if (lua_isnil(L, -1)) {
388 lua_pop(L, 1); /* pop result */
389 *size = 0; 381 *size = 0;
390 return NULL; 382 return NULL;
391 } 383 }
392 else if (l_unlikely(!lua_isstring(L, -1))) 384 else if (l_unlikely(!lua_isstring(L, -1)))
393 luaL_error(L, "reader function must return a string"); 385 luaL_error(L, "reader function must return a string");
394 lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ 386 return lua_tolstring(L, -1, size);
395 return lua_tolstring(L, RESERVEDSLOT, size);
396} 387}
397 388
398 389
@@ -407,10 +398,10 @@ static int luaB_load (lua_State *L) {
407 status = luaL_loadbufferx(L, s, l, chunkname, mode); 398 status = luaL_loadbufferx(L, s, l, chunkname, mode);
408 } 399 }
409 else { /* loading from a reader function */ 400 else { /* loading from a reader function */
401 int firstcall = 1; /* userdata for generic_reader */
410 const char *chunkname = luaL_optstring(L, 2, "=(load)"); 402 const char *chunkname = luaL_optstring(L, 2, "=(load)");
411 luaL_checktype(L, 1, LUA_TFUNCTION); 403 luaL_checktype(L, 1, LUA_TFUNCTION);
412 lua_settop(L, RESERVEDSLOT); /* create reserved slot */ 404 status = lua_load(L, generic_reader, &firstcall, chunkname, mode);
413 status = lua_load(L, generic_reader, NULL, chunkname, mode);
414 } 405 }
415 return load_aux(L, status, env); 406 return load_aux(L, status, env);
416} 407}