aboutsummaryrefslogtreecommitdiff
path: root/lbaselib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lbaselib.c')
-rw-r--r--lbaselib.c84
1 files changed, 61 insertions, 23 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 3e18013e..80c4e3fa 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.221 2009/10/23 19:12:19 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.222 2009/11/09 18:55:17 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -276,13 +276,11 @@ static int luaB_loadfile (lua_State *L) {
276 276
277 277
278/* 278/*
279** Reader for generic `load' function: `lua_load' uses the 279** {======================================================
280** stack for internal stuff, so the reader cannot change the 280** Generic Read function
281** stack top. Instead, it keeps its resulting string in a 281** =======================================================
282** reserved slot inside the stack.
283*/ 282*/
284 283
285
286static const char *checkrights (lua_State *L, const char *mode, const char *s) { 284static const char *checkrights (lua_State *L, const char *mode, const char *s) {
287 if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) 285 if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0])
288 return lua_pushstring(L, "attempt to load a binary chunk"); 286 return lua_pushstring(L, "attempt to load a binary chunk");
@@ -292,24 +290,42 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) {
292} 290}
293 291
294 292
293/*
294** reserves a slot, above all arguments, to hold a copy of the returned
295** string to avoid it being collected while parsed
296*/
297#define RESERVEDSLOT 4
298
299
300/*
301** Reader for generic `load' function: `lua_load' uses the
302** stack for internal stuff, so the reader cannot change the
303** stack top. Instead, it keeps its resulting string in a
304** reserved slot inside the stack.
305*/
306typedef struct { /* reader state */
307 int f; /* position of reader function on stack */
308 const char *mode; /* allowed modes (binary/text) */
309} Readstat;
310
295static const char *generic_reader (lua_State *L, void *ud, size_t *size) { 311static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
296 const char *s; 312 const char *s;
297 const char **mode = (const char **)ud; 313 Readstat *stat = (Readstat *)ud;
298 luaL_checkstack(L, 2, "too many nested functions"); 314 luaL_checkstack(L, 2, "too many nested functions");
299 lua_pushvalue(L, 1); /* get function */ 315 lua_pushvalue(L, stat->f); /* get function */
300 lua_call(L, 0, 1); /* call it */ 316 lua_call(L, 0, 1); /* call it */
301 if (lua_isnil(L, -1)) { 317 if (lua_isnil(L, -1)) {
302 *size = 0; 318 *size = 0;
303 return NULL; 319 return NULL;
304 } 320 }
305 else if ((s = lua_tostring(L, -1)) != NULL) { 321 else if ((s = lua_tostring(L, -1)) != NULL) {
306 if (*mode != NULL) { /* first time? */ 322 if (stat->mode != NULL) { /* first time? */
307 s = checkrights(L, *mode, s); /* check whether chunk format is allowed */ 323 s = checkrights(L, stat->mode, s); /* check mode */
308 *mode = NULL; /* to avoid further checks */ 324 stat->mode = NULL; /* to avoid further checks */
309 if (s) luaL_error(L, s); 325 if (s) luaL_error(L, s);
310 } 326 }
311 lua_replace(L, 3); /* save string in a reserved stack slot */ 327 lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
312 return lua_tolstring(L, 3, size); 328 return lua_tolstring(L, RESERVEDSLOT, size);
313 } 329 }
314 else { 330 else {
315 luaL_error(L, "reader function must return a string"); 331 luaL_error(L, "reader function must return a string");
@@ -318,30 +334,51 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
318} 334}
319 335
320 336
321static int luaB_load (lua_State *L) { 337static int luaB_load_aux (lua_State *L, int farg) {
322 int status; 338 int status;
323 const char *s = lua_tostring(L, 1); 339 Readstat stat;
324 const char *mode = luaL_optstring(L, 3, "bt"); 340 const char *s = lua_tostring(L, farg);
341 stat.mode = luaL_optstring(L, farg + 2, "bt");
325 if (s != NULL) { /* loading a string? */ 342 if (s != NULL) { /* loading a string? */
326 const char *chunkname = luaL_optstring(L, 2, s); 343 const char *chunkname = luaL_optstring(L, farg + 1, s);
327 status = (checkrights(L, mode, s) != NULL) 344 status = (checkrights(L, stat.mode, s) != NULL)
328 || luaL_loadbuffer(L, s, lua_objlen(L, 1), chunkname); 345 || luaL_loadbuffer(L, s, lua_objlen(L, farg), chunkname);
329 } 346 }
330 else { /* loading from a reader function */ 347 else { /* loading from a reader function */
331 const char *chunkname = luaL_optstring(L, 2, "=(load)"); 348 const char *chunkname = luaL_optstring(L, farg + 1, "=(load)");
332 luaL_checktype(L, 1, LUA_TFUNCTION); 349 luaL_checktype(L, farg, LUA_TFUNCTION);
333 lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ 350 stat.f = farg;
334 status = lua_load(L, generic_reader, &mode, chunkname); 351 lua_settop(L, RESERVEDSLOT); /* create reserved slot */
352 status = lua_load(L, generic_reader, &stat, chunkname);
335 } 353 }
336 return load_aux(L, status); 354 return load_aux(L, status);
337} 355}
338 356
339 357
358static int luaB_load (lua_State *L) {
359 return luaB_load_aux(L, 1);
360}
361
362
363static int luaB_loadin (lua_State *L) {
364 int n;
365 luaL_checktype(L, 1, LUA_TTABLE);
366 n = luaB_load_aux(L, 2);
367 if (n == 1) { /* success? */
368 lua_pushvalue(L, 1); /* environment for loaded function */
369 lua_setfenv(L, -2);
370 }
371 return n;
372}
373
374
340static int luaB_loadstring (lua_State *L) { 375static int luaB_loadstring (lua_State *L) {
341 lua_settop(L, 2); 376 lua_settop(L, 2);
342 lua_pushliteral(L, "tb"); 377 lua_pushliteral(L, "tb");
343 return luaB_load(L); /* dostring(s, n) == load(s, n, "tb") */ 378 return luaB_load(L); /* dostring(s, n) == load(s, n, "tb") */
379
344} 380}
381/* }====================================================== */
345 382
346 383
347static int dofilecont (lua_State *L) { 384static int dofilecont (lua_State *L) {
@@ -481,6 +518,7 @@ static const luaL_Reg base_funcs[] = {
481 {"getmetatable", luaB_getmetatable}, 518 {"getmetatable", luaB_getmetatable},
482 {"loadfile", luaB_loadfile}, 519 {"loadfile", luaB_loadfile},
483 {"load", luaB_load}, 520 {"load", luaB_load},
521 {"loadin", luaB_loadin},
484 {"loadstring", luaB_loadstring}, 522 {"loadstring", luaB_loadstring},
485 {"next", luaB_next}, 523 {"next", luaB_next},
486 {"pcall", luaB_pcall}, 524 {"pcall", luaB_pcall},