diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-02-15 11:17:39 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-02-15 11:17:39 -0300 |
| commit | 165389b27bc54e7c5214276db177e3ef75226f18 (patch) | |
| tree | f6ce6e7bff04ff6cbe735ee68d64290cc04c04bf | |
| parent | c8121ce34b39c6fd31899f4da91e26063c8af54f (diff) | |
| download | lua-165389b27bc54e7c5214276db177e3ef75226f18.tar.gz lua-165389b27bc54e7c5214276db177e3ef75226f18.tar.bz2 lua-165389b27bc54e7c5214276db177e3ef75226f18.zip | |
New interface to function 'luaL_openselectedlibs'
Instead of preloading all non-loaded libraries, there is another
mask to select which libraries to preload.
| -rw-r--r-- | linit.c | 22 | ||||
| -rw-r--r-- | ltests.c | 5 | ||||
| -rw-r--r-- | lua.c | 2 | ||||
| -rw-r--r-- | lualib.h | 8 | ||||
| -rwxr-xr-x | manual/2html | 2 | ||||
| -rw-r--r-- | manual/manual.of | 85 | ||||
| -rw-r--r-- | testes/api.lua | 10 | ||||
| -rw-r--r-- | testes/coroutine.lua | 2 |
8 files changed, 80 insertions, 56 deletions
| @@ -21,12 +21,12 @@ | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | ** Standard Libraries | 24 | ** Standard Libraries. (Must be listed in the same ORDER of their |
| 25 | ** respective constants LUA_<libname>K.) | ||
| 25 | */ | 26 | */ |
| 26 | static const luaL_Reg stdlibs[] = { | 27 | static const luaL_Reg stdlibs[] = { |
| 27 | {LUA_GNAME, luaopen_base}, | 28 | {LUA_GNAME, luaopen_base}, |
| 28 | {LUA_LOADLIBNAME, luaopen_package}, | 29 | {LUA_LOADLIBNAME, luaopen_package}, |
| 29 | |||
| 30 | {LUA_COLIBNAME, luaopen_coroutine}, | 30 | {LUA_COLIBNAME, luaopen_coroutine}, |
| 31 | {LUA_DBLIBNAME, luaopen_debug}, | 31 | {LUA_DBLIBNAME, luaopen_debug}, |
| 32 | {LUA_IOLIBNAME, luaopen_io}, | 32 | {LUA_IOLIBNAME, luaopen_io}, |
| @@ -35,30 +35,28 @@ static const luaL_Reg stdlibs[] = { | |||
| 35 | {LUA_STRLIBNAME, luaopen_string}, | 35 | {LUA_STRLIBNAME, luaopen_string}, |
| 36 | {LUA_TABLIBNAME, luaopen_table}, | 36 | {LUA_TABLIBNAME, luaopen_table}, |
| 37 | {LUA_UTF8LIBNAME, luaopen_utf8}, | 37 | {LUA_UTF8LIBNAME, luaopen_utf8}, |
| 38 | |||
| 39 | {NULL, NULL} | 38 | {NULL, NULL} |
| 40 | }; | 39 | }; |
| 41 | 40 | ||
| 42 | 41 | ||
| 43 | /* | 42 | /* |
| 44 | ** require selected standard libraries and add the others to the | 43 | ** require and preload selected standard libraries |
| 45 | ** preload table. | ||
| 46 | */ | 44 | */ |
| 47 | LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) { | 45 | LUALIB_API void luaL_openselectedlibs (lua_State *L, int load, int preload) { |
| 48 | int mask = 1; | 46 | int mask; |
| 49 | const luaL_Reg *lib; | 47 | const luaL_Reg *lib; |
| 50 | luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); | 48 | luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); |
| 51 | for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) { | 49 | for (lib = stdlibs, mask = 1; lib->name != NULL; lib++, mask <<= 1) { |
| 52 | if (what & mask) { /* selected? */ | 50 | if (load & mask) { /* selected? */ |
| 53 | luaL_requiref(L, lib->name, lib->func, 1); /* require library */ | 51 | luaL_requiref(L, lib->name, lib->func, 1); /* require library */ |
| 54 | lua_pop(L, 1); /* remove result from the stack */ | 52 | lua_pop(L, 1); /* remove result from the stack */ |
| 55 | } | 53 | } |
| 56 | else { /* add library to PRELOAD table */ | 54 | else if (preload & mask) { /* selected? */ |
| 57 | lua_pushcfunction(L, lib->func); | 55 | lua_pushcfunction(L, lib->func); |
| 58 | lua_setfield(L, -2, lib->name); | 56 | lua_setfield(L, -2, lib->name); /* add library to PRELOAD table */ |
| 59 | } | 57 | } |
| 60 | } | 58 | } |
| 61 | lua_assert((mask >> 1) == LUA_UTF8LIBK); | 59 | lua_assert((mask >> 1) == LUA_UTF8LIBK); |
| 62 | lua_pop(L, 1); // remove PRELOAD table | 60 | lua_pop(L, 1); /* remove PRELOAD table */ |
| 63 | } | 61 | } |
| 64 | 62 | ||
| @@ -1223,8 +1223,9 @@ static lua_State *getstate (lua_State *L) { | |||
| 1223 | 1223 | ||
| 1224 | static int loadlib (lua_State *L) { | 1224 | static int loadlib (lua_State *L) { |
| 1225 | lua_State *L1 = getstate(L); | 1225 | lua_State *L1 = getstate(L); |
| 1226 | int what = luaL_checkinteger(L, 2); | 1226 | int load = luaL_checkinteger(L, 2); |
| 1227 | luaL_openselectedlibs(L1, what); | 1227 | int preload = luaL_checkinteger(L, 3); |
| 1228 | luaL_openselectedlibs(L1, load, preload); | ||
| 1228 | luaL_requiref(L1, "T", luaB_opentests, 0); | 1229 | luaL_requiref(L1, "T", luaB_opentests, 0); |
| 1229 | lua_assert(lua_type(L1, -1) == LUA_TTABLE); | 1230 | lua_assert(lua_type(L1, -1) == LUA_TTABLE); |
| 1230 | /* 'requiref' should not reload module already loaded... */ | 1231 | /* 'requiref' should not reload module already loaded... */ |
| @@ -618,7 +618,7 @@ static void doREPL (lua_State *L) { | |||
| 618 | /* }================================================================== */ | 618 | /* }================================================================== */ |
| 619 | 619 | ||
| 620 | #if !defined(luai_openlibs) | 620 | #if !defined(luai_openlibs) |
| 621 | #define luai_openlibs(L) luaL_openlibs(L) | 621 | #define luai_openlibs(L) luaL_openselectedlibs(L, ~0, 0) |
| 622 | #endif | 622 | #endif |
| 623 | 623 | ||
| 624 | 624 | ||
| @@ -14,11 +14,11 @@ | |||
| 14 | /* version suffix for environment variable names */ | 14 | /* version suffix for environment variable names */ |
| 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR | 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR |
| 16 | 16 | ||
| 17 | #define LUA_GK 1 | 17 | #define LUA_GLIBK 1 |
| 18 | LUAMOD_API int (luaopen_base) (lua_State *L); | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); |
| 19 | 19 | ||
| 20 | #define LUA_LOADLIBNAME "package" | 20 | #define LUA_LOADLIBNAME "package" |
| 21 | #define LUA_LOADLIBK (LUA_GK << 1) | 21 | #define LUA_LOADLIBK (LUA_GLIBK << 1) |
| 22 | LUAMOD_API int (luaopen_package) (lua_State *L); | 22 | LUAMOD_API int (luaopen_package) (lua_State *L); |
| 23 | 23 | ||
| 24 | 24 | ||
| @@ -56,10 +56,10 @@ LUAMOD_API int (luaopen_utf8) (lua_State *L); | |||
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | /* open selected libraries */ | 58 | /* open selected libraries */ |
| 59 | LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what); | 59 | LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int load, int preload); |
| 60 | 60 | ||
| 61 | /* open all libraries */ | 61 | /* open all libraries */ |
| 62 | #define luaL_openlibs(L) luaL_openselectedlibs(L, ~0) | 62 | #define luaL_openlibs(L) luaL_openselectedlibs(L, ~0, 0) |
| 63 | 63 | ||
| 64 | 64 | ||
| 65 | #endif | 65 | #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) | |||
| 358 | local t, p = string.match(s, "^([^\n|]+)|()") | 358 | local t, p = string.match(s, "^([^\n|]+)|()") |
| 359 | if t then | 359 | if t then |
| 360 | s = string.sub(s, p) | 360 | s = string.sub(s, p) |
| 361 | s = Tag.b(t..": ") .. s | 361 | s = Tag.b(t) ..": " .. s |
| 362 | end | 362 | end |
| 363 | return Tag.li(fixpara(s)) | 363 | return Tag.li(fixpara(s)) |
| 364 | end, | 364 | 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 | |||
| 664 | start a new cycle. | 664 | start a new cycle. |
| 665 | A value of 200 means that the collector waits for | 665 | A value of 200 means that the collector waits for |
| 666 | the total number of objects to double before starting a new cycle. | 666 | the total number of objects to double before starting a new cycle. |
| 667 | The default value is 200. | ||
| 668 | 667 | ||
| 669 | The garbage-collector step size controls the | 668 | The garbage-collector step size controls the |
| 670 | size of each incremental step, | 669 | size of each incremental step, |
| @@ -672,7 +671,6 @@ specifically how many objects the interpreter creates | |||
| 672 | before performing a step: | 671 | before performing a step: |
| 673 | A value of @M{n} means the interpreter will create | 672 | A value of @M{n} means the interpreter will create |
| 674 | approximately @M{n} objects between steps. | 673 | approximately @M{n} objects between steps. |
| 675 | The default value is 250. | ||
| 676 | 674 | ||
| 677 | The garbage-collector step multiplier | 675 | The garbage-collector step multiplier |
| 678 | controls the size of each GC step. | 676 | controls the size of each GC step. |
| @@ -681,7 +679,6 @@ in each step, @M{n%} objects for each created object. | |||
| 681 | Larger values make the collector more aggressive. | 679 | Larger values make the collector more aggressive. |
| 682 | Beware that values too small can | 680 | Beware that values too small can |
| 683 | make the collector too slow to ever finish a cycle. | 681 | make the collector too slow to ever finish a cycle. |
| 684 | The default value is 200. | ||
| 685 | As a special case, a zero value means unlimited work, | 682 | As a special case, a zero value means unlimited work, |
| 686 | effectively producing a non-incremental, stop-the-world collector. | 683 | effectively producing a non-incremental, stop-the-world collector. |
| 687 | 684 | ||
| @@ -711,7 +708,6 @@ after the last major collection. | |||
| 711 | For instance, for a multiplier of 20, | 708 | For instance, for a multiplier of 20, |
| 712 | the collector will do a minor collection when the number of objects | 709 | the collector will do a minor collection when the number of objects |
| 713 | gets 20% larger than the total after the last major collection. | 710 | gets 20% larger than the total after the last major collection. |
| 714 | The default value is 25. | ||
| 715 | 711 | ||
| 716 | The minor-major multiplier controls the shift to major collections. | 712 | The minor-major multiplier controls the shift to major collections. |
| 717 | For a multiplier @M{x}, | 713 | For a multiplier @M{x}, |
| @@ -721,7 +717,6 @@ than the total after the previous major collection. | |||
| 721 | For instance, for a multiplier of 100, | 717 | For instance, for a multiplier of 100, |
| 722 | the collector will do a major collection when the number of old objects | 718 | the collector will do a major collection when the number of old objects |
| 723 | gets larger than twice the total after the previous major collection. | 719 | gets larger than twice the total after the previous major collection. |
| 724 | The default value is 100. | ||
| 725 | 720 | ||
| 726 | The major-minor multiplier controls the shift back to minor collections. | 721 | The major-minor multiplier controls the shift back to minor collections. |
| 727 | For a multiplier @M{x}, | 722 | For a multiplier @M{x}, |
| @@ -731,7 +726,6 @@ of the objects allocated during the last cycle. | |||
| 731 | In particular, for a multiplier of 0, | 726 | In particular, for a multiplier of 0, |
| 732 | the collector will immediately shift back to minor collections | 727 | the collector will immediately shift back to minor collections |
| 733 | after doing one cycle of major collections. | 728 | after doing one cycle of major collections. |
| 734 | The default value is 50. | ||
| 735 | 729 | ||
| 736 | } | 730 | } |
| 737 | 731 | ||
| @@ -5885,13 +5879,6 @@ or @id{NULL} if there is a @x{memory allocation error}. | |||
| 5885 | 5879 | ||
| 5886 | } | 5880 | } |
| 5887 | 5881 | ||
| 5888 | @APIEntry{void luaL_openlibs (lua_State *L);| | ||
| 5889 | @apii{0,0,e} | ||
| 5890 | |||
| 5891 | Opens all standard Lua libraries into the given state. | ||
| 5892 | |||
| 5893 | } | ||
| 5894 | |||
| 5895 | @APIEntry{ | 5882 | @APIEntry{ |
| 5896 | T luaL_opt (L, func, arg, dflt);| | 5883 | T luaL_opt (L, func, arg, dflt);| |
| 5897 | @apii{0,0,-} | 5884 | @apii{0,0,-} |
| @@ -6073,7 +6060,7 @@ and sets the call result to @T{package.loaded[modname]}, | |||
| 6073 | as if that function has been called through @Lid{require}. | 6060 | as if that function has been called through @Lid{require}. |
| 6074 | 6061 | ||
| 6075 | If @id{glb} is true, | 6062 | If @id{glb} is true, |
| 6076 | also stores the module into the global @id{modname}. | 6063 | also stores the module into the global variable @id{modname}. |
| 6077 | 6064 | ||
| 6078 | Leaves a copy of the module on the stack. | 6065 | Leaves a copy of the module on the stack. |
| 6079 | 6066 | ||
| @@ -6290,23 +6277,61 @@ Except for the basic and the package libraries, | |||
| 6290 | each library provides all its functions as fields of a global table | 6277 | each library provides all its functions as fields of a global table |
| 6291 | or as methods of its objects. | 6278 | or as methods of its objects. |
| 6292 | 6279 | ||
| 6293 | To have access to these libraries, | 6280 | } |
| 6294 | the @N{C host} program should call the @Lid{luaL_openlibs} function, | 6281 | |
| 6295 | which opens all standard libraries. | 6282 | |
| 6283 | @sect2{lualib-h| @title{Loading the Libraries in C code} | ||
| 6284 | |||
| 6285 | A @N{C host} program must explicitly load | ||
| 6286 | the standard libraries into a state, | ||
| 6287 | if it wants its scripts to use them. | ||
| 6288 | For that, | ||
| 6289 | the host program can call the function @Lid{luaL_openlibs}. | ||
| 6296 | Alternatively, | 6290 | Alternatively, |
| 6297 | the host program can open them individually by using | 6291 | the host can select which libraries to open, |
| 6298 | @Lid{luaL_requiref} to call | 6292 | by using @Lid{luaL_openselectedlibs}. |
| 6299 | @defid{luaopen_base} (for the basic library), | 6293 | Both functions are defined in the header file @id{lualib.h}. |
| 6300 | @defid{luaopen_package} (for the package library), | 6294 | @index{lualib.h} |
| 6301 | @defid{luaopen_coroutine} (for the coroutine library), | 6295 | |
| 6302 | @defid{luaopen_string} (for the string library), | 6296 | The stand-alone interpreter @id{lua} @see{lua-sa} |
| 6303 | @defid{luaopen_utf8} (for the UTF-8 library), | 6297 | already opens all standard libraries. |
| 6304 | @defid{luaopen_table} (for the table library), | 6298 | |
| 6305 | @defid{luaopen_math} (for the mathematical library), | 6299 | @APIEntry{void luaL_openlibs (lua_State *L);| |
| 6306 | @defid{luaopen_io} (for the I/O library), | 6300 | @apii{0,0,e} |
| 6307 | @defid{luaopen_os} (for the operating system library), | 6301 | |
| 6308 | and @defid{luaopen_debug} (for the debug library). | 6302 | Opens all standard Lua libraries into the given state. |
| 6309 | These functions are declared in @defid{lualib.h}. | 6303 | |
| 6304 | } | ||
| 6305 | |||
| 6306 | @APIEntry{void luaL_openselectedlibs (lua_State *L, int load, int preload);| | ||
| 6307 | @apii{0,0,e} | ||
| 6308 | |||
| 6309 | Opens (loads) and preloads selected libraries into the state @id{L}. | ||
| 6310 | (To @emph{preload} means to add | ||
| 6311 | the library loader into the table @Lid{package.preload}, | ||
| 6312 | so that the library can be required later by the program. | ||
| 6313 | Keep in mind that @Lid{require} itself is provided | ||
| 6314 | by the @emph{package} library. | ||
| 6315 | If a program does not load that library, | ||
| 6316 | it will be unable to require anything.) | ||
| 6317 | |||
| 6318 | The integer @id{load} selects which libraries to load; | ||
| 6319 | the integer @id{preload} selects which to preload, among those not loaded. | ||
| 6320 | Both are masks formed by a bitwise OR of the following constants: | ||
| 6321 | @description{ | ||
| 6322 | @item{@defid{LUA_GLIBK} | the basic library.} | ||
| 6323 | @item{@defid{LUA_LOADLIBK} | the package library.} | ||
| 6324 | @item{@defid{LUA_COLIBK} | the coroutine library.} | ||
| 6325 | @item{@defid{LUA_STRLIBK} | the string library.} | ||
| 6326 | @item{@defid{LUA_UTF8LIBK} | the UTF-8 library.} | ||
| 6327 | @item{@defid{LUA_TABLIBK} | the table library.} | ||
| 6328 | @item{@defid{LUA_MATHLIBK} | the mathematical library.} | ||
| 6329 | @item{@defid{LUA_IOLIBK} | the I/O library.} | ||
| 6330 | @item{@defid{LUA_OSLIBK} | the operating system library.} | ||
| 6331 | @item{@defid{LUA_DBLIBK} | the debug library.} | ||
| 6332 | } | ||
| 6333 | |||
| 6334 | } | ||
| 6310 | 6335 | ||
| 6311 | } | 6336 | } |
| 6312 | 6337 | ||
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 | |||
| 546 | ]], source) | 546 | ]], source) |
| 547 | collectgarbage() | 547 | collectgarbage() |
| 548 | local m2 = collectgarbage"count" * 1024 | 548 | local m2 = collectgarbage"count" * 1024 |
| 549 | -- load used fewer than 350 bytes. Code alone has more than 3*N bytes, | 549 | -- load used fewer than 400 bytes. Code alone has more than 3*N bytes, |
| 550 | -- and string literal has N bytes. Both were not loaded. | 550 | -- and string literal has N bytes. Both were not loaded. |
| 551 | assert(m2 > m1 and m2 - m1 < 350) | 551 | assert(m2 > m1 and m2 - m1 < 400) |
| 552 | X = 0; code(); assert(X == N and Y == string.rep("a", N)) | 552 | X = 0; code(); assert(X == N and Y == string.rep("a", N)) |
| 553 | X = nil; Y = nil | 553 | X = nil; Y = nil |
| 554 | 554 | ||
| @@ -1122,7 +1122,7 @@ assert(a == nil and c == 2) -- 2 == run-time error | |||
| 1122 | a, b, c = T.doremote(L1, "return a+") | 1122 | a, b, c = T.doremote(L1, "return a+") |
| 1123 | assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error | 1123 | assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error |
| 1124 | 1124 | ||
| 1125 | T.loadlib(L1, 2) -- load only 'package' | 1125 | T.loadlib(L1, 2, ~2) -- load only 'package', preload all others |
| 1126 | a, b, c = T.doremote(L1, [[ | 1126 | a, b, c = T.doremote(L1, [[ |
| 1127 | string = require'string' | 1127 | string = require'string' |
| 1128 | local initialG = _G -- not loaded yet | 1128 | local initialG = _G -- not loaded yet |
| @@ -1141,7 +1141,7 @@ T.closestate(L1); | |||
| 1141 | 1141 | ||
| 1142 | 1142 | ||
| 1143 | L1 = T.newstate() | 1143 | L1 = T.newstate() |
| 1144 | T.loadlib(L1, 0) | 1144 | T.loadlib(L1, 0, 0) |
| 1145 | T.doremote(L1, "a = {}") | 1145 | T.doremote(L1, "a = {}") |
| 1146 | T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1; | 1146 | T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1; |
| 1147 | settable -3]]) | 1147 | settable -3]]) |
| @@ -1524,7 +1524,7 @@ end | |||
| 1524 | 1524 | ||
| 1525 | do -- garbage collection with no extra memory | 1525 | do -- garbage collection with no extra memory |
| 1526 | local L = T.newstate() | 1526 | local L = T.newstate() |
| 1527 | T.loadlib(L, 1 | 2) -- load _G and 'package' | 1527 | T.loadlib(L, 1 | 2, 0) -- load _G and 'package' |
| 1528 | local res = (T.doremote(L, [[ | 1528 | local res = (T.doremote(L, [[ |
| 1529 | _ENV = _G | 1529 | _ENV = _G |
| 1530 | assert(string == nil) | 1530 | 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 | |||
| 705 | 705 | ||
| 706 | T.testC(state, "settop 0") | 706 | T.testC(state, "settop 0") |
| 707 | 707 | ||
| 708 | T.loadlib(state, 1 | 2) -- load _G and 'package' | 708 | T.loadlib(state, 1 | 2, 4) -- load _G and 'package', preload 'coroutine' |
| 709 | 709 | ||
| 710 | assert(T.doremote(state, [[ | 710 | assert(T.doremote(state, [[ |
| 711 | coroutine = require'coroutine'; | 711 | coroutine = require'coroutine'; |
