diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-17 18:37:37 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-17 18:37:37 -0300 |
commit | 1514e49d4321efc30d597e05a072266c7c4d697d (patch) | |
tree | affcab00868f3b34091b85519a0ee4da8728b032 | |
parent | 22ef84b6c8d980eb869f414610f8ff5f25568ca7 (diff) | |
download | lua-1514e49d4321efc30d597e05a072266c7c4d697d.tar.gz lua-1514e49d4321efc30d597e05a072266c7c4d697d.tar.bz2 lua-1514e49d4321efc30d597e05a072266c7c4d697d.zip |
avoid using function environments in C libraries (as it probably will
be deprecated)
-rw-r--r-- | lauxlib.c | 21 | ||||
-rw-r--r-- | lauxlib.h | 19 | ||||
-rw-r--r-- | liolib.c | 59 | ||||
-rw-r--r-- | loadlib.c | 21 |
4 files changed, 69 insertions, 51 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.201 2010/02/18 19:37:57 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.202 2010/03/12 18:59:32 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -670,13 +670,13 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | |||
670 | 670 | ||
671 | static int libsize (const luaL_Reg *l) { | 671 | static int libsize (const luaL_Reg *l) { |
672 | int size = 0; | 672 | int size = 0; |
673 | for (; l->name; l++) size++; | 673 | for (; l && l->name; l++) size++; |
674 | return size; | 674 | return size; |
675 | } | 675 | } |
676 | 676 | ||
677 | 677 | ||
678 | LUALIB_API void luaL_register (lua_State *L, const char *libname, | 678 | LUALIB_API void luaL_openlib (lua_State *L, const char *libname, |
679 | const luaL_Reg *l) { | 679 | const luaL_Reg *l, int nup) { |
680 | luaL_checkversion(L); | 680 | luaL_checkversion(L); |
681 | if (libname) { | 681 | if (libname) { |
682 | /* check whether lib already exists */ | 682 | /* check whether lib already exists */ |
@@ -692,12 +692,17 @@ LUALIB_API void luaL_register (lua_State *L, const char *libname, | |||
692 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | 692 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ |
693 | } | 693 | } |
694 | lua_remove(L, -2); /* remove _LOADED table */ | 694 | lua_remove(L, -2); /* remove _LOADED table */ |
695 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ | ||
695 | } | 696 | } |
696 | if (l == NULL) return; /* nothing to register? */ | 697 | luaL_checkstack(L, nup, "too many upvalues"); |
697 | for (; l->name; l++) { /* else fill the table with given functions */ | 698 | for (; l && l->name; l++) { /* else fill the table with given functions */ |
698 | lua_pushcfunction(L, l->func); | 699 | int i; |
699 | lua_setfield(L, -2, l->name); | 700 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ |
701 | lua_pushvalue(L, -nup); | ||
702 | lua_pushcclosure(L, l->func, nup); | ||
703 | lua_setfield(L, -(nup + 2), l->name); | ||
700 | } | 704 | } |
705 | lua_pop(L, nup); /* remove upvalues */ | ||
701 | } | 706 | } |
702 | 707 | ||
703 | 708 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.h,v 1.99 2010/01/11 16:00:45 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.100 2010/01/21 16:49:21 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -29,8 +29,8 @@ typedef struct luaL_Reg { | |||
29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); |
30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) | 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) |
31 | 31 | ||
32 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | 32 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, |
33 | const luaL_Reg *l); | 33 | const luaL_Reg *l, int nup); |
34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | 34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
35 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); | 35 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); |
36 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); | 36 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); |
@@ -71,7 +71,7 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); | |||
71 | 71 | ||
72 | LUALIB_API lua_State *(luaL_newstate) (void); | 72 | LUALIB_API lua_State *(luaL_newstate) (void); |
73 | 73 | ||
74 | LUALIB_API int luaL_len (lua_State *L, int idx); | 74 | LUALIB_API int (luaL_len) (lua_State *L, int idx); |
75 | 75 | ||
76 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, | 76 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, |
77 | const char *r); | 77 | const char *r); |
@@ -79,11 +79,11 @@ LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, | |||
79 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, | 79 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, |
80 | const char *fname, int szhint); | 80 | const char *fname, int szhint); |
81 | 81 | ||
82 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | 82 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, |
83 | const char *msg, int level); | 83 | const char *msg, int level); |
84 | 84 | ||
85 | LUALIB_API int luaL_cpcall (lua_State *L, lua_CFunction f, int nargs, | 85 | LUALIB_API int (luaL_cpcall) (lua_State *L, lua_CFunction f, int nargs, |
86 | int nresults); | 86 | int nresults); |
87 | 87 | ||
88 | 88 | ||
89 | /* | 89 | /* |
@@ -113,6 +113,9 @@ LUALIB_API int luaL_cpcall (lua_State *L, lua_CFunction f, int nargs, | |||
113 | 113 | ||
114 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) | 114 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) |
115 | 115 | ||
116 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) | ||
117 | |||
118 | |||
116 | /* | 119 | /* |
117 | ** {====================================================== | 120 | ** {====================================================== |
118 | ** Generic Buffer manipulation | 121 | ** Generic Buffer manipulation |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 2.85 2009/12/17 16:20:01 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 2.86 2010/03/03 18:48:57 roberto Exp roberto $ |
3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -103,13 +103,12 @@ static FILE *tofile (lua_State *L) { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | 105 | ||
106 | |||
107 | /* | 106 | /* |
108 | ** When creating file handles, always creates a `closed' file handle | 107 | ** When creating file handles, always creates a `closed' file handle |
109 | ** before opening the actual file; so, if there is a memory error, the | 108 | ** before opening the actual file; so, if there is a memory error, the |
110 | ** file is not left opened. | 109 | ** file is not left opened. |
111 | */ | 110 | */ |
112 | static FILE **newfile (lua_State *L) { | 111 | static FILE **newprefile (lua_State *L) { |
113 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); | 112 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); |
114 | *pf = NULL; /* file handle is currently `closed' */ | 113 | *pf = NULL; /* file handle is currently `closed' */ |
115 | luaL_getmetatable(L, LUA_FILEHANDLE); | 114 | luaL_getmetatable(L, LUA_FILEHANDLE); |
@@ -118,6 +117,14 @@ static FILE **newfile (lua_State *L) { | |||
118 | } | 117 | } |
119 | 118 | ||
120 | 119 | ||
120 | static FILE **newfile (lua_State *L) { | ||
121 | FILE **pf = newprefile(L); | ||
122 | lua_pushvalue(L, lua_upvalueindex(1)); /* set upvalue... */ | ||
123 | lua_setfenv(L, -2); /* ... as environment for new file */ | ||
124 | return pf; | ||
125 | } | ||
126 | |||
127 | |||
121 | /* | 128 | /* |
122 | ** function to (not) close the standard files stdin, stdout, and stderr | 129 | ** function to (not) close the standard files stdin, stdout, and stderr |
123 | */ | 130 | */ |
@@ -164,7 +171,7 @@ static int aux_close (lua_State *L) { | |||
164 | 171 | ||
165 | static int io_close (lua_State *L) { | 172 | static int io_close (lua_State *L) { |
166 | if (lua_isnone(L, 1)) | 173 | if (lua_isnone(L, 1)) |
167 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); | 174 | lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT); |
168 | tofile(L); /* make sure argument is a file */ | 175 | tofile(L); /* make sure argument is a file */ |
169 | return aux_close(L); | 176 | return aux_close(L); |
170 | } | 177 | } |
@@ -229,7 +236,7 @@ static int io_tmpfile (lua_State *L) { | |||
229 | 236 | ||
230 | static FILE *getiofile (lua_State *L, int findex) { | 237 | static FILE *getiofile (lua_State *L, int findex) { |
231 | FILE *f; | 238 | FILE *f; |
232 | lua_rawgeti(L, LUA_ENVIRONINDEX, findex); | 239 | lua_rawgeti(L, lua_upvalueindex(1), findex); |
233 | f = *(FILE **)lua_touserdata(L, -1); | 240 | f = *(FILE **)lua_touserdata(L, -1); |
234 | if (f == NULL) | 241 | if (f == NULL) |
235 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); | 242 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); |
@@ -250,10 +257,10 @@ static int g_iofile (lua_State *L, int f, const char *mode) { | |||
250 | tofile(L); /* check that it's a valid file handle */ | 257 | tofile(L); /* check that it's a valid file handle */ |
251 | lua_pushvalue(L, 1); | 258 | lua_pushvalue(L, 1); |
252 | } | 259 | } |
253 | lua_rawseti(L, LUA_ENVIRONINDEX, f); | 260 | lua_rawseti(L, lua_upvalueindex(1), f); |
254 | } | 261 | } |
255 | /* return current value */ | 262 | /* return current value */ |
256 | lua_rawgeti(L, LUA_ENVIRONINDEX, f); | 263 | lua_rawgeti(L, lua_upvalueindex(1), f); |
257 | return 1; | 264 | return 1; |
258 | } | 265 | } |
259 | 266 | ||
@@ -295,7 +302,7 @@ static int io_lines (lua_State *L) { | |||
295 | int toclose; | 302 | int toclose; |
296 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ | 303 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
297 | if (lua_isnil(L, 1)) { /* no file name? */ | 304 | if (lua_isnil(L, 1)) { /* no file name? */ |
298 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); /* get default input */ | 305 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ |
299 | lua_replace(L, 1); /* put it at index 1 */ | 306 | lua_replace(L, 1); /* put it at index 1 */ |
300 | tofile(L); /* check that it's a valid file handle */ | 307 | tofile(L); /* check that it's a valid file handle */ |
301 | toclose = 0; /* do not close it after iteration */ | 308 | toclose = 0; /* do not close it after iteration */ |
@@ -576,23 +583,27 @@ static void createmeta (lua_State *L) { | |||
576 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ | 583 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ |
577 | lua_pushvalue(L, -1); /* push metatable */ | 584 | lua_pushvalue(L, -1); /* push metatable */ |
578 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ | 585 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ |
579 | luaL_register(L, NULL, flib); /* file methods */ | 586 | luaL_register(L, NULL, flib); /* add file methods to new metatable */ |
587 | lua_pop(L, 1); /* pop new metatable */ | ||
580 | } | 588 | } |
581 | 589 | ||
582 | 590 | ||
583 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { | 591 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { |
584 | *newfile(L) = f; | 592 | *newprefile(L) = f; |
585 | if (k > 0) { | 593 | if (k > 0) { |
586 | lua_pushvalue(L, -1); | 594 | lua_pushvalue(L, -1); /* copy new file */ |
587 | lua_rawseti(L, LUA_ENVIRONINDEX, k); | 595 | lua_rawseti(L, 1, k); /* add it to common upvalue */ |
588 | } | 596 | } |
589 | lua_pushvalue(L, -2); /* copy environment */ | 597 | lua_pushvalue(L, 3); /* get environment for default files */ |
590 | lua_setfenv(L, -2); /* set it */ | 598 | lua_setfenv(L, -2); /* set it as environment for file */ |
591 | lua_setfield(L, -3, fname); | 599 | lua_setfield(L, 2, fname); /* add file to module */ |
592 | } | 600 | } |
593 | 601 | ||
594 | 602 | ||
595 | static void newfenv (lua_State *L, lua_CFunction cls) { | 603 | /* |
604 | ** pushes a new table with {__close = cls} | ||
605 | */ | ||
606 | static void newenv (lua_State *L, lua_CFunction cls) { | ||
596 | lua_createtable(L, 0, 1); | 607 | lua_createtable(L, 0, 1); |
597 | lua_pushcfunction(L, cls); | 608 | lua_pushcfunction(L, cls); |
598 | lua_setfield(L, -2, "__close"); | 609 | lua_setfield(L, -2, "__close"); |
@@ -600,21 +611,21 @@ static void newfenv (lua_State *L, lua_CFunction cls) { | |||
600 | 611 | ||
601 | 612 | ||
602 | LUAMOD_API int luaopen_io (lua_State *L) { | 613 | LUAMOD_API int luaopen_io (lua_State *L) { |
614 | lua_settop(L, 0); | ||
603 | createmeta(L); | 615 | createmeta(L); |
604 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ | 616 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ |
605 | newfenv(L, io_fclose); | 617 | newenv(L, io_fclose); /* upvalue for all io functions at index 1 */ |
606 | lua_replace(L, LUA_ENVIRONINDEX); | 618 | lua_pushvalue(L, -1); /* copy to be consumed by 'openlib' */ |
607 | /* open library */ | 619 | luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* new module at index 2 */ |
608 | luaL_register(L, LUA_IOLIBNAME, iolib); | ||
609 | /* create (and set) default files */ | 620 | /* create (and set) default files */ |
610 | newfenv(L, io_noclose); /* close function for default files */ | 621 | newenv(L, io_noclose); /* environment for default files at index 3 */ |
611 | createstdfile(L, stdin, IO_INPUT, "stdin"); | 622 | createstdfile(L, stdin, IO_INPUT, "stdin"); |
612 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); | 623 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); |
613 | createstdfile(L, stderr, 0, "stderr"); | 624 | createstdfile(L, stderr, 0, "stderr"); |
614 | lua_pop(L, 1); /* pop environment for default files */ | 625 | lua_pop(L, 1); /* pop environment for default files */ |
615 | lua_getfield(L, -1, "popen"); | 626 | lua_getfield(L, 2, "popen"); |
616 | newfenv(L, io_pclose); /* create environment for 'popen' */ | 627 | newenv(L, io_pclose); /* create environment for 'popen' streams */ |
617 | lua_setfenv(L, -2); /* set fenv for 'popen' */ | 628 | lua_setupvalue(L, -2, 1); /* set it as upvalue for 'popen' */ |
618 | lua_pop(L, 1); /* pop 'popen' */ | 629 | lua_pop(L, 1); /* pop 'popen' */ |
619 | return 1; | 630 | return 1; |
620 | } | 631 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loadlib.c,v 1.79 2010/01/13 16:09:05 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.80 2010/01/13 16:30:27 roberto Exp roberto $ |
3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | ** | 5 | ** |
@@ -353,9 +353,7 @@ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { | |||
353 | lua_CFunction f = ll_sym(L, *reg, sym); | 353 | lua_CFunction f = ll_sym(L, *reg, sym); |
354 | if (f == NULL) | 354 | if (f == NULL) |
355 | return ERRFUNC; /* unable to find function */ | 355 | return ERRFUNC; /* unable to find function */ |
356 | lua_pushcfunction(L, f); /* else create new function... */ | 356 | lua_pushcfunction(L, f); /* else create new function */ |
357 | lua_pushglobaltable(L); /* ... and set the standard global table... */ | ||
358 | lua_setfenv(L, -2); /* ... as its environment */ | ||
359 | return 0; /* no errors */ | 357 | return 0; /* no errors */ |
360 | } | 358 | } |
361 | } | 359 | } |
@@ -435,7 +433,7 @@ static int ll_searchpath (lua_State *L) { | |||
435 | static const char *findfile (lua_State *L, const char *name, | 433 | static const char *findfile (lua_State *L, const char *name, |
436 | const char *pname) { | 434 | const char *pname) { |
437 | const char *path; | 435 | const char *path; |
438 | lua_getfield(L, LUA_ENVIRONINDEX, pname); | 436 | lua_getfield(L, lua_upvalueindex(1), pname); |
439 | path = lua_tostring(L, -1); | 437 | path = lua_tostring(L, -1); |
440 | if (path == NULL) | 438 | if (path == NULL) |
441 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | 439 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); |
@@ -509,7 +507,7 @@ static int loader_Croot (lua_State *L) { | |||
509 | 507 | ||
510 | static int loader_preload (lua_State *L) { | 508 | static int loader_preload (lua_State *L) { |
511 | const char *name = luaL_checkstring(L, 1); | 509 | const char *name = luaL_checkstring(L, 1); |
512 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | 510 | lua_getfield(L, lua_upvalueindex(1), "preload"); |
513 | if (!lua_istable(L, -1)) | 511 | if (!lua_istable(L, -1)) |
514 | luaL_error(L, LUA_QL("package.preload") " must be a table"); | 512 | luaL_error(L, LUA_QL("package.preload") " must be a table"); |
515 | lua_getfield(L, -1, name); | 513 | lua_getfield(L, -1, name); |
@@ -535,7 +533,7 @@ static int ll_require (lua_State *L) { | |||
535 | return 1; /* package is already loaded */ | 533 | return 1; /* package is already loaded */ |
536 | } | 534 | } |
537 | /* else must load it; iterate over available loaders */ | 535 | /* else must load it; iterate over available loaders */ |
538 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | 536 | lua_getfield(L, lua_upvalueindex(1), "loaders"); |
539 | if (!lua_istable(L, -1)) | 537 | if (!lua_istable(L, -1)) |
540 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); | 538 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); |
541 | lua_pushliteral(L, ""); /* error message accumulator */ | 539 | lua_pushliteral(L, ""); /* error message accumulator */ |
@@ -709,12 +707,12 @@ LUAMOD_API int luaopen_package (lua_State *L) { | |||
709 | lua_setfield(L, -2, "__gc"); | 707 | lua_setfield(L, -2, "__gc"); |
710 | /* create `package' table */ | 708 | /* create `package' table */ |
711 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); | 709 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); |
712 | lua_copy(L, -1, LUA_ENVIRONINDEX); | ||
713 | /* create `loaders' table */ | 710 | /* create `loaders' table */ |
714 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); | 711 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); |
715 | /* fill it with pre-defined loaders */ | 712 | /* fill it with pre-defined loaders */ |
716 | for (i=0; loaders[i] != NULL; i++) { | 713 | for (i=0; loaders[i] != NULL; i++) { |
717 | lua_pushcfunction(L, loaders[i]); | 714 | lua_pushvalue(L, -2); /* set 'package' as upvalue for all loaders */ |
715 | lua_pushcclosure(L, loaders[i], 1); | ||
718 | lua_rawseti(L, -2, i+1); | 716 | lua_rawseti(L, -2, i+1); |
719 | } | 717 | } |
720 | lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ | 718 | lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ |
@@ -731,8 +729,9 @@ LUAMOD_API int luaopen_package (lua_State *L) { | |||
731 | lua_newtable(L); | 729 | lua_newtable(L); |
732 | lua_setfield(L, -2, "preload"); | 730 | lua_setfield(L, -2, "preload"); |
733 | lua_pushglobaltable(L); | 731 | lua_pushglobaltable(L); |
734 | luaL_register(L, NULL, ll_funcs); /* open lib into global table */ | 732 | lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ |
735 | lua_pop(L, 1); | 733 | luaL_openlib(L, NULL, ll_funcs, 1); /* open lib into global table */ |
734 | lua_pop(L, 1); /* pop global table */ | ||
736 | return 1; /* return 'package' table */ | 735 | return 1; /* return 'package' table */ |
737 | } | 736 | } |
738 | 737 | ||