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

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