From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 6AAF658123F; Wed, 16 Aug 2023 19:40:22 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 6AAF658123F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1692204022; bh=XVUSwMG4zH5E3zJoL/oWE2F7Bbwag8p0BrbXJb1D+iw=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=nnoQATL3GsS4RnZMyHCYhTxrKPXpuEGbpGRq2hnh1cBujuDCHtSu0kkLuBoHDUR5q a8QhGN5xgcotoy1URYbbjoGVd87U6IAgTNtOybnOcK18SIL4R+QPv346mj/iIhgo5X 7I+J7dPJkNRjQMd9awjF++/NlKKD8WIjaDkJrs4M= Received: from smtp33.i.mail.ru (smtp33.i.mail.ru [95.163.41.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 96B2058123F for ; Wed, 16 Aug 2023 19:40:20 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 96B2058123F Received: by smtp33.i.mail.ru with esmtpa (envelope-from ) id 1qWJZD-00GnVG-0h; Wed, 16 Aug 2023 19:40:19 +0300 Message-ID: Date: Wed, 16 Aug 2023 19:40:18 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Content-Language: en-US To: Sergey Kaplun , Igor Munkin Cc: tarantool-patches@dev.tarantool.org References: <86adbae13323277ea291b7e3a709fc166086fbd3.1691592488.git.skaplun@tarantool.org> In-Reply-To: <86adbae13323277ea291b7e3a709fc166086fbd3.1691592488.git.skaplun@tarantool.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9700E0DCE2907754D77D6FA938422CA5F653AC3988EEC6B12182A05F53808504084D801DC12C3D8D15DAC4B75A5B499BF34220BE06AB1ED4B6B7E76DFE0D8305A X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE727FD6E7FC3A8F857EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637BD890EF519C7ACB58638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D88DFE74F82502544A94504C2B2187085D117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC4AFB60FD1831C04CA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751FF04B652EEC242312D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE9647ADFADE5905B1AD7EC71F1DB884274AD6D5ED66289B523666184CF4C3C14F6136E347CC761E07725E5C173C3A84C3C24E78AA85F86F6C76E601842F6C81A1F004C906525384303E02D724532EE2C3F43C7A68FF6260569E8FC8737B5C2249D082881546D93491E827F84554CEF50127C277FBC8AE2E8B03FB6F9198DE190422CA9DD8327EE4930A3850AC1BE2E7356D8C47C27EEC5E9FB5C8C57E37DE458BEDA766A37F9254B7 X-B7AD71C0: 4965CFDFE0519134C1FE400A9E48C5401DD40DE57556AFB266D16FC5F53507A1816E0A2A8F779BBED8D40077074E805C66D16FC5F53507A117535B0CF9F6D0C3EE9D5CB6078CC77C052B6B5A589B15AC9016E28473A56E49 X-C1DE0DAB: 0D63561A33F958A5D54E349332ECBBEB1F3C6AC5C69CAD85E8C381C0FDC58A04F87CCE6106E1FC07E67D4AC08A07B9B0DB8A315C1FF4794DBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD75DCE07D45A749953FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF813A522AB6B8A5EA8C3B6543CAE0256C0A4D3D44C89EC02D621EA7D2207CE9BCC2F598A3E54AB45124F7434E9608BF9F2B891EB0B185D184D8CE9842EBDE9D7EE48CAC7CA610320002C26D483E81D6BE0DBAE6F56676BC7117BB6831D7356A2DEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojFRrmMqSMPxq09BFA1u2wrg== X-Mailru-Sender: C4F68CFF4024C8867DFDF7C7F2588458CEFAF2C4CD67D0083202B8A561D509331B51B3791EA37415282EC151BADDC1D3523A6D01B4765B2DFB59E2DDD9FE06B14FA522850F29BC30B0DAF586E7D11B3E67EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 08/19] Windows: Add UWP support, part 1. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi, Sergey Thanks for the patch! LGTM On 8/9/23 18:35, Sergey Kaplun wrote: > From: Mike Pall > > Contributed by Ben Pye. > > (cherry-picked from commit c3c54ce1aef782823936808a75460e6b53aada2c) > > This patch adds partial support for the Universal Windows Platform [1] > in LuaJIT. > This includes: > * `LJ_TARGET_UWP` is introduced to mark that target is Universal Windows > Platform. > * `LJ_WIN_VALLOC()` macro is introduced to use instead of > `VirtualAlloc()` [2] (`VirtualAllocFromApp()` [3] for UWP) > * `LJ_WIN_VPROTECT()` macro is introduced to use instead of > `VirtualProtect()` [4] (`VirtualProtectFromApp()` [5] for UWP) > * `LJ_WIN_LOADLIBA()` macro is introduced to use instead of > `LoadLibraryExA()` [6] (custom implementation using > `LoadPackagedLibrary()` [7] for UWP). > > Note that the following features are not implemented for UWP: > * `io.popen()`. > * LuaJIT profiler's (`jit.p`) timer for Windows has not very high > resolution since `timeBeginPeriod()` [8] and `timeEndPeriod()` [9] are > not used, because the library isn't loaded. > > [1]: https://learn.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide > [2]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc > [3]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocfromapp > [4]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotect > [5]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotectfromapp > [6]: https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa > [7]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-loadpackagedlibrary > [8]: https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod > [9]: https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timeendperiod > > Sergey Kaplun: > * added the description for the feature > > Part of tarantool/tarantool#8825 > --- > doc/ext_ffi_api.html | 2 ++ > src/lib_ffi.c | 3 +++ > src/lib_io.c | 4 ++-- > src/lib_package.c | 24 +++++++++++++++++++++++- > src/lj_alloc.c | 6 +++--- > src/lj_arch.h | 19 +++++++++++++++++++ > src/lj_ccallback.c | 4 ++-- > src/lj_clib.c | 20 ++++++++++++++++---- > src/lj_mcode.c | 8 ++++---- > src/lj_profile_timer.c | 8 ++++---- > 10 files changed, 78 insertions(+), 20 deletions(-) > > diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html > index 91af2e1d..c72191d1 100644 > --- a/doc/ext_ffi_api.html > +++ b/doc/ext_ffi_api.html > @@ -469,6 +469,8 @@ otherwise. The following parameters are currently defined: > > winWindows variant of the standard ABI > > +uwpUniversal Windows Platform > + > gc6464 bit GC references > > > diff --git a/src/lib_ffi.c b/src/lib_ffi.c > index 136e98e8..d1fe1a14 100644 > --- a/src/lib_ffi.c > +++ b/src/lib_ffi.c > @@ -746,6 +746,9 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.) > #endif > #if LJ_ABI_WIN > case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ > +#endif > +#if LJ_TARGET_UWP > + case H_(a40f0bcb,a40f0bcb): b = 1; break; /* uwp */ > #endif > case H_(3af93066,1f001464): b = 1; break; /* le/be */ > #if LJ_GC64 > diff --git a/src/lib_io.c b/src/lib_io.c > index f0108227..db995ae6 100644 > --- a/src/lib_io.c > +++ b/src/lib_io.c > @@ -99,7 +99,7 @@ static int io_file_close(lua_State *L, IOFileUD *iof) > int stat = -1; > #if LJ_TARGET_POSIX > stat = pclose(iof->fp); > -#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE > +#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP > stat = _pclose(iof->fp); > #else > lua_assert(0); > @@ -414,7 +414,7 @@ LJLIB_CF(io_open) > > LJLIB_CF(io_popen) > { > -#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE) > +#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP) > const char *fname = strdata(lj_lib_checkstr(L, 1)); > GCstr *s = lj_lib_optstr(L, 2); > const char *mode = s ? strdata(s) : "r"; > diff --git a/src/lib_package.c b/src/lib_package.c > index 67959a10..b49f0209 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) > BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); > #endif > > +#if LJ_TARGET_UWP > +void *LJ_WIN_LOADLIBA(const char *path) > +{ > + DWORD err = GetLastError(); > + wchar_t wpath[256]; > + HANDLE lib = NULL; > + if (MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, 256) > 0) { > + lib = LoadPackagedLibrary(wpath, 0); > + } > + SetLastError(err); > + return lib; > +} > +#endif > + > #undef setprogdir > > static void setprogdir(lua_State *L) > @@ -119,7 +133,7 @@ static void ll_unloadlib(void *lib) > > static void *ll_load(lua_State *L, const char *path, int gl) > { > - HINSTANCE lib = LoadLibraryExA(path, NULL, 0); > + HINSTANCE lib = LJ_WIN_LOADLIBA(path); > if (lib == NULL) pusherror(L); > UNUSED(gl); > return lib; > @@ -132,17 +146,25 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) > return f; > } > > +#if LJ_TARGET_UWP > +EXTERN_C IMAGE_DOS_HEADER __ImageBase; > +#endif > + > static const char *ll_bcsym(void *lib, const char *sym) > { > if (lib) { > return (const char *)GetProcAddress((HINSTANCE)lib, sym); > } else { > +#if LJ_TARGET_UWP > + return (const char *)GetProcAddress((HINSTANCE)&__ImageBase, sym); > +#else > HINSTANCE h = GetModuleHandleA(NULL); > const char *p = (const char *)GetProcAddress(h, sym); > if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, > (const char *)ll_bcsym, &h)) > p = (const char *)GetProcAddress(h, sym); > return p; > +#endif > } > } > > diff --git a/src/lj_alloc.c b/src/lj_alloc.c > index f7039b5b..9e2fb1f6 100644 > --- a/src/lj_alloc.c > +++ b/src/lj_alloc.c > @@ -167,7 +167,7 @@ static void *DIRECT_MMAP(size_t size) > static void *CALL_MMAP(size_t size) > { > DWORD olderr = GetLastError(); > - void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); > + void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); > SetLastError(olderr); > return ptr ? ptr : MFAIL; > } > @@ -176,8 +176,8 @@ static void *CALL_MMAP(size_t size) > static void *DIRECT_MMAP(size_t size) > { > DWORD olderr = GetLastError(); > - void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, > - PAGE_READWRITE); > + void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, > + PAGE_READWRITE); > SetLastError(olderr); > return ptr ? ptr : MFAIL; > } > diff --git a/src/lj_arch.h b/src/lj_arch.h > index 7397492e..0351e046 100644 > --- a/src/lj_arch.h > +++ b/src/lj_arch.h > @@ -141,6 +141,13 @@ > #define LJ_TARGET_GC64 1 > #endif > > +#ifdef _UWP > +#define LJ_TARGET_UWP 1 > +#if LUAJIT_TARGET == LUAJIT_ARCH_X64 > +#define LJ_TARGET_GC64 1 > +#endif > +#endif > + > #define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */ > #define LJ_NUMMODE_SINGLE_DUAL 1 /* Default to single-number mode. */ > #define LJ_NUMMODE_DUAL 2 /* Dual-number mode only. */ > @@ -586,6 +593,18 @@ > #define LJ_ABI_WIN 0 > #endif > > +#if LJ_TARGET_WINDOWS > +#if LJ_TARGET_UWP > +#define LJ_WIN_VALLOC VirtualAllocFromApp > +#define LJ_WIN_VPROTECT VirtualProtectFromApp > +extern void *LJ_WIN_LOADLIBA(const char *path); > +#else > +#define LJ_WIN_VALLOC VirtualAlloc > +#define LJ_WIN_VPROTECT VirtualProtect > +#define LJ_WIN_LOADLIBA(path) LoadLibraryExA((path), NULL, 0) > +#endif > +#endif > + > #if defined(LUAJIT_NO_UNWIND) || __GNU_COMPACT_EH__ || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4 > #define LJ_NO_UNWIND 1 > #endif > diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c > index c33190d7..37edd00f 100644 > --- a/src/lj_ccallback.c > +++ b/src/lj_ccallback.c > @@ -267,7 +267,7 @@ static void callback_mcode_new(CTState *cts) > if (CALLBACK_MAX_SLOT == 0) > lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); > #if LJ_TARGET_WINDOWS > - p = VirtualAlloc(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); > + p = LJ_WIN_VALLOC(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); > if (!p) > lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); > #elif LJ_TARGET_POSIX > @@ -285,7 +285,7 @@ static void callback_mcode_new(CTState *cts) > #if LJ_TARGET_WINDOWS > { > DWORD oprot; > - VirtualProtect(p, sz, PAGE_EXECUTE_READ, &oprot); > + LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot); > } > #elif LJ_TARGET_POSIX > mprotect(p, sz, (PROT_READ|PROT_EXEC)); > diff --git a/src/lj_clib.c b/src/lj_clib.c > index c06c0915..a8672052 100644 > --- a/src/lj_clib.c > +++ b/src/lj_clib.c > @@ -158,11 +158,13 @@ BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); > /* Default libraries. */ > enum { > CLIB_HANDLE_EXE, > +#if !LJ_TARGET_UWP > CLIB_HANDLE_DLL, > CLIB_HANDLE_CRT, > CLIB_HANDLE_KERNEL32, > CLIB_HANDLE_USER32, > CLIB_HANDLE_GDI32, > +#endif > CLIB_HANDLE_MAX > }; > > @@ -208,7 +210,7 @@ static const char *clib_extname(lua_State *L, const char *name) > static void *clib_loadlib(lua_State *L, const char *name, int global) > { > DWORD oldwerr = GetLastError(); > - void *h = (void *)LoadLibraryExA(clib_extname(L, name), NULL, 0); > + void *h = LJ_WIN_LOADLIBA(clib_extname(L, name)); > if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", name); > SetLastError(oldwerr); > UNUSED(global); > @@ -218,6 +220,7 @@ static void *clib_loadlib(lua_State *L, const char *name, int global) > static void clib_unloadlib(CLibrary *cl) > { > if (cl->handle == CLIB_DEFHANDLE) { > +#if !LJ_TARGET_UWP > MSize i; > for (i = CLIB_HANDLE_KERNEL32; i < CLIB_HANDLE_MAX; i++) { > void *h = clib_def_handle[i]; > @@ -226,11 +229,16 @@ static void clib_unloadlib(CLibrary *cl) > FreeLibrary((HINSTANCE)h); > } > } > +#endif > } else if (cl->handle) { > FreeLibrary((HINSTANCE)cl->handle); > } > } > > +#if LJ_TARGET_UWP > +EXTERN_C IMAGE_DOS_HEADER __ImageBase; > +#endif > + > static void *clib_getsym(CLibrary *cl, const char *name) > { > void *p = NULL; > @@ -239,6 +247,9 @@ static void *clib_getsym(CLibrary *cl, const char *name) > for (i = 0; i < CLIB_HANDLE_MAX; i++) { > HINSTANCE h = (HINSTANCE)clib_def_handle[i]; > if (!(void *)h) { /* Resolve default library handles (once). */ > +#if LJ_TARGET_UWP > + h = (HINSTANCE)&__ImageBase; > +#else > switch (i) { > case CLIB_HANDLE_EXE: GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, &h); break; > case CLIB_HANDLE_DLL: > @@ -249,11 +260,12 @@ static void *clib_getsym(CLibrary *cl, const char *name) > GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, > (const char *)&_fmode, &h); > break; > - case CLIB_HANDLE_KERNEL32: h = LoadLibraryExA("kernel32.dll", NULL, 0); break; > - case CLIB_HANDLE_USER32: h = LoadLibraryExA("user32.dll", NULL, 0); break; > - case CLIB_HANDLE_GDI32: h = LoadLibraryExA("gdi32.dll", NULL, 0); break; > + case CLIB_HANDLE_KERNEL32: h = LJ_WIN_LOADLIBA("kernel32.dll"); break; > + case CLIB_HANDLE_USER32: h = LJ_WIN_LOADLIBA("user32.dll"); break; > + case CLIB_HANDLE_GDI32: h = LJ_WIN_LOADLIBA("gdi32.dll"); break; > } > if (!h) continue; > +#endif > clib_def_handle[i] = (void *)h; > } > p = (void *)GetProcAddress(h, name); > diff --git a/src/lj_mcode.c b/src/lj_mcode.c > index c6361018..10db4457 100644 > --- a/src/lj_mcode.c > +++ b/src/lj_mcode.c > @@ -66,8 +66,8 @@ void lj_mcode_sync(void *start, void *end) > > static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, DWORD prot) > { > - void *p = VirtualAlloc((void *)hint, sz, > - MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot); > + void *p = LJ_WIN_VALLOC((void *)hint, sz, > + MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot); > if (!p && !hint) > lj_trace_err(J, LJ_TRERR_MCODEAL); > return p; > @@ -82,7 +82,7 @@ static void mcode_free(jit_State *J, void *p, size_t sz) > static int mcode_setprot(void *p, size_t sz, DWORD prot) > { > DWORD oprot; > - return !VirtualProtect(p, sz, prot, &oprot); > + return !LJ_WIN_VPROTECT(p, sz, prot, &oprot); > } > > #elif LJ_TARGET_POSIX > @@ -255,7 +255,7 @@ static void *mcode_alloc(jit_State *J, size_t sz) > /* All memory addresses are reachable by relative jumps. */ > static void *mcode_alloc(jit_State *J, size_t sz) > { > -#ifdef __OpenBSD__ > +#if defined(__OpenBSD__) || LJ_TARGET_UWP > /* Allow better executable memory allocation for OpenBSD W^X mode. */ > void *p = mcode_alloc_at(J, 0, sz, MCPROT_RUN); > if (p && mcode_setprot(p, sz, MCPROT_GEN)) { > diff --git a/src/lj_profile_timer.c b/src/lj_profile_timer.c > index 056fd1f7..0b859457 100644 > --- a/src/lj_profile_timer.c > +++ b/src/lj_profile_timer.c > @@ -84,7 +84,7 @@ static DWORD WINAPI timer_thread(void *timerx) > { > lj_profile_timer *timer = (lj_profile_timer *)timerx; > int interval = timer->opt.interval_msec; > -#if LJ_TARGET_WINDOWS > +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP > timer->wmm_tbp(interval); > #endif > while (1) { > @@ -92,7 +92,7 @@ static DWORD WINAPI timer_thread(void *timerx) > if (timer->abort) break; > timer->opt.handler(); > } > -#if LJ_TARGET_WINDOWS > +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP > timer->wmm_tep(interval); > #endif > return 0; > @@ -101,9 +101,9 @@ static DWORD WINAPI timer_thread(void *timerx) > /* Start profiling timer thread. */ > void lj_profile_timer_start(lj_profile_timer *timer) > { > -#if LJ_TARGET_WINDOWS > +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP > if (!timer->wmm) { /* Load WinMM library on-demand. */ > - timer->wmm = LoadLibraryExA("winmm.dll", NULL, 0); > + timer->wmm = LJ_WIN_LOADLIBA("winmm.dll"); > if (timer->wmm) { > timer->wmm_tbp = > (WMM_TPFUNC)GetProcAddress(timer->wmm, "timeBeginPeriod");