simpler implementation for generic reader

This commit is contained in:
Roberto Ierusalimschy
2004-09-03 10:16:48 -03:00
parent 9c34e23214
commit 79fc7dea43

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lbaselib.c,v 1.155 2004/08/30 15:28:32 roberto Exp roberto $ ** $Id: lbaselib.c,v 1.156 2004/08/30 18:35:14 roberto Exp roberto $
** Basic library ** Basic library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -273,25 +273,25 @@ static int luaB_loadfile (lua_State *L) {
} }
struct Aux_load { /*
int func; ** Reader for generic `load' function: `lua_load' uses the
int res; ** stack for internal stuff, so the reader cannot change the
}; ** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) { static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
struct Aux_load *al = (struct Aux_load *)ud; luaL_checkstack(L, 2, "too many nested functions");
luaL_unref(L, al->res, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); /* get function */
lua_getref(L, al->func); lua_call(L, 0, 1); /* call it */
lua_call(L, 0, 1);
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
*size = 0; *size = 0;
return NULL; return NULL;
} }
else if (lua_isstring(L, -1)) { else if (lua_isstring(L, -1)) {
const char *res = lua_tostring(L, -1); const char *res;
*size = lua_strlen(L, -1); lua_replace(L, 3); /* save string in a reserved stack slot */
al->res = luaL_ref(L, LUA_REGISTRYINDEX); res = lua_tostring(L, 3);
*size = lua_strlen(L, 3);
return res; return res;
} }
else luaL_error(L, "reader function must return a string"); else luaL_error(L, "reader function must return a string");
@@ -300,16 +300,11 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
static int luaB_load (lua_State *L) { static int luaB_load (lua_State *L) {
struct Aux_load al;
int status; int status;
const char *cname = luaL_optstring(L, 2, "=(load)"); const char *cname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION); luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1); lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
al.func = luaL_ref(L, LUA_REGISTRYINDEX); status = lua_load(L, generic_reader, NULL, cname);
al.res = LUA_REFNIL;
status = lua_load(L, generic_reader, &al, cname);
luaL_unref(L, al.func, LUA_REGISTRYINDEX);
luaL_unref(L, al.res, LUA_REGISTRYINDEX);
return load_aux(L, status); return load_aux(L, status);
} }