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