2
0
Эх сурвалжийг харах

New interface to function 'luaL_openselectedlibs'

Instead of preloading all non-loaded libraries, there is another
mask to select which libraries to preload.
Roberto Ierusalimschy 1 жил өмнө
parent
commit
165389b27b
8 өөрчлөгдсөн 80 нэмэгдсэн , 56 устгасан
  1. 10 12
      linit.c
  2. 3 2
      ltests.c
  3. 1 1
      lua.c
  4. 4 4
      lualib.h
  5. 1 1
      manual/2html
  6. 55 30
      manual/manual.of
  7. 5 5
      testes/api.lua
  8. 1 1
      testes/coroutine.lua

+ 10 - 12
linit.c

@@ -21,12 +21,12 @@
 
 
 
 
 /*
 /*
-** Standard Libraries
+** Standard Libraries. (Must be listed in the same ORDER of their
+** respective constants LUA_<libname>K.)
 */
 */
 static const luaL_Reg stdlibs[] = {
 static const luaL_Reg stdlibs[] = {
   {LUA_GNAME, luaopen_base},
   {LUA_GNAME, luaopen_base},
   {LUA_LOADLIBNAME, luaopen_package},
   {LUA_LOADLIBNAME, luaopen_package},
-
   {LUA_COLIBNAME, luaopen_coroutine},
   {LUA_COLIBNAME, luaopen_coroutine},
   {LUA_DBLIBNAME, luaopen_debug},
   {LUA_DBLIBNAME, luaopen_debug},
   {LUA_IOLIBNAME, luaopen_io},
   {LUA_IOLIBNAME, luaopen_io},
@@ -35,30 +35,28 @@ static const luaL_Reg stdlibs[] = {
   {LUA_STRLIBNAME, luaopen_string},
   {LUA_STRLIBNAME, luaopen_string},
   {LUA_TABLIBNAME, luaopen_table},
   {LUA_TABLIBNAME, luaopen_table},
   {LUA_UTF8LIBNAME, luaopen_utf8},
   {LUA_UTF8LIBNAME, luaopen_utf8},
-
   {NULL, NULL}
   {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;
   const luaL_Reg *lib;
   luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
   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 */
       luaL_requiref(L, lib->name, lib->func, 1);  /* require library */
       lua_pop(L, 1);  /* remove result from the stack */
       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_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_assert((mask >> 1) == LUA_UTF8LIBK);
-  lua_pop(L, 1);  // remove PRELOAD table
+  lua_pop(L, 1);  /* remove PRELOAD table */
 }
 }
 
 

+ 3 - 2
ltests.c

@@ -1223,8 +1223,9 @@ static lua_State *getstate (lua_State *L) {
 
 
 static int loadlib (lua_State *L) {
 static int loadlib (lua_State *L) {
   lua_State *L1 = getstate(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);
   luaL_requiref(L1, "T", luaB_opentests, 0);
   lua_assert(lua_type(L1, -1) == LUA_TTABLE);
   lua_assert(lua_type(L1, -1) == LUA_TTABLE);
   /* 'requiref' should not reload module already loaded... */
   /* 'requiref' should not reload module already loaded... */

+ 1 - 1
lua.c

@@ -618,7 +618,7 @@ static void doREPL (lua_State *L) {
 /* }================================================================== */
 /* }================================================================== */
 
 
 #if !defined(luai_openlibs)
 #if !defined(luai_openlibs)
-#define luai_openlibs(L)	luaL_openlibs(L)
+#define luai_openlibs(L)	luaL_openselectedlibs(L, ~0, 0)
 #endif
 #endif
 
 
 
 

+ 4 - 4
lualib.h

@@ -14,11 +14,11 @@
 /* version suffix for environment variable names */
 /* version suffix for environment variable names */
 #define LUA_VERSUFFIX          "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
 #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);
 LUAMOD_API int (luaopen_base) (lua_State *L);
 
 
 #define LUA_LOADLIBNAME	"package"
 #define LUA_LOADLIBNAME	"package"
-#define LUA_LOADLIBK	(LUA_GK << 1)
+#define LUA_LOADLIBK	(LUA_GLIBK << 1)
 LUAMOD_API int (luaopen_package) (lua_State *L);
 LUAMOD_API int (luaopen_package) (lua_State *L);
 
 
 
 
@@ -56,10 +56,10 @@ LUAMOD_API int (luaopen_utf8) (lua_State *L);
 
 
 
 
 /* open selected libraries */
 /* 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 */
 /* open all libraries */
-#define luaL_openlibs(L)	luaL_openselectedlibs(L, ~0)
+#define luaL_openlibs(L)	luaL_openselectedlibs(L, ~0, 0)
 
 
 
 
 #endif
 #endif

+ 1 - 1
manual/2html

@@ -358,7 +358,7 @@ item = function (s)
          local t, p = string.match(s, "^([^\n|]+)|()")
          local t, p = string.match(s, "^([^\n|]+)|()")
          if t then
          if t then
            s = string.sub(s, p)
            s = string.sub(s, p)
-           s = Tag.b(t..": ") .. s
+           s = Tag.b(t) ..": " .. s
          end
          end
          return Tag.li(fixpara(s))
          return Tag.li(fixpara(s))
        end,
        end,

+ 55 - 30
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.
 start a new cycle.
 A value of 200 means that the collector waits for
 A value of 200 means that the collector waits for
 the total number of objects to double before starting a new cycle.
 the total number of objects to double before starting a new cycle.
-The default value is 200.
 
 
 The garbage-collector step size controls the
 The garbage-collector step size controls the
 size of each incremental step,
 size of each incremental step,
@@ -672,7 +671,6 @@ specifically how many objects the interpreter creates
 before performing a step:
 before performing a step:
 A value of @M{n} means the interpreter will create
 A value of @M{n} means the interpreter will create
 approximately @M{n} objects between steps.
 approximately @M{n} objects between steps.
-The default value is 250.
 
 
 The garbage-collector step multiplier
 The garbage-collector step multiplier
 controls the size of each GC step.
 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.
 Larger values make the collector more aggressive.
 Beware that values too small can
 Beware that values too small can
 make the collector too slow to ever finish a cycle.
 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,
 As a special case, a zero value means unlimited work,
 effectively producing a non-incremental, stop-the-world collector.
 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,
 For instance, for a multiplier of 20,
 the collector will do a minor collection when the number of objects
 the collector will do a minor collection when the number of objects
 gets 20% larger than the total after the last major collection.
 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.
 The minor-major multiplier controls the shift to major collections.
 For a multiplier @M{x},
 For a multiplier @M{x},
@@ -721,7 +717,6 @@ than the total after the previous major collection.
 For instance, for a multiplier of 100,
 For instance, for a multiplier of 100,
 the collector will do a major collection when the number of old objects
 the collector will do a major collection when the number of old objects
 gets larger than twice the total after the previous major collection.
 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.
 The major-minor multiplier controls the shift back to minor collections.
 For a multiplier @M{x},
 For a multiplier @M{x},
@@ -731,7 +726,6 @@ of the objects allocated during the last cycle.
 In particular, for a multiplier of 0,
 In particular, for a multiplier of 0,
 the collector will immediately shift back to minor collections
 the collector will immediately shift back to minor collections
 after doing one cycle of major 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{
 @APIEntry{
 T luaL_opt (L, func, arg, dflt);|
 T luaL_opt (L, func, arg, dflt);|
 @apii{0,0,-}
 @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}.
 as if that function has been called through @Lid{require}.
 
 
 If @id{glb} is true,
 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.
 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
 each library provides all its functions as fields of a global table
 or as methods of its objects.
 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,
 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.}
+}
+
+}
 
 
 }
 }
 
 

+ 5 - 5
testes/api.lua

@@ -546,9 +546,9 @@ do
   ]], source)
   ]], source)
   collectgarbage()
   collectgarbage()
   local m2 = collectgarbage"count" * 1024
   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.
   -- 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 = 0; code(); assert(X == N and Y == string.rep("a", N))
   X = nil; Y = nil
   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+")
 a, b, c = T.doremote(L1, "return a+")
 assert(a == nil and c == 3 and type(b) == "string")   -- 3 == syntax error
 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, [[
 a, b, c = T.doremote(L1, [[
   string = require'string'
   string = require'string'
   local initialG = _G   -- not loaded yet
   local initialG = _G   -- not loaded yet
@@ -1141,7 +1141,7 @@ T.closestate(L1);
 
 
 
 
 L1 = T.newstate()
 L1 = T.newstate()
-T.loadlib(L1, 0)
+T.loadlib(L1, 0, 0)
 T.doremote(L1, "a = {}")
 T.doremote(L1, "a = {}")
 T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1;
 T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1;
              settable -3]])
              settable -3]])
@@ -1524,7 +1524,7 @@ end
 
 
 do   -- garbage collection with no extra memory
 do   -- garbage collection with no extra memory
   local L = T.newstate()
   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, [[
   local res = (T.doremote(L, [[
     _ENV = _G
     _ENV = _G
     assert(string == nil)
     assert(string == nil)

+ 1 - 1
testes/coroutine.lua

@@ -705,7 +705,7 @@ else
 
 
   T.testC(state, "settop 0")
   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, [[
   assert(T.doremote(state, [[
     coroutine = require'coroutine';
     coroutine = require'coroutine';