diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-07-02 15:09:11 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-07-02 15:09:11 -0300 |
| commit | 3d5187f6e554d05883dbc0d7af8d9697d9f160b7 (patch) | |
| tree | a7cd2f226e16e26db11e49b5d616fe16828222b0 | |
| parent | 80ec81926c19ff638a65088bb3d5a55d20b55945 (diff) | |
| download | lua-3d5187f6e554d05883dbc0d7af8d9697d9f160b7.tar.gz lua-3d5187f6e554d05883dbc0d7af8d9697d9f160b7.tar.bz2 lua-3d5187f6e554d05883dbc0d7af8d9697d9f160b7.zip | |
`require' uses its private reference to `_LOADED' table
| -rw-r--r-- | lbaselib.c | 28 |
1 files changed, 14 insertions, 14 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.150 2004/06/29 16:58:17 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.151 2004/07/01 14:26:28 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 | */ |
| @@ -462,17 +462,12 @@ static int luaB_newproxy (lua_State *L) { | |||
| 462 | static int luaB_require (lua_State *L) { | 462 | static int luaB_require (lua_State *L) { |
| 463 | const char *name = luaL_checkstring(L, 1); | 463 | const char *name = luaL_checkstring(L, 1); |
| 464 | const char *fname; | 464 | const char *fname; |
| 465 | int loaded; | 465 | lua_getfield(L, lua_upvalueindex(1), name); |
| 466 | lua_getglobal(L, REQTAB); | ||
| 467 | loaded = lua_gettop(L); | ||
| 468 | if (!lua_istable(L, loaded)) | ||
| 469 | return luaL_error(L, "global `" REQTAB "' is not a table"); | ||
| 470 | lua_getfield(L, loaded, name); | ||
| 471 | if (lua_toboolean(L, -1)) /* is it there? */ | 466 | if (lua_toboolean(L, -1)) /* is it there? */ |
| 472 | return 1; /* package is already loaded; return its result */ | 467 | return 1; /* package is already loaded; return its result */ |
| 473 | /* else must load it; first mark it as loaded */ | 468 | /* else must load it; first mark it as loaded */ |
| 474 | lua_pushboolean(L, 1); | 469 | lua_pushboolean(L, 1); |
| 475 | lua_setfield(L, loaded, name); /* _LOADED[name] = true */ | 470 | lua_setfield(L, lua_upvalueindex(1), name); /* _LOADED[name] = true */ |
| 476 | fname = luaL_searchpath(L, name, NULL); | 471 | fname = luaL_searchpath(L, name, NULL); |
| 477 | if (fname == NULL || luaL_loadfile(L, fname) != 0) | 472 | if (fname == NULL || luaL_loadfile(L, fname) != 0) |
| 478 | return luaL_error(L, "error loading package `%s' (%s)", name, | 473 | return luaL_error(L, "error loading package `%s' (%s)", name, |
| @@ -480,8 +475,8 @@ static int luaB_require (lua_State *L) { | |||
| 480 | lua_pushvalue(L, 1); /* pass name as argument to module */ | 475 | lua_pushvalue(L, 1); /* pass name as argument to module */ |
| 481 | lua_call(L, 1, 1); /* run loaded module */ | 476 | lua_call(L, 1, 1); /* run loaded module */ |
| 482 | if (!lua_isnil(L, -1)) /* nil return? */ | 477 | if (!lua_isnil(L, -1)) /* nil return? */ |
| 483 | lua_setfield(L, loaded, name); | 478 | lua_setfield(L, lua_upvalueindex(1), name); |
| 484 | lua_getfield(L, loaded, name); /* return _LOADED[name] */ | 479 | lua_getfield(L, lua_upvalueindex(1), name); /* return _LOADED[name] */ |
| 485 | return 1; | 480 | return 1; |
| 486 | } | 481 | } |
| 487 | 482 | ||
| @@ -513,7 +508,6 @@ static const luaL_reg base_funcs[] = { | |||
| 513 | {"dofile", luaB_dofile}, | 508 | {"dofile", luaB_dofile}, |
| 514 | {"loadstring", luaB_loadstring}, | 509 | {"loadstring", luaB_loadstring}, |
| 515 | {"load", luaB_load}, | 510 | {"load", luaB_load}, |
| 516 | {"require", luaB_require}, | ||
| 517 | {NULL, NULL} | 511 | {NULL, NULL} |
| 518 | }; | 512 | }; |
| 519 | 513 | ||
| @@ -650,15 +644,21 @@ static void base_open (lua_State *L) { | |||
| 650 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ | 644 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ |
| 651 | lua_pushcclosure(L, luaB_newproxy, 1); | 645 | lua_pushcclosure(L, luaB_newproxy, 1); |
| 652 | lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ | 646 | lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ |
| 653 | lua_setfield(L, -1, "_G"); /* set global _G */ | 647 | /* `require' needs a table to keep loaded chunks */ |
| 648 | lua_newtable(L); | ||
| 649 | lua_pushvalue(L, -1); | ||
| 650 | lua_setglobal(L, REQTAB); | ||
| 651 | lua_pushcclosure(L, luaB_require, 1); | ||
| 652 | lua_setfield(L, -2, "require"); | ||
| 653 | /* set global _G */ | ||
| 654 | lua_pushvalue(L, -1); | ||
| 655 | lua_setfield(L, -2, "_G"); | ||
| 654 | } | 656 | } |
| 655 | 657 | ||
| 656 | 658 | ||
| 657 | LUALIB_API int luaopen_base (lua_State *L) { | 659 | LUALIB_API int luaopen_base (lua_State *L) { |
| 658 | base_open(L); | 660 | base_open(L); |
| 659 | luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); | 661 | luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); |
| 660 | lua_newtable(L); | ||
| 661 | lua_setglobal(L, REQTAB); | ||
| 662 | return 2; | 662 | return 2; |
| 663 | } | 663 | } |
| 664 | 664 | ||
