diff options
Diffstat (limited to 'src/lib_package.c')
-rw-r--r-- | src/lib_package.c | 73 |
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) | |||
76 | BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); | 76 | BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); |
77 | #endif | 77 | #endif |
78 | 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 | |||
79 | #undef setprogdir | 93 | #undef setprogdir |
80 | 94 | ||
81 | static void setprogdir(lua_State *L) | 95 | static void setprogdir(lua_State *L) |
@@ -96,9 +110,17 @@ static void setprogdir(lua_State *L) | |||
96 | static void pusherror(lua_State *L) | 110 | static 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 | ||
112 | static void *ll_load(lua_State *L, const char *path, int gl) | 134 | static 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 | ||
150 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; | ||
151 | #endif | ||
152 | |||
127 | static const char *ll_bcsym(void *lib, const char *sym) | 153 | static 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 | ||
399 | static const int sentinel_ = 0; | 428 | #define KEY_SENTINEL (U64x(80000000,00000000)|'s') |
400 | #define sentinel ((void *)&sentinel_) | ||
401 | 429 | ||
402 | static int lj_cf_package_require(lua_State *L) | 430 | static 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) | |||
487 | static int lj_cf_package_module(lua_State *L) | 515 | static 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 | ||
515 | static int lj_cf_package_seeall(lua_State *L) | 533 | static 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); |