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 02DEC5C571F; Tue, 15 Aug 2023 15:09:53 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 02DEC5C571F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1692101393; bh=JIbItnV5LMoPOMnR7wbJk2wpKYoTpUWsqFHYlD9OKw0=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Hk7Os7kD6Md2KLJEig7Ig4+WwP00SVugLdGJ29ErcnAH0ccZMsMd/BZK4O8GL51JW PSHzWKPpfedY5o+4xVguyYhFNHhugWB1b9/QUmP2YpA/0/CcHWztghXvot57iKk+ln 5S3TSl3qDRtY2Heyd8DR7+/P84c2d6L+a2wminlQ= Received: from smtp35.i.mail.ru (smtp35.i.mail.ru [95.163.41.76]) (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 41BDF5C571F for ; Tue, 15 Aug 2023 15:09:51 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 41BDF5C571F Received: by smtp35.i.mail.ru with esmtpa (envelope-from ) id 1qVsru-004LUB-0t; Tue, 15 Aug 2023 15:09:50 +0300 Date: Tue, 15 Aug 2023 15:09:49 +0300 To: Sergey Kaplun Message-ID: References: <86adbae13323277ea291b7e3a709fc166086fbd3.1691592488.git.skaplun@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <86adbae13323277ea291b7e3a709fc166086fbd3.1691592488.git.skaplun@tarantool.org> X-Mailru-Src: smtp X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD969E04B5EED670DC86EE92E42F0C271DDDF6A6B73F41FC074182A05F538085040F718AE0523DED0CC9C18D10B43DC6DEB5C998DCEB5758A7366B6436A83CF61AD X-C1DE0DAB: 0D63561A33F958A55A047BD3AEFA15282435D0960C33A3FF5CBE9943DD7EDCD6F87CCE6106E1FC07E67D4AC08A07B9B04AB4081B6A6C2E07CB5012B2E24CD356 X-C8649E89: 1C3962B70DF3F0AD5177F0B940C8B66ECE892A7B2722663E91682638B966EB3F662256BEEFA9527F0CC46FEDC77E1FCF8B6DECD8C54F7C79BF83C05DFC9CDDDE7E43B4A185D7597F978258B831A101C237FD76D11AF80A0DC23A2B46ACB6D3BC9F6506935E02D776EA455F16B58544A21C197AAF4D2E4732965026E5D17F6739C77C69D99B9914278E50E1F0597A6FD5CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojHVl7ekwB6hgqZ6V6bKZJtA== X-Mailru-Sender: 11C2EC085EDE56FA38FD4C59F7EFE40755843ADFBBA998A0F1B38B0DB5491CA946EB8B20CC5C2CB7D51284F0FE6F529ABC7555A253F5B200DF104D74F62EE79D27EC13EC74F6107F4198E0F3ECE9B5443453F38A29522196 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: Maxim Kokryashkin via Tarantool-patches Reply-To: Maxim Kokryashkin Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi, Sergey! Thanks for the patch! LGTM, except for a few comments below. On Wed, Aug 09, 2023 at 06:35:57PM +0300, Sergey Kaplun via Tarantool-patches 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 Typo: s/is Unviersal/is the Universal/ > Platform. > * `LJ_WIN_VALLOC()` macro is introduced to use instead of Typo: s/to use/to be used/ > `VirtualAlloc()` [2] (`VirtualAllocFromApp()` [3] for UWP) > * `LJ_WIN_VPROTECT()` macro is introduced to use instead of Typo: s/to use/to be used/ > `VirtualProtect()` [4] (`VirtualProtectFromApp()` [5] for UWP) > * `LJ_WIN_LOADLIBA()` macro is introduced to use instead of Typo: s/to use/to be used/ > `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 Typo: s/not very high/a low/ > 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 It is not obvious what happens here and it is not mentioned in the commit message. Please add a description of this change too. > 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"); > -- > 2.41.0 >