diff --git a/linit.c b/linit.c index 675fb65f..140f6d75 100644 --- a/linit.c +++ b/linit.c @@ -21,12 +21,12 @@ /* -** Standard Libraries +** Standard Libraries. (Must be listed in the same ORDER of their +** respective constants LUA_K.) */ static const luaL_Reg stdlibs[] = { {LUA_GNAME, luaopen_base}, {LUA_LOADLIBNAME, luaopen_package}, - {LUA_COLIBNAME, luaopen_coroutine}, {LUA_DBLIBNAME, luaopen_debug}, {LUA_IOLIBNAME, luaopen_io}, @@ -35,30 +35,28 @@ static const luaL_Reg stdlibs[] = { {LUA_STRLIBNAME, luaopen_string}, {LUA_TABLIBNAME, luaopen_table}, {LUA_UTF8LIBNAME, luaopen_utf8}, - {NULL, NULL} }; /* -** require selected standard libraries and add the others to the -** preload table. +** require and preload selected standard libraries */ -LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) { - int mask = 1; +LUALIB_API void luaL_openselectedlibs (lua_State *L, int load, int preload) { + int mask; const luaL_Reg *lib; luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); - for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) { - if (what & mask) { /* selected? */ + for (lib = stdlibs, mask = 1; lib->name != NULL; lib++, mask <<= 1) { + if (load & mask) { /* selected? */ luaL_requiref(L, lib->name, lib->func, 1); /* require library */ lua_pop(L, 1); /* remove result from the stack */ } - else { /* add library to PRELOAD table */ + else if (preload & mask) { /* selected? */ lua_pushcfunction(L, lib->func); - lua_setfield(L, -2, lib->name); + lua_setfield(L, -2, lib->name); /* add library to PRELOAD table */ } } lua_assert((mask >> 1) == LUA_UTF8LIBK); - lua_pop(L, 1); // remove PRELOAD table + lua_pop(L, 1); /* remove PRELOAD table */ } diff --git a/ltests.c b/ltests.c index 6081aba6..59df7cad 100644 --- a/ltests.c +++ b/ltests.c @@ -1223,8 +1223,9 @@ static lua_State *getstate (lua_State *L) { static int loadlib (lua_State *L) { lua_State *L1 = getstate(L); - int what = luaL_checkinteger(L, 2); - luaL_openselectedlibs(L1, what); + int load = luaL_checkinteger(L, 2); + int preload = luaL_checkinteger(L, 3); + luaL_openselectedlibs(L1, load, preload); luaL_requiref(L1, "T", luaB_opentests, 0); lua_assert(lua_type(L1, -1) == LUA_TTABLE); /* 'requiref' should not reload module already loaded... */ diff --git a/lua.c b/lua.c index e574ec9b..6a9bb948 100644 --- a/lua.c +++ b/lua.c @@ -618,7 +618,7 @@ static void doREPL (lua_State *L) { /* }================================================================== */ #if !defined(luai_openlibs) -#define luai_openlibs(L) luaL_openlibs(L) +#define luai_openlibs(L) luaL_openselectedlibs(L, ~0, 0) #endif diff --git a/lualib.h b/lualib.h index e124cf1b..068f60ab 100644 --- a/lualib.h +++ b/lualib.h @@ -14,11 +14,11 @@ /* version suffix for environment variable names */ #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR -#define LUA_GK 1 +#define LUA_GLIBK 1 LUAMOD_API int (luaopen_base) (lua_State *L); #define LUA_LOADLIBNAME "package" -#define LUA_LOADLIBK (LUA_GK << 1) +#define LUA_LOADLIBK (LUA_GLIBK << 1) LUAMOD_API int (luaopen_package) (lua_State *L); @@ -56,10 +56,10 @@ LUAMOD_API int (luaopen_utf8) (lua_State *L); /* open selected libraries */ -LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what); +LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int load, int preload); /* open all libraries */ -#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0) +#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0, 0) #endif diff --git a/manual/2html b/manual/2html index 43fd8913..bada6ee0 100755 --- a/manual/2html +++ b/manual/2html @@ -358,7 +358,7 @@ item = function (s) local t, p = string.match(s, "^([^\n|]+)|()") if t then s = string.sub(s, p) - s = Tag.b(t..": ") .. s + s = Tag.b(t) ..": " .. s end return Tag.li(fixpara(s)) end, diff --git a/manual/manual.of b/manual/manual.of index cdd54f66..3181549d 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -664,7 +664,6 @@ Values equal to or less than 100 mean the collector will not wait to start a new cycle. A value of 200 means that the collector waits for the total number of objects to double before starting a new cycle. -The default value is 200. The garbage-collector step size controls the size of each incremental step, @@ -672,7 +671,6 @@ specifically how many objects the interpreter creates before performing a step: A value of @M{n} means the interpreter will create approximately @M{n} objects between steps. -The default value is 250. The garbage-collector step multiplier controls the size of each GC step. @@ -681,7 +679,6 @@ in each step, @M{n%} objects for each created object. Larger values make the collector more aggressive. Beware that values too small can make the collector too slow to ever finish a cycle. -The default value is 200. As a special case, a zero value means unlimited work, effectively producing a non-incremental, stop-the-world collector. @@ -711,7 +708,6 @@ after the last major collection. For instance, for a multiplier of 20, the collector will do a minor collection when the number of objects gets 20% larger than the total after the last major collection. -The default value is 25. The minor-major multiplier controls the shift to major collections. For a multiplier @M{x}, @@ -721,7 +717,6 @@ than the total after the previous major collection. For instance, for a multiplier of 100, the collector will do a major collection when the number of old objects gets larger than twice the total after the previous major collection. -The default value is 100. The major-minor multiplier controls the shift back to minor collections. For a multiplier @M{x}, @@ -731,7 +726,6 @@ of the objects allocated during the last cycle. In particular, for a multiplier of 0, the collector will immediately shift back to minor collections after doing one cycle of major collections. -The default value is 50. } @@ -5885,13 +5879,6 @@ or @id{NULL} if there is a @x{memory allocation error}. } -@APIEntry{void luaL_openlibs (lua_State *L);| -@apii{0,0,e} - -Opens all standard Lua libraries into the given state. - -} - @APIEntry{ T luaL_opt (L, func, arg, dflt);| @apii{0,0,-} @@ -6073,7 +6060,7 @@ and sets the call result to @T{package.loaded[modname]}, as if that function has been called through @Lid{require}. If @id{glb} is true, -also stores the module into the global @id{modname}. +also stores the module into the global variable @id{modname}. Leaves a copy of the module on the stack. @@ -6290,23 +6277,61 @@ Except for the basic and the package libraries, each library provides all its functions as fields of a global table or as methods of its objects. -To have access to these libraries, -the @N{C host} program should call the @Lid{luaL_openlibs} function, -which opens all standard libraries. +} + + +@sect2{lualib-h| @title{Loading the Libraries in C code} + +A @N{C host} program must explicitly load +the standard libraries into a state, +if it wants its scripts to use them. +For that, +the host program can call the function @Lid{luaL_openlibs}. Alternatively, -the host program can open them individually by using -@Lid{luaL_requiref} to call -@defid{luaopen_base} (for the basic library), -@defid{luaopen_package} (for the package library), -@defid{luaopen_coroutine} (for the coroutine library), -@defid{luaopen_string} (for the string library), -@defid{luaopen_utf8} (for the UTF-8 library), -@defid{luaopen_table} (for the table library), -@defid{luaopen_math} (for the mathematical library), -@defid{luaopen_io} (for the I/O library), -@defid{luaopen_os} (for the operating system library), -and @defid{luaopen_debug} (for the debug library). -These functions are declared in @defid{lualib.h}. +the host can select which libraries to open, +by using @Lid{luaL_openselectedlibs}. +Both functions are defined in the header file @id{lualib.h}. +@index{lualib.h} + +The stand-alone interpreter @id{lua} @see{lua-sa} +already opens all standard libraries. + +@APIEntry{void luaL_openlibs (lua_State *L);| +@apii{0,0,e} + +Opens all standard Lua libraries into the given state. + +} + +@APIEntry{void luaL_openselectedlibs (lua_State *L, int load, int preload);| +@apii{0,0,e} + +Opens (loads) and preloads selected libraries into the state @id{L}. +(To @emph{preload} means to add +the library loader into the table @Lid{package.preload}, +so that the library can be required later by the program. +Keep in mind that @Lid{require} itself is provided +by the @emph{package} library. +If a program does not load that library, +it will be unable to require anything.) + +The integer @id{load} selects which libraries to load; +the integer @id{preload} selects which to preload, among those not loaded. +Both are masks formed by a bitwise OR of the following constants: +@description{ +@item{@defid{LUA_GLIBK} | the basic library.} +@item{@defid{LUA_LOADLIBK} | the package library.} +@item{@defid{LUA_COLIBK} | the coroutine library.} +@item{@defid{LUA_STRLIBK} | the string library.} +@item{@defid{LUA_UTF8LIBK} | the UTF-8 library.} +@item{@defid{LUA_TABLIBK} | the table library.} +@item{@defid{LUA_MATHLIBK} | the mathematical library.} +@item{@defid{LUA_IOLIBK} | the I/O library.} +@item{@defid{LUA_OSLIBK} | the operating system library.} +@item{@defid{LUA_DBLIBK} | the debug library.} +} + +} } diff --git a/testes/api.lua b/testes/api.lua index ca4b3fb4..eec9c0ab 100644 --- a/testes/api.lua +++ b/testes/api.lua @@ -546,9 +546,9 @@ do ]], source) collectgarbage() local m2 = collectgarbage"count" * 1024 - -- load used fewer than 350 bytes. Code alone has more than 3*N bytes, + -- load used fewer than 400 bytes. Code alone has more than 3*N bytes, -- and string literal has N bytes. Both were not loaded. - assert(m2 > m1 and m2 - m1 < 350) + assert(m2 > m1 and m2 - m1 < 400) X = 0; code(); assert(X == N and Y == string.rep("a", N)) X = nil; Y = nil @@ -1122,7 +1122,7 @@ assert(a == nil and c == 2) -- 2 == run-time error a, b, c = T.doremote(L1, "return a+") assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error -T.loadlib(L1, 2) -- load only 'package' +T.loadlib(L1, 2, ~2) -- load only 'package', preload all others a, b, c = T.doremote(L1, [[ string = require'string' local initialG = _G -- not loaded yet @@ -1141,7 +1141,7 @@ T.closestate(L1); L1 = T.newstate() -T.loadlib(L1, 0) +T.loadlib(L1, 0, 0) T.doremote(L1, "a = {}") T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1; settable -3]]) @@ -1524,7 +1524,7 @@ end do -- garbage collection with no extra memory local L = T.newstate() - T.loadlib(L, 1 | 2) -- load _G and 'package' + T.loadlib(L, 1 | 2, 0) -- load _G and 'package' local res = (T.doremote(L, [[ _ENV = _G assert(string == nil) diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 664ef5fa..c1252ab8 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua @@ -705,7 +705,7 @@ else T.testC(state, "settop 0") - T.loadlib(state, 1 | 2) -- load _G and 'package' + T.loadlib(state, 1 | 2, 4) -- load _G and 'package', preload 'coroutine' assert(T.doremote(state, [[ coroutine = require'coroutine';