aboutsummaryrefslogtreecommitdiff
path: root/src/lib_package.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_package.c')
-rw-r--r--src/lib_package.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/src/lib_package.c b/src/lib_package.c
index a9c1ca48..1f8b0677 100644
--- a/src/lib_package.c
+++ b/src/lib_package.c
@@ -76,6 +76,20 @@ static const char *ll_bcsym(void *lib, const char *sym)
76BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); 76BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
77#endif 77#endif
78 78
79#if LJ_TARGET_UWP
80void *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
79#undef setprogdir 93#undef setprogdir
80 94
81static void setprogdir(lua_State *L) 95static void setprogdir(lua_State *L)
@@ -96,9 +110,17 @@ static void setprogdir(lua_State *L)
96static void pusherror(lua_State *L) 110static void pusherror(lua_State *L)
97{ 111{
98 DWORD error = GetLastError(); 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
99 char buffer[128]; 120 char buffer[128];
100 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 121 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
101 NULL, error, 0, buffer, sizeof(buffer), NULL)) 122 NULL, error, 0, buffer, sizeof(buffer), NULL))
123#endif
102 lua_pushstring(L, buffer); 124 lua_pushstring(L, buffer);
103 else 125 else
104 lua_pushfstring(L, "system error %d\n", error); 126 lua_pushfstring(L, "system error %d\n", error);
@@ -111,7 +133,7 @@ static void ll_unloadlib(void *lib)
111 133
112static void *ll_load(lua_State *L, const char *path, int gl) 134static void *ll_load(lua_State *L, const char *path, int gl)
113{ 135{
114 HINSTANCE lib = LoadLibraryA(path); 136 HINSTANCE lib = LJ_WIN_LOADLIBA(path);
115 if (lib == NULL) pusherror(L); 137 if (lib == NULL) pusherror(L);
116 UNUSED(gl); 138 UNUSED(gl);
117 return lib; 139 return lib;
@@ -124,17 +146,25 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
124 return f; 146 return f;
125} 147}
126 148
149#if LJ_TARGET_UWP
150EXTERN_C IMAGE_DOS_HEADER __ImageBase;
151#endif
152
127static const char *ll_bcsym(void *lib, const char *sym) 153static const char *ll_bcsym(void *lib, const char *sym)
128{ 154{
129 if (lib) { 155 if (lib) {
130 return (const char *)GetProcAddress((HINSTANCE)lib, sym); 156 return (const char *)GetProcAddress((HINSTANCE)lib, sym);
131 } else { 157 } else {
158#if LJ_TARGET_UWP
159 return (const char *)GetProcAddress((HINSTANCE)&__ImageBase, sym);
160#else
132 HINSTANCE h = GetModuleHandleA(NULL); 161 HINSTANCE h = GetModuleHandleA(NULL);
133 const char *p = (const char *)GetProcAddress(h, sym); 162 const char *p = (const char *)GetProcAddress(h, sym);
134 if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 163 if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
135 (const char *)ll_bcsym, &h)) 164 (const char *)ll_bcsym, &h))
136 p = (const char *)GetProcAddress(h, sym); 165 p = (const char *)GetProcAddress(h, sym);
137 return p; 166 return p;
167#endif
138 } 168 }
139} 169}
140 170
@@ -185,8 +215,7 @@ static void **ll_register(lua_State *L, const char *path)
185 lua_pop(L, 1); 215 lua_pop(L, 1);
186 plib = (void **)lua_newuserdata(L, sizeof(void *)); 216 plib = (void **)lua_newuserdata(L, sizeof(void *));
187 *plib = NULL; 217 *plib = NULL;
188 luaL_getmetatable(L, "_LOADLIB"); 218 luaL_setmetatable(L, "_LOADLIB");
189 lua_setmetatable(L, -2);
190 lua_pushfstring(L, "LOADLIB: %s", path); 219 lua_pushfstring(L, "LOADLIB: %s", path);
191 lua_pushvalue(L, -2); 220 lua_pushvalue(L, -2);
192 lua_settable(L, LUA_REGISTRYINDEX); 221 lua_settable(L, LUA_REGISTRYINDEX);
@@ -396,8 +425,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
396 425
397/* ------------------------------------------------------------------------ */ 426/* ------------------------------------------------------------------------ */
398 427
399static const int sentinel_ = 0; 428#define KEY_SENTINEL (U64x(80000000,00000000)|'s')
400#define sentinel ((void *)&sentinel_)
401 429
402static int lj_cf_package_require(lua_State *L) 430static int lj_cf_package_require(lua_State *L)
403{ 431{
@@ -407,7 +435,7 @@ static int lj_cf_package_require(lua_State *L)
407 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 435 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
408 lua_getfield(L, 2, name); 436 lua_getfield(L, 2, name);
409 if (lua_toboolean(L, -1)) { /* is it there? */ 437 if (lua_toboolean(L, -1)) { /* is it there? */
410 if (lua_touserdata(L, -1) == sentinel) /* check loops */ 438 if ((L->top-1)->u64 == KEY_SENTINEL) /* check loops */
411 luaL_error(L, "loop or previous error loading module " LUA_QS, name); 439 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
412 return 1; /* package is already loaded */ 440 return 1; /* package is already loaded */
413 } 441 }
@@ -430,14 +458,14 @@ static int lj_cf_package_require(lua_State *L)
430 else 458 else
431 lua_pop(L, 1); 459 lua_pop(L, 1);
432 } 460 }
433 lua_pushlightuserdata(L, sentinel); 461 (L->top++)->u64 = KEY_SENTINEL;
434 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ 462 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
435 lua_pushstring(L, name); /* pass name as argument to module */ 463 lua_pushstring(L, name); /* pass name as argument to module */
436 lua_call(L, 1, 1); /* run loaded module */ 464 lua_call(L, 1, 1); /* run loaded module */
437 if (!lua_isnil(L, -1)) /* non-nil return? */ 465 if (!lua_isnil(L, -1)) /* non-nil return? */
438 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 466 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
439 lua_getfield(L, 2, name); 467 lua_getfield(L, 2, name);
440 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ 468 if ((L->top-1)->u64 == KEY_SENTINEL) { /* module did not set a value? */
441 lua_pushboolean(L, 1); /* use true as result */ 469 lua_pushboolean(L, 1); /* use true as result */
442 lua_pushvalue(L, -1); /* extra copy to be returned */ 470 lua_pushvalue(L, -1); /* extra copy to be returned */
443 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 471 lua_setfield(L, 2, name); /* _LOADED[name] = true */
@@ -487,29 +515,19 @@ static void modinit(lua_State *L, const char *modname)
487static int lj_cf_package_module(lua_State *L) 515static int lj_cf_package_module(lua_State *L)
488{ 516{
489 const char *modname = luaL_checkstring(L, 1); 517 const char *modname = luaL_checkstring(L, 1);
490 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ 518 int lastarg = (int)(L->top - L->base);
491 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 519 luaL_pushmodule(L, modname, 1);
492 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
493 if (!lua_istable(L, -1)) { /* not found? */
494 lua_pop(L, 1); /* remove previous result */
495 /* try global variable (and create one if it does not exist) */
496 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
497 lj_err_callerv(L, LJ_ERR_BADMODN, modname);
498 lua_pushvalue(L, -1);
499 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
500 }
501 /* check whether table already has a _NAME field */
502 lua_getfield(L, -1, "_NAME"); 520 lua_getfield(L, -1, "_NAME");
503 if (!lua_isnil(L, -1)) { /* is table an initialized module? */ 521 if (!lua_isnil(L, -1)) { /* Module already initialized? */
504 lua_pop(L, 1); 522 lua_pop(L, 1);
505 } else { /* no; initialize it */ 523 } else {
506 lua_pop(L, 1); 524 lua_pop(L, 1);
507 modinit(L, modname); 525 modinit(L, modname);
508 } 526 }
509 lua_pushvalue(L, -1); 527 lua_pushvalue(L, -1);
510 setfenv(L); 528 setfenv(L);
511 dooptions(L, loaded - 1); 529 dooptions(L, lastarg);
512 return 0; 530 return LJ_52;
513} 531}
514 532
515static int lj_cf_package_seeall(lua_State *L) 533static int lj_cf_package_seeall(lua_State *L)
@@ -580,13 +598,16 @@ LUALIB_API int luaopen_package(lua_State *L)
580 lj_lib_pushcf(L, lj_cf_package_unloadlib, 1); 598 lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
581 lua_setfield(L, -2, "__gc"); 599 lua_setfield(L, -2, "__gc");
582 luaL_register(L, LUA_LOADLIBNAME, package_lib); 600 luaL_register(L, LUA_LOADLIBNAME, package_lib);
583 lua_pushvalue(L, -1); 601 lua_copy(L, -1, LUA_ENVIRONINDEX);
584 lua_replace(L, LUA_ENVIRONINDEX);
585 lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0); 602 lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
586 for (i = 0; package_loaders[i] != NULL; i++) { 603 for (i = 0; package_loaders[i] != NULL; i++) {
587 lj_lib_pushcf(L, package_loaders[i], 1); 604 lj_lib_pushcf(L, package_loaders[i], 1);
588 lua_rawseti(L, -2, i+1); 605 lua_rawseti(L, -2, i+1);
589 } 606 }
607#if LJ_52
608 lua_pushvalue(L, -1);
609 lua_setfield(L, -3, "searchers");
610#endif
590 lua_setfield(L, -2, "loaders"); 611 lua_setfield(L, -2, "loaders");
591 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 612 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
592 noenv = lua_toboolean(L, -1); 613 noenv = lua_toboolean(L, -1);