root/lib_package.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ll_unloadlib
  2. ll_load
  3. ll_sym
  4. ll_bcsym
  5. setprogdir
  6. pusherror
  7. ll_unloadlib
  8. ll_load
  9. ll_sym
  10. ll_bcsym
  11. ll_unloadlib
  12. ll_load
  13. ll_sym
  14. ll_bcsym
  15. ll_register
  16. mksymname
  17. ll_loadfunc
  18. lj_cf_package_loadlib
  19. lj_cf_package_unloadlib
  20. readable
  21. pushnexttemplate
  22. searchpath
  23. lj_cf_package_searchpath
  24. findfile
  25. loaderror
  26. lj_cf_package_loader_lua
  27. lj_cf_package_loader_c
  28. lj_cf_package_loader_croot
  29. lj_cf_package_loader_preload
  30. lj_cf_package_require
  31. setfenv
  32. dooptions
  33. modinit
  34. lj_cf_package_module
  35. lj_cf_package_seeall
  36. setpath
  37. luaopen_package

   1 /*
   2 ** Package library.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 **
   5 ** Major portions taken verbatim or adapted from the Lua interpreter.
   6 ** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
   7 */
   8 
   9 #define lib_package_c
  10 #define LUA_LIB
  11 
  12 #include "lua.h"
  13 #include "lauxlib.h"
  14 #include "lualib.h"
  15 
  16 #include "lj_obj.h"
  17 #include "lj_err.h"
  18 #include "lj_lib.h"
  19 
  20 /* ------------------------------------------------------------------------ */
  21 
  22 /* Error codes for ll_loadfunc. */
  23 #define PACKAGE_ERR_LIB         1
  24 #define PACKAGE_ERR_FUNC        2
  25 #define PACKAGE_ERR_LOAD        3
  26 
  27 /* Redefined in platform specific part. */
  28 #define PACKAGE_LIB_FAIL        "open"
  29 #define setprogdir(L)           ((void)0)
  30 
  31 /* Symbol name prefixes. */
  32 #define SYMPREFIX_CF            "luaopen_%s"
  33 #define SYMPREFIX_BC            "luaJIT_BC_%s"
  34 
  35 #if LJ_TARGET_DLOPEN
  36 
  37 #include <dlfcn.h>
  38 
  39 static void ll_unloadlib(void *lib)
  40 {
  41   dlclose(lib);
  42 }
  43 
  44 static void *ll_load(lua_State *L, const char *path, int gl)
  45 {
  46   void *lib = dlopen(path, RTLD_NOW | (gl ? RTLD_GLOBAL : RTLD_LOCAL));
  47   if (lib == NULL) lua_pushstring(L, dlerror());
  48   return lib;
  49 }
  50 
  51 static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
  52 {
  53   lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
  54   if (f == NULL) lua_pushstring(L, dlerror());
  55   return f;
  56 }
  57 
  58 static const char *ll_bcsym(void *lib, const char *sym)
  59 {
  60 #if defined(RTLD_DEFAULT)
  61   if (lib == NULL) lib = RTLD_DEFAULT;
  62 #elif LJ_TARGET_OSX || LJ_TARGET_BSD
  63   if (lib == NULL) lib = (void *)(intptr_t)-2;
  64 #endif
  65   return (const char *)dlsym(lib, sym);
  66 }
  67 
  68 #elif LJ_TARGET_WINDOWS
  69 
  70 #define WIN32_LEAN_AND_MEAN
  71 #include <windows.h>
  72 
  73 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
  74 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS  4
  75 #define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT  2
  76 BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
  77 #endif
  78 
  79 #undef setprogdir
  80 
  81 static void setprogdir(lua_State *L)
  82 {
  83   char buff[MAX_PATH + 1];
  84   char *lb;
  85   DWORD nsize = sizeof(buff);
  86   DWORD n = GetModuleFileNameA(NULL, buff, nsize);
  87   if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) {
  88     luaL_error(L, "unable to get ModuleFileName");
  89   } else {
  90     *lb = '\0';
  91     luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
  92     lua_remove(L, -2);  /* remove original string */
  93   }
  94 }
  95 
  96 static void pusherror(lua_State *L)
  97 {
  98   DWORD error = GetLastError();
  99 #if LJ_TARGET_XBOXONE
 100   wchar_t wbuffer[128];
 101   char buffer[128*2];
 102   if (FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
 103       NULL, error, 0, wbuffer, sizeof(wbuffer)/sizeof(wchar_t), NULL) &&
 104       WideCharToMultiByte(CP_ACP, 0, wbuffer, 128, buffer, 128*2, NULL, NULL))
 105 #else
 106   char buffer[128];
 107   if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
 108       NULL, error, 0, buffer, sizeof(buffer), NULL))
 109 #endif
 110     lua_pushstring(L, buffer);
 111   else
 112     lua_pushfstring(L, "system error %d\n", error);
 113 }
 114 
 115 static void ll_unloadlib(void *lib)
 116 {
 117   FreeLibrary((HINSTANCE)lib);
 118 }
 119 
 120 static void *ll_load(lua_State *L, const char *path, int gl)
 121 {
 122   HINSTANCE lib = LoadLibraryExA(path, NULL, 0);
 123   if (lib == NULL) pusherror(L);
 124   UNUSED(gl);
 125   return lib;
 126 }
 127 
 128 static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
 129 {
 130   lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
 131   if (f == NULL) pusherror(L);
 132   return f;
 133 }
 134 
 135 static const char *ll_bcsym(void *lib, const char *sym)
 136 {
 137   if (lib) {
 138     return (const char *)GetProcAddress((HINSTANCE)lib, sym);
 139   } else {
 140     HINSTANCE h = GetModuleHandleA(NULL);
 141     const char *p = (const char *)GetProcAddress(h, sym);
 142     if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
 143                                         (const char *)ll_bcsym, &h))
 144       p = (const char *)GetProcAddress(h, sym);
 145     return p;
 146   }
 147 }
 148 
 149 #else
 150 
 151 #undef PACKAGE_LIB_FAIL
 152 #define PACKAGE_LIB_FAIL        "absent"
 153 
 154 #define DLMSG   "dynamic libraries not enabled; no support for target OS"
 155 
 156 static void ll_unloadlib(void *lib)
 157 {
 158   UNUSED(lib);
 159 }
 160 
 161 static void *ll_load(lua_State *L, const char *path, int gl)
 162 {
 163   UNUSED(path); UNUSED(gl);
 164   lua_pushliteral(L, DLMSG);
 165   return NULL;
 166 }
 167 
 168 static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
 169 {
 170   UNUSED(lib); UNUSED(sym);
 171   lua_pushliteral(L, DLMSG);
 172   return NULL;
 173 }
 174 
 175 static const char *ll_bcsym(void *lib, const char *sym)
 176 {
 177   UNUSED(lib); UNUSED(sym);
 178   return NULL;
 179 }
 180 
 181 #endif
 182 
 183 /* ------------------------------------------------------------------------ */
 184 
 185 static void **ll_register(lua_State *L, const char *path)
 186 {
 187   void **plib;
 188   lua_pushfstring(L, "LOADLIB: %s", path);
 189   lua_gettable(L, LUA_REGISTRYINDEX);  /* check library in registry? */
 190   if (!lua_isnil(L, -1)) {  /* is there an entry? */
 191     plib = (void **)lua_touserdata(L, -1);
 192   } else {  /* no entry yet; create one */
 193     lua_pop(L, 1);
 194     plib = (void **)lua_newuserdata(L, sizeof(void *));
 195     *plib = NULL;
 196     luaL_setmetatable(L, "_LOADLIB");
 197     lua_pushfstring(L, "LOADLIB: %s", path);
 198     lua_pushvalue(L, -2);
 199     lua_settable(L, LUA_REGISTRYINDEX);
 200   }
 201   return plib;
 202 }
 203 
 204 static const char *mksymname(lua_State *L, const char *modname,
 205                              const char *prefix)
 206 {
 207   const char *funcname;
 208   const char *mark = strchr(modname, *LUA_IGMARK);
 209   if (mark) modname = mark + 1;
 210   funcname = luaL_gsub(L, modname, ".", "_");
 211   funcname = lua_pushfstring(L, prefix, funcname);
 212   lua_remove(L, -2);  /* remove 'gsub' result */
 213   return funcname;
 214 }
 215 
 216 static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
 217 {
 218   void **reg = ll_register(L, path);
 219   if (*reg == NULL) *reg = ll_load(L, path, (*name == '*'));
 220   if (*reg == NULL) {
 221     return PACKAGE_ERR_LIB;  /* Unable to load library. */
 222   } else if (*name == '*') {  /* Only load library into global namespace. */
 223     lua_pushboolean(L, 1);
 224     return 0;
 225   } else {
 226     const char *sym = r ? name : mksymname(L, name, SYMPREFIX_CF);
 227     lua_CFunction f = ll_sym(L, *reg, sym);
 228     if (f) {
 229       lua_pushcfunction(L, f);
 230       return 0;
 231     }
 232     if (!r) {
 233       const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
 234       lua_pop(L, 1);
 235       if (bcdata) {
 236         if (luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
 237           return PACKAGE_ERR_LOAD;
 238         return 0;
 239       }
 240     }
 241     return PACKAGE_ERR_FUNC;  /* Unable to find function. */
 242   }
 243 }
 244 
 245 static int lj_cf_package_loadlib(lua_State *L)
 246 {
 247   const char *path = luaL_checkstring(L, 1);
 248   const char *init = luaL_checkstring(L, 2);
 249   int st = ll_loadfunc(L, path, init, 1);
 250   if (st == 0) {  /* no errors? */
 251     return 1;  /* return the loaded function */
 252   } else {  /* error; error message is on stack top */
 253     lua_pushnil(L);
 254     lua_insert(L, -2);
 255     lua_pushstring(L, (st == PACKAGE_ERR_LIB) ?  PACKAGE_LIB_FAIL : "init");
 256     return 3;  /* return nil, error message, and where */
 257   }
 258 }
 259 
 260 static int lj_cf_package_unloadlib(lua_State *L)
 261 {
 262   void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
 263   if (*lib) ll_unloadlib(*lib);
 264   *lib = NULL;  /* mark library as closed */
 265   return 0;
 266 }
 267 
 268 /* ------------------------------------------------------------------------ */
 269 
 270 static int readable(const char *filename)
 271 {
 272   FILE *f = fopen(filename, "r");  /* try to open file */
 273   if (f == NULL) return 0;  /* open failed */
 274   fclose(f);
 275   return 1;
 276 }
 277 
 278 static const char *pushnexttemplate(lua_State *L, const char *path)
 279 {
 280   const char *l;
 281   while (*path == *LUA_PATHSEP) path++;  /* skip separators */
 282   if (*path == '\0') return NULL;  /* no more templates */
 283   l = strchr(path, *LUA_PATHSEP);  /* find next separator */
 284   if (l == NULL) l = path + strlen(path);
 285   lua_pushlstring(L, path, (size_t)(l - path));  /* template */
 286   return l;
 287 }
 288 
 289 static const char *searchpath (lua_State *L, const char *name,
 290                                const char *path, const char *sep,
 291                                const char *dirsep)
 292 {
 293   luaL_Buffer msg;  /* to build error message */
 294   luaL_buffinit(L, &msg);
 295   if (*sep != '\0')  /* non-empty separator? */
 296     name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
 297   while ((path = pushnexttemplate(L, path)) != NULL) {
 298     const char *filename = luaL_gsub(L, lua_tostring(L, -1),
 299                                      LUA_PATH_MARK, name);
 300     lua_remove(L, -2);  /* remove path template */
 301     if (readable(filename))  /* does file exist and is readable? */
 302       return filename;  /* return that file name */
 303     lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
 304     lua_remove(L, -2);  /* remove file name */
 305     luaL_addvalue(&msg);  /* concatenate error msg. entry */
 306   }
 307   luaL_pushresult(&msg);  /* create error message */
 308   return NULL;  /* not found */
 309 }
 310 
 311 static int lj_cf_package_searchpath(lua_State *L)
 312 {
 313   const char *f = searchpath(L, luaL_checkstring(L, 1),
 314                                 luaL_checkstring(L, 2),
 315                                 luaL_optstring(L, 3, "."),
 316                                 luaL_optstring(L, 4, LUA_DIRSEP));
 317   if (f != NULL) {
 318     return 1;
 319   } else {  /* error message is on top of the stack */
 320     lua_pushnil(L);
 321     lua_insert(L, -2);
 322     return 2;  /* return nil + error message */
 323   }
 324 }
 325 
 326 static const char *findfile(lua_State *L, const char *name,
 327                             const char *pname)
 328 {
 329   const char *path;
 330   lua_getfield(L, LUA_ENVIRONINDEX, pname);
 331   path = lua_tostring(L, -1);
 332   if (path == NULL)
 333     luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
 334   return searchpath(L, name, path, ".", LUA_DIRSEP);
 335 }
 336 
 337 static void loaderror(lua_State *L, const char *filename)
 338 {
 339   luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
 340              lua_tostring(L, 1), filename, lua_tostring(L, -1));
 341 }
 342 
 343 static int lj_cf_package_loader_lua(lua_State *L)
 344 {
 345   const char *filename;
 346   const char *name = luaL_checkstring(L, 1);
 347   filename = findfile(L, name, "path");
 348   if (filename == NULL) return 1;  /* library not found in this path */
 349   if (luaL_loadfile(L, filename) != 0)
 350     loaderror(L, filename);
 351   return 1;  /* library loaded successfully */
 352 }
 353 
 354 static int lj_cf_package_loader_c(lua_State *L)
 355 {
 356   const char *name = luaL_checkstring(L, 1);
 357   const char *filename = findfile(L, name, "cpath");
 358   if (filename == NULL) return 1;  /* library not found in this path */
 359   if (ll_loadfunc(L, filename, name, 0) != 0)
 360     loaderror(L, filename);
 361   return 1;  /* library loaded successfully */
 362 }
 363 
 364 static int lj_cf_package_loader_croot(lua_State *L)
 365 {
 366   const char *filename;
 367   const char *name = luaL_checkstring(L, 1);
 368   const char *p = strchr(name, '.');
 369   int st;
 370   if (p == NULL) return 0;  /* is root */
 371   lua_pushlstring(L, name, (size_t)(p - name));
 372   filename = findfile(L, lua_tostring(L, -1), "cpath");
 373   if (filename == NULL) return 1;  /* root not found */
 374   if ((st = ll_loadfunc(L, filename, name, 0)) != 0) {
 375     if (st != PACKAGE_ERR_FUNC) loaderror(L, filename);  /* real error */
 376     lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
 377                     name, filename);
 378     return 1;  /* function not found */
 379   }
 380   return 1;
 381 }
 382 
 383 static int lj_cf_package_loader_preload(lua_State *L)
 384 {
 385   const char *name = luaL_checkstring(L, 1);
 386   lua_getfield(L, LUA_ENVIRONINDEX, "preload");
 387   if (!lua_istable(L, -1))
 388     luaL_error(L, LUA_QL("package.preload") " must be a table");
 389   lua_getfield(L, -1, name);
 390   if (lua_isnil(L, -1)) {  /* Not found? */
 391     const char *bcname = mksymname(L, name, SYMPREFIX_BC);
 392     const char *bcdata = ll_bcsym(NULL, bcname);
 393     if (bcdata == NULL || luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
 394       lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
 395   }
 396   return 1;
 397 }
 398 
 399 /* ------------------------------------------------------------------------ */
 400 
 401 #define sentinel        ((void *)0x4004)
 402 
 403 static int lj_cf_package_require(lua_State *L)
 404 {
 405   const char *name = luaL_checkstring(L, 1);
 406   int i;
 407   lua_settop(L, 1);  /* _LOADED table will be at index 2 */
 408   lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
 409   lua_getfield(L, 2, name);
 410   if (lua_toboolean(L, -1)) {  /* is it there? */
 411     if (lua_touserdata(L, -1) == sentinel)  /* check loops */
 412       luaL_error(L, "loop or previous error loading module " LUA_QS, name);
 413     return 1;  /* package is already loaded */
 414   }
 415   /* else must load it; iterate over available loaders */
 416   lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
 417   if (!lua_istable(L, -1))
 418     luaL_error(L, LUA_QL("package.loaders") " must be a table");
 419   lua_pushliteral(L, "");  /* error message accumulator */
 420   for (i = 1; ; i++) {
 421     lua_rawgeti(L, -2, i);  /* get a loader */
 422     if (lua_isnil(L, -1))
 423       luaL_error(L, "module " LUA_QS " not found:%s",
 424                  name, lua_tostring(L, -2));
 425     lua_pushstring(L, name);
 426     lua_call(L, 1, 1);  /* call it */
 427     if (lua_isfunction(L, -1))  /* did it find module? */
 428       break;  /* module loaded successfully */
 429     else if (lua_isstring(L, -1))  /* loader returned error message? */
 430       lua_concat(L, 2);  /* accumulate it */
 431     else
 432       lua_pop(L, 1);
 433   }
 434   lua_pushlightuserdata(L, sentinel);
 435   lua_setfield(L, 2, name);  /* _LOADED[name] = sentinel */
 436   lua_pushstring(L, name);  /* pass name as argument to module */
 437   lua_call(L, 1, 1);  /* run loaded module */
 438   if (!lua_isnil(L, -1))  /* non-nil return? */
 439     lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
 440   lua_getfield(L, 2, name);
 441   if (lua_touserdata(L, -1) == sentinel) {   /* module did not set a value? */
 442     lua_pushboolean(L, 1);  /* use true as result */
 443     lua_pushvalue(L, -1);  /* extra copy to be returned */
 444     lua_setfield(L, 2, name);  /* _LOADED[name] = true */
 445   }
 446   lj_lib_checkfpu(L);
 447   return 1;
 448 }
 449 
 450 /* ------------------------------------------------------------------------ */
 451 
 452 static void setfenv(lua_State *L)
 453 {
 454   lua_Debug ar;
 455   if (lua_getstack(L, 1, &ar) == 0 ||
 456       lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
 457       lua_iscfunction(L, -1))
 458     luaL_error(L, LUA_QL("module") " not called from a Lua function");
 459   lua_pushvalue(L, -2);
 460   lua_setfenv(L, -2);
 461   lua_pop(L, 1);
 462 }
 463 
 464 static void dooptions(lua_State *L, int n)
 465 {
 466   int i;
 467   for (i = 2; i <= n; i++) {
 468     lua_pushvalue(L, i);  /* get option (a function) */
 469     lua_pushvalue(L, -2);  /* module */
 470     lua_call(L, 1, 0);
 471   }
 472 }
 473 
 474 static void modinit(lua_State *L, const char *modname)
 475 {
 476   const char *dot;
 477   lua_pushvalue(L, -1);
 478   lua_setfield(L, -2, "_M");  /* module._M = module */
 479   lua_pushstring(L, modname);
 480   lua_setfield(L, -2, "_NAME");
 481   dot = strrchr(modname, '.');  /* look for last dot in module name */
 482   if (dot == NULL) dot = modname; else dot++;
 483   /* set _PACKAGE as package name (full module name minus last part) */
 484   lua_pushlstring(L, modname, (size_t)(dot - modname));
 485   lua_setfield(L, -2, "_PACKAGE");
 486 }
 487 
 488 static int lj_cf_package_module(lua_State *L)
 489 {
 490   const char *modname = luaL_checkstring(L, 1);
 491   int lastarg = (int)(L->top - L->base);
 492   luaL_pushmodule(L, modname, 1);
 493   lua_getfield(L, -1, "_NAME");
 494   if (!lua_isnil(L, -1)) {  /* Module already initialized? */
 495     lua_pop(L, 1);
 496   } else {
 497     lua_pop(L, 1);
 498     modinit(L, modname);
 499   }
 500   lua_pushvalue(L, -1);
 501   setfenv(L);
 502   dooptions(L, lastarg);
 503   return LJ_52;
 504 }
 505 
 506 static int lj_cf_package_seeall(lua_State *L)
 507 {
 508   luaL_checktype(L, 1, LUA_TTABLE);
 509   if (!lua_getmetatable(L, 1)) {
 510     lua_createtable(L, 0, 1); /* create new metatable */
 511     lua_pushvalue(L, -1);
 512     lua_setmetatable(L, 1);
 513   }
 514   lua_pushvalue(L, LUA_GLOBALSINDEX);
 515   lua_setfield(L, -2, "__index");  /* mt.__index = _G */
 516   return 0;
 517 }
 518 
 519 /* ------------------------------------------------------------------------ */
 520 
 521 #define AUXMARK         "\1"
 522 
 523 static void setpath(lua_State *L, const char *fieldname, const char *envname,
 524                     const char *def, int noenv)
 525 {
 526 #if LJ_TARGET_CONSOLE
 527   const char *path = NULL;
 528   UNUSED(envname);
 529 #else
 530   const char *path = getenv(envname);
 531 #endif
 532   if (path == NULL || noenv) {
 533     lua_pushstring(L, def);
 534   } else {
 535     path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
 536                               LUA_PATHSEP AUXMARK LUA_PATHSEP);
 537     luaL_gsub(L, path, AUXMARK, def);
 538     lua_remove(L, -2);
 539   }
 540   setprogdir(L);
 541   lua_setfield(L, -2, fieldname);
 542 }
 543 
 544 static const luaL_Reg package_lib[] = {
 545   { "loadlib",  lj_cf_package_loadlib },
 546   { "searchpath",  lj_cf_package_searchpath },
 547   { "seeall",   lj_cf_package_seeall },
 548   { NULL, NULL }
 549 };
 550 
 551 static const luaL_Reg package_global[] = {
 552   { "module",   lj_cf_package_module },
 553   { "require",  lj_cf_package_require },
 554   { NULL, NULL }
 555 };
 556 
 557 static const lua_CFunction package_loaders[] =
 558 {
 559   lj_cf_package_loader_preload,
 560   lj_cf_package_loader_lua,
 561   lj_cf_package_loader_c,
 562   lj_cf_package_loader_croot,
 563   NULL
 564 };
 565 
 566 LUALIB_API int luaopen_package(lua_State *L)
 567 {
 568   int i;
 569   int noenv;
 570   luaL_newmetatable(L, "_LOADLIB");
 571   lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
 572   lua_setfield(L, -2, "__gc");
 573   luaL_register(L, LUA_LOADLIBNAME, package_lib);
 574   lua_copy(L, -1, LUA_ENVIRONINDEX);
 575   lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
 576   for (i = 0; package_loaders[i] != NULL; i++) {
 577     lj_lib_pushcf(L, package_loaders[i], 1);
 578     lua_rawseti(L, -2, i+1);
 579   }
 580 #if LJ_52
 581   lua_pushvalue(L, -1);
 582   lua_setfield(L, -3, "searchers");
 583 #endif
 584   lua_setfield(L, -2, "loaders");
 585   lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
 586   noenv = lua_toboolean(L, -1);
 587   lua_pop(L, 1);
 588   setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT, noenv);
 589   setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT, noenv);
 590   lua_pushliteral(L, LUA_PATH_CONFIG);
 591   lua_setfield(L, -2, "config");
 592   luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
 593   lua_setfield(L, -2, "loaded");
 594   luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
 595   lua_setfield(L, -2, "preload");
 596   lua_pushvalue(L, LUA_GLOBALSINDEX);
 597   luaL_register(L, NULL, package_global);
 598   lua_pop(L, 1);
 599   return 1;
 600 }
 601 

/* [<][>][^][v][top][bottom][index][help] */