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 259FD6F3C8; Wed, 28 Sep 2022 11:20:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 259FD6F3C8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1664353235; bh=bzyOa3GbW43TQIeD5IVVciCP2pot/UNamyq32O/AdEE=; h=In-Reply-To:Date:References:To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UPP+b0kLGGw9XpTkETwKTBivB1b1jFdgBeCtMkY5d3ZgeC6QHmIHbavC9OlZO/Qo8 Bx2bUESsCE6ZznMdh8mcTmxxNPT3yVJGgkURtBBBd6I9UCjZCKEZaETvlvXpb7mOUe vd9zD1hOGP477z8TCtB3QvfAokXi7WokG/f20Ukc= Received: from smtp52.i.mail.ru (smtp52.i.mail.ru [94.100.177.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 38EBB6F3C8 for ; Wed, 28 Sep 2022 11:20:32 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 38EBB6F3C8 Received: by smtp52.i.mail.ru with esmtpa (envelope-from ) id 1odSIx-0003xh-9j; Wed, 28 Sep 2022 11:20:31 +0300 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.1\)) In-Reply-To: Date: Wed, 28 Sep 2022 11:20:18 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <99AFA9A2-5CE1-4B4A-A0FD-D341710167A9@tarantool.org> References: To: Maksim Kokryashkin X-Mailer: Apple Mail (2.3696.120.41.1.1) X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 78E4E2B564C1792B X-77F55803: 4F1203BC0FB41BD99929F1169E77FC7A3F9488CD0D5932E5A67477A437337310182A05F5380850403031185EF4F17E8368969576E656D4A53794963B02C0A9B7733829EAF2BD3FE3 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE76ABD3380F320B62CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006372FD0E46BD6FDBDB0EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38B8859CA687ABA27BA1074FD9EFC0205BE28E77343582B326BCC7F00164DA146DAFE8445B8C89999728AA50765F7900637529BE3F22733EA6E389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC8062BEEFFB5F8EA3EF6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA73AA81AA40904B5D9A18204E546F3947C706E30CA523186196E0066C2D8992A164AD6D5ED66289B52698AB9A7B718F8C46E0066C2D8992A16725E5C173C3A84C382354B272D6C28B2BA3038C0950A5D36B5C8C57E37DE458B330BD67F2E7D9AF16D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F790063788B3B24285A3CD0EEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-C1DE0DAB: 9604B64F49C60606AD91A466A1DEF99B296C473AB1E142185AC9E3593CE4B31AB1881A6453793CE9274300E5CE05BD4401A9E91200F654B0F56C66D0505D9834F04B2EF7FE17FE77474476E6A597BA462A6751949C8C30359C2B6934AE262D3EE7EAB7254005DCED8DA55E71E02F9FC08E8E86DC7131B365E7726E8460B7C23C X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34C974B02B4EA30DFB9AF38D922358A4A7B794FA908367494C5033765CBE3CC7C118178B3E6CB29DC21D7E09C32AA3244C01358D7D53C1500EC08EF38A321776B71E098CBE561D6343FACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojVySwzd+bxOeC6q2cpY2bWA== X-Mailru-Sender: 5AA3D5B9D8C486465A7E7C48E78B605D176537D6F4C1A0DD68969576E656D4A57AD558DE3329E34460D8632BEC246C7D55B4A2144138A8805FC805B5969CB4993EE16157CC7DAB4272D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 1/6] Cleanup and enable external unwinding for more platforms. 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: sergos via Tarantool-patches Reply-To: sergos Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi! Thanks for the patch! Just one nit in message. Otherwise - LGTM. Sergos > On 26 Sep 2022, at 18:54, Maksim Kokryashkin = wrote: >=20 > (cherry picked from commit e131936133c58de4426c595db2341caf5a1665b5) >=20 > This commit enables external unwiding on all platforms, that ^^^^^^^^^ > create unwind tables by default. Corresponding check is added > to the build routine. >=20 > Also, GC64 mode is now enabled on MacOS by default. >=20 > Maxim Kokryashkin: > * added the description for the patch >=20 > Needed for tarantool/tarantool#6096 > Needed for tarantool/tarantool#7230 > --- > CMakeLists.txt | 3 + > cmake/SetTargetFlags.cmake | 22 ++- > doc/extensions.html | 22 +-- > src/Makefile.original | 11 +- > src/lj_arch.h | 27 ++-- > src/lj_err.c | 321 +++++++++++++++++++------------------ > 6 files changed, 213 insertions(+), 193 deletions(-) >=20 > diff --git a/CMakeLists.txt b/CMakeLists.txt > index 8b49f9d7..c4f3ef62 100644 > --- a/CMakeLists.txt > +++ b/CMakeLists.txt > @@ -176,6 +176,9 @@ endif() >=20 > # Enable GC64 mode for x64. > option(LUAJIT_ENABLE_GC64 "GC64 mode for x64" OFF) > +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") > + set(LUAJIT_ENABLE_GC64 ON) > +endif() > if(LUAJIT_ENABLE_GC64) > AppendFlags(TARGET_C_FLAGS -DLUAJIT_ENABLE_GC64) > endif() > diff --git a/cmake/SetTargetFlags.cmake b/cmake/SetTargetFlags.cmake > index b544d2ac..36896aff 100644 > --- a/cmake/SetTargetFlags.cmake > +++ b/cmake/SetTargetFlags.cmake > @@ -15,6 +15,22 @@ endif() > LuaJITTestArch(TESTARCH "${TARGET_C_FLAGS}") > LuaJITArch(LUAJIT_ARCH "${TESTARCH}") >=20 > +string(FIND ${TARGET_C_FLAGS} "LJ_NO_UNWIND 1" UNWIND_POS) > +if(UNWIND_POS EQUAL -1) > + execute_process( > + COMMAND bash -c "exec 2>/dev/null; echo 'extern void b(void);int = a(void){b();return 0;}' | ${CMAKE_C_COMPILER} -c -x c - -o tmpunwind.o = && grep -qa -e eh_frame -e __unwind_info tmpunwind.o && echo E; rm -f = tmpunwind.o" > + WORKING_DIRECTORY ${LUAJIT_SOURCE_DIR} > + OUTPUT_VARIABLE TESTUNWIND > + RESULT_VARIABLE TESTUNWIND_RC > + ) > + if(TESTUNWIND_RC EQUAL 0) > + string(FIND "${TESTUNWIND}" "E" UNW_TEST_POS) > + if(NOT UNW_TEST_POS EQUAL -1) > + AppendFlags(TARGET_C_FLAGS -DLUAJIT_UNWIND_EXTERNAL) > + endif() > + endif() > +endif() > + > # Target-specific compiler options. > # > # x86/x64 only: For GCC 4.2 or higher and if you don't intend to > @@ -25,12 +41,6 @@ if(LUAJIT_ARCH STREQUAL "x86") > endif() >=20 > if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") > - if(LUAJIT_ARCH STREQUAL "x64") > - # XXX: Set -pagezero_size to hint when allocating 32 > - # bit memory on OSX/x64, otherwise the lower 4GB are blocked. > - AppendFlags(TARGET_BIN_FLAGS -pagezero_size 10000 -image_base = 100000000) > - AppendFlags(TARGET_SHARED_FLAGS -image_base 7fff04c4a000) > - endif() > AppendFlags(TARGET_SHARED_FLAGS -single_module -undefined = dynamic_lookup) > else() # Linux and FreeBSD. > AppendFlags(TARGET_BIN_FLAGS -Wl,-E) > diff --git a/doc/extensions.html b/doc/extensions.html > index e0f136e2..777e9928 100644 > --- a/doc/extensions.html > +++ b/doc/extensions.html > @@ -395,29 +395,19 @@ the toolchain used to compile LuaJIT: > Interoperability > > > -POSIX/x64, DWARF2 unwinding > -GCC 4.3+, Clang > +External frame unwinding > +GCC, Clang, MSVC > Full > > > -ARM -DLUAJIT_UNWIND_EXTERNAL > -GCC, Clang > -Full > - > - > -Other platforms, DWARF2 unwinding > +Internal frame unwinding + DWARF2 > GCC, Clang > Limited > > - > -Windows/x64 > -MSVC or WinSDK > -Full > - > > -Windows/x86 > -Any > -Full > +Windows 64 bit > +non-MSVC > +Limited > > > Other platforms > diff --git a/src/Makefile.original b/src/Makefile.original > index dd1c6a76..c9609700 100644 > --- a/src/Makefile.original > +++ b/src/Makefile.original > @@ -320,6 +320,13 @@ else > ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null = -fno-stack-protector 2>/dev/null || echo 1)) > TARGET_XCFLAGS+=3D -fno-stack-protector > endif > +ifeq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH))) > + # Find out whether the target toolchain always generates unwind = tables. > + TARGET_TESTUNWIND=3D$(shell exec 2>/dev/null; echo 'extern void = b(void);int a(void){b();return 0;}' | $(TARGET_CC) -c -x c - -o = tmpunwind.o && grep -qa -e eh_frame -e __unwind_info tmpunwind.o && echo = E; rm -f tmpunwind.o) > + ifneq (,$(findstring E,$(TARGET_TESTUNWIND))) > + TARGET_XCFLAGS+=3D -DLUAJIT_UNWIND_EXTERNAL > + endif > +endif > ifeq (Darwin,$(TARGET_SYS)) > ifeq (,$(MACOSX_DEPLOYMENT_TARGET)) > export MACOSX_DEPLOYMENT_TARGET=3D10.4 > @@ -328,10 +335,6 @@ ifeq (Darwin,$(TARGET_SYS)) > TARGET_XSHLDFLAGS=3D -dynamiclib -single_module -undefined = dynamic_lookup -fPIC > TARGET_DYNXLDOPTS=3D > TARGET_XSHLDFLAGS+=3D -install_name $(TARGET_DYLIBPATH) = -compatibility_version $(MAJVER).$(MINVER) -current_version = $(MAJVER).$(MINVER).$(RELVER) > - ifeq (x64,$(TARGET_LJARCH)) > - TARGET_XLDFLAGS+=3D -pagezero_size 10000 -image_base 100000000 > - TARGET_XSHLDFLAGS+=3D -image_base 7fff04c4a000 > - endif > else > ifeq (iOS,$(TARGET_SYS)) > TARGET_STRIP+=3D -x > diff --git a/src/lj_arch.h b/src/lj_arch.h > index 40129d9e..730be5bf 100644 > --- a/src/lj_arch.h > +++ b/src/lj_arch.h > @@ -152,11 +152,6 @@ > #define LJ_ARCH_NAME "x86" > #define LJ_ARCH_BITS 32 > #define LJ_ARCH_ENDIAN LUAJIT_LE > -#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN > -#define LJ_ABI_WIN 1 > -#else > -#define LJ_ABI_WIN 0 > -#endif > #define LJ_TARGET_X86 1 > #define LJ_TARGET_X86ORX64 1 > #define LJ_TARGET_EHRETREG 0 > @@ -170,11 +165,6 @@ > #define LJ_ARCH_NAME "x64" > #define LJ_ARCH_BITS 64 > #define LJ_ARCH_ENDIAN LUAJIT_LE > -#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN > -#define LJ_ABI_WIN 1 > -#else > -#define LJ_ABI_WIN 0 > -#endif > #define LJ_TARGET_X64 1 > #define LJ_TARGET_X86ORX64 1 > #define LJ_TARGET_EHRETREG 0 > @@ -185,6 +175,8 @@ > #define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL > #ifdef LUAJIT_ENABLE_GC64 > #define LJ_TARGET_GC64 1 > +#elif LJ_TARGET_OSX > +#error "macOS requires GC64 -- don't disable it" > #endif >=20 > #elif LUAJIT_TARGET =3D=3D LUAJIT_ARCH_ARM > @@ -566,15 +558,22 @@ > #define LJ_NO_SYSTEM 1 > #endif >=20 > -#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ > -/* NYI: no support for compact unwind specification, yet. */ > -#define LUAJIT_NO_UNWIND 1 > +#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN > +#define LJ_ABI_WIN 1 > +#else > +#define LJ_ABI_WIN 0 > #endif >=20 > -#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || = LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4 > +#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 >=20 > +#if !LJ_NO_UNWIND && !defined(LUAJIT_UNWIND_INTERNAL) && (LJ_ABI_WIN = || (defined(LUAJIT_UNWIND_EXTERNAL) && (defined(__GNUC__) || = defined(__clang__)))) > +#define LJ_UNWIND_EXT 1 > +#else > +#define LJ_UNWIND_EXT 0 > +#endif > + > /* Compatibility with Lua 5.1 vs. 5.2. */ > #ifdef LUAJIT_ENABLE_LUA52COMPAT > #define LJ_52 1 > diff --git a/src/lj_err.c b/src/lj_err.c > index c310daf6..298e5434 100644 > --- a/src/lj_err.c > +++ b/src/lj_err.c > @@ -29,12 +29,18 @@ > ** Pros and Cons: > ** > ** - EXT requires unwind tables for *all* functions on the C stack = between > -** the pcall/catch and the error/throw. This is the default on x64, > -** but needs to be manually enabled on x86/PPC for non-C++ code. > +** the pcall/catch and the error/throw. C modules used by Lua code = can > +** throw errors, so these need to have unwind tables, too. = Transitively > +** this applies to all system libraries used by C modules -- at = least > +** when they have callbacks which may throw an error. > ** > -** - INT is faster when actually throwing errors (but this happens = rarely). > +** - INT is faster when actually throwing errors, but this happens = rarely. > ** Setting up error handlers is zero-cost in any case. > ** > +** - INT needs to save *all* callee-saved registers when entering the > +** interpreter. EXT only needs to save those actually used inside = the > +** interpreter. JIT-compiled code may need to save some more. > +** > ** - EXT provides full interoperability with C++ exceptions. You can = throw > ** Lua errors or C++ exceptions through a mix of Lua frames and C++ = frames. > ** C++ destructors are called as needed. C++ exceptions caught by = pcall > @@ -46,27 +52,33 @@ > ** the wrapper function feature. Lua errors thrown through C++ = frames > ** cannot be caught by C++ code and C++ destructors are not run. > ** > -** EXT is the default on x64 systems and on Windows, INT is the = default on all > -** other systems. > +** EXT is the default on all systems where the toolchain produces = unwind > +** tables by default (*). This is hard-coded and/or detected in = src/Makefile. > +** You can thwart the detection with: = TARGET_XCFLAGS=3D-DLUAJIT_UNWIND_INTERNAL > +** > +** INT is the default on all other systems. > +** > +** EXT can be manually enabled for toolchains that are able to = produce > +** conforming unwind tables: > +** "TARGET_XCFLAGS=3D-funwind-tables -DLUAJIT_UNWIND_EXTERNAL" > +** As explained above, *all* C code used directly or indirectly by = LuaJIT > +** must be compiled with -funwind-tables (or -fexceptions). C++ code = must > +** *not* be compiled with -fno-exceptions. > +** > +** If you're unsure whether error handling inside the VM works = correctly, > +** try running this and check whether it prints "OK": > ** > -** EXT can be manually enabled on POSIX systems using GCC and DWARF2 = stack > -** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be = compiled > -** with -funwind-tables (or -fexceptions). This includes LuaJIT = itself (set > -** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C = modules > -** and all C libraries that have callbacks which may be used to call = back > -** into Lua. C++ code must *not* be compiled with -fno-exceptions. > +** luajit -e "print(select(2, load('OK')):match('OK'))" > ** > -** EXT is mandatory on WIN64 since the calling convention has an = abundance > -** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, = xmm6-xmm15). > -** The POSIX/x64 interpreter only saves r12/r13 for INT (e.g. PS4). > +** (*) Originally, toolchains only generated unwind tables for C++ = code. For > +** interoperability reasons, this can be manually enabled for plain C = code, > +** too (with -funwind-tables). With the introduction of the x64 = architecture, > +** the corresponding POSIX and Windows ABIs mandated unwind tables = for all > +** code. Over the following years most desktop and server platforms = have > +** enabled unwind tables by default on all architectures. OTOH mobile = and > +** embedded platforms do not consistently mandate unwind tables. > */ >=20 > -#if defined(__GNUC__) && (LJ_TARGET_X64 || = defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND > -#define LJ_UNWIND_EXT 1 > -#elif LJ_TARGET_WINDOWS > -#define LJ_UNWIND_EXT 1 > -#endif > - > /* -- Error messages = ------------------------------------------------------ */ >=20 > /* Error message strings. */ > @@ -183,7 +195,125 @@ static void *err_unwind(lua_State *L, void = *stopcf, int errcode) >=20 > /* -- External frame unwinding = -------------------------------------------- */ >=20 > -#if defined(__GNUC__) && !LJ_NO_UNWIND && !LJ_ABI_WIN > +#if LJ_ABI_WIN > + > +/* > +** Someone in Redmond owes me several days of my life. A lot of this = is > +** undocumented or just plain wrong on MSDN. Some of it can be = gathered > +** from 3rd party docs or must be found by trial-and-error. They = really > +** don't want you to write your own language-specific exception = handler > +** or to interact gracefully with MSVC. :-( > +** > +** Apparently MSVC doesn't call C++ destructors for foreign = exceptions > +** unless you compile your C++ code with /EHa. Unfortunately this = means > +** catch (...) also catches things like access violations. The use of > +** _set_se_translator doesn't really help, because it requires /EHa, = too. > +*/ > + > +#define WIN32_LEAN_AND_MEAN > +#include > + > +#if LJ_TARGET_X86 > +typedef void *UndocumentedDispatcherContext; /* Unused on x86. */ > +#else > +/* Taken from: http://www.nynaeve.net/?p=3D99 */ > +typedef struct UndocumentedDispatcherContext { > + ULONG64 ControlPc; > + ULONG64 ImageBase; > + PRUNTIME_FUNCTION FunctionEntry; > + ULONG64 EstablisherFrame; > + ULONG64 TargetIp; > + PCONTEXT ContextRecord; > + void (*LanguageHandler)(void); > + PVOID HandlerData; > + PUNWIND_HISTORY_TABLE HistoryTable; > + ULONG ScopeIndex; > + ULONG Fill0; > +} UndocumentedDispatcherContext; > +#endif > + > +/* Another wild guess. */ > +extern void __DestructExceptionObject(EXCEPTION_RECORD *rec, int = nothrow); > + > +#if LJ_TARGET_X64 && defined(MINGW_SDK_INIT) > +/* Workaround for broken MinGW64 declaration. */ > +VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) = asm("RtlUnwindEx"); > +#define RtlUnwindEx RtlUnwindEx_FIXED > +#endif > + > +#define LJ_MSVC_EXCODE ((DWORD)0xe06d7363) > +#define LJ_GCC_EXCODE ((DWORD)0x20474343) > + > +#define LJ_EXCODE ((DWORD)0xe24c4a00) > +#define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c)) > +#define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <=3D 0xff) > +#define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff)) > + > +/* Windows exception handler for interpreter frame. */ > +LJ_FUNCA int lj_err_unwind_win(EXCEPTION_RECORD *rec, > + void *f, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) > +{ > +#if LJ_TARGET_X86 > + void *cf =3D (char *)f - CFRAME_OFS_SEH; > +#else > + void *cf =3D f; > +#endif > + lua_State *L =3D cframe_L(cf); > + int errcode =3D LJ_EXCODE_CHECK(rec->ExceptionCode) ? > + LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; > + if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ > + /* Unwind internal frames. */ > + err_unwind(L, cf, errcode); > + } else { > + void *cf2 =3D err_unwind(L, cf, 0); > + if (cf2) { /* We catch it, so start unwinding the upper frames. = */ > + if (rec->ExceptionCode =3D=3D LJ_MSVC_EXCODE || > + rec->ExceptionCode =3D=3D LJ_GCC_EXCODE) { > +#if !LJ_TARGET_CYGWIN > + __DestructExceptionObject(rec, 1); > +#endif > + setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); > + } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { > + /* Don't catch access violations etc. */ > + return 1; /* ExceptionContinueSearch */ > + } > +#if LJ_TARGET_X86 > + UNUSED(ctx); > + UNUSED(dispatch); > + /* Call all handlers for all lower C frames (including = ourselves) again > + ** with EH_UNWINDING set. Then call the specified function, = passing cf > + ** and errcode. > + */ > + lj_vm_rtlunwind(cf, (void *)rec, > + (cframe_unwind_ff(cf2) && errcode !=3D LUA_YIELD) ? > + (void *)lj_vm_unwind_ff : (void *)lj_vm_unwind_c, errcode); > + /* lj_vm_rtlunwind does not return. */ > +#else > + /* Unwind the stack and call all handlers for all lower C = frames > + ** (including ourselves) again with EH_UNWINDING set. Then set > + ** stack pointer =3D cf, result =3D errcode and jump to the = specified target. > + */ > + RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode !=3D = LUA_YIELD) ? > + lj_vm_unwind_ff_eh : > + lj_vm_unwind_c_eh), > + rec, (void *)(uintptr_t)errcode, ctx, = dispatch->HistoryTable); > + /* RtlUnwindEx should never return. */ > +#endif > + } > + } > + return 1; /* ExceptionContinueSearch */ > +} > + > +/* Raise Windows exception. */ > +static void err_raise_ext(global_State *g, int errcode) > +{ > +#if LJ_HASJIT > + setmref(g->jit_base, NULL); > +#endif > + RaiseException(LJ_EXCODE_MAKE(errcode), 1 /* EH_NONCONTINUABLE */, = 0, NULL); > +} > + > +#elif !LJ_NO_UNWIND && (defined(__GNUC__) || defined(__clang__)) >=20 > /* > ** We have to use our own definitions instead of the mandatory (!) = unwind.h, > @@ -232,7 +362,6 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, int = actions, > lua_State *L; > if (version !=3D 1) > return _URC_FATAL_PHASE1_ERROR; > - UNUSED(uexclass); > cf =3D (void *)_Unwind_GetCFA(ctx); > L =3D cframe_L(cf); > if ((actions & _UA_SEARCH_PHASE)) { > @@ -280,6 +409,9 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, int = actions, > ** it on non-x64 because the interpreter restores all callee-saved = regs. > */ > lj_err_throw(L, errcode); > +#if LJ_TARGET_X64 > +#error "Broken build system -- only use the provided Makefiles!" > +#endif > #endif > } > return _URC_CONTINUE_UNWIND; > @@ -292,14 +424,6 @@ static _Unwind_Exception static_uex; > #else > static __thread _Unwind_Exception static_uex; > #endif > - > -/* Raise DWARF2 exception. */ > -static void err_raise_ext(int errcode) > -{ > - static_uex.exclass =3D LJ_UEXCLASS_MAKE(errcode); > - static_uex.excleanup =3D NULL; > - _Unwind_RaiseException(&static_uex); > -} > #endif >=20 > #else /* LJ_TARGET_ARM */ > @@ -373,132 +497,22 @@ LJ_FUNCA int lj_err_unwind_arm(int state, = _Unwind_Control_Block *ucb, >=20 > #if LJ_UNWIND_EXT > static __thread _Unwind_Control_Block static_uex; > +#endif > +#endif /* LJ_TARGET_ARM */ >=20 > -static void err_raise_ext(int errcode) > +#if LJ_UNWIND_EXT > +/* Raise external exception. */ > +static void err_raise_ext(global_State *g, int errcode) > { > +#if LJ_HASJIT > + setmref(g->jit_base, NULL); > +#endif > memset(&static_uex, 0, sizeof(static_uex)); > static_uex.exclass =3D LJ_UEXCLASS_MAKE(errcode); > _Unwind_RaiseException(&static_uex); > } > #endif >=20 > -#endif /* LJ_TARGET_ARM */ > - > -#elif LJ_ABI_WIN > - > -/* > -** Someone in Redmond owes me several days of my life. A lot of this = is > -** undocumented or just plain wrong on MSDN. Some of it can be = gathered > -** from 3rd party docs or must be found by trial-and-error. They = really > -** don't want you to write your own language-specific exception = handler > -** or to interact gracefully with MSVC. :-( > -** > -** Apparently MSVC doesn't call C++ destructors for foreign = exceptions > -** unless you compile your C++ code with /EHa. Unfortunately this = means > -** catch (...) also catches things like access violations. The use of > -** _set_se_translator doesn't really help, because it requires /EHa, = too. > -*/ > - > -#define WIN32_LEAN_AND_MEAN > -#include > - > -#if LJ_TARGET_X64 > -/* Taken from: http://www.nynaeve.net/?p=3D99 */ > -typedef struct UndocumentedDispatcherContext { > - ULONG64 ControlPc; > - ULONG64 ImageBase; > - PRUNTIME_FUNCTION FunctionEntry; > - ULONG64 EstablisherFrame; > - ULONG64 TargetIp; > - PCONTEXT ContextRecord; > - void (*LanguageHandler)(void); > - PVOID HandlerData; > - PUNWIND_HISTORY_TABLE HistoryTable; > - ULONG ScopeIndex; > - ULONG Fill0; > -} UndocumentedDispatcherContext; > -#else > -typedef void *UndocumentedDispatcherContext; > -#endif > - > -/* Another wild guess. */ > -extern void __DestructExceptionObject(EXCEPTION_RECORD *rec, int = nothrow); > - > -#if LJ_TARGET_X64 && defined(MINGW_SDK_INIT) > -/* Workaround for broken MinGW64 declaration. */ > -VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) = asm("RtlUnwindEx"); > -#define RtlUnwindEx RtlUnwindEx_FIXED > -#endif > - > -#define LJ_MSVC_EXCODE ((DWORD)0xe06d7363) > -#define LJ_GCC_EXCODE ((DWORD)0x20474343) > - > -#define LJ_EXCODE ((DWORD)0xe24c4a00) > -#define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c)) > -#define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <=3D 0xff) > -#define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff)) > - > -/* Windows exception handler for interpreter frame. */ > -LJ_FUNCA int lj_err_unwind_win(EXCEPTION_RECORD *rec, > - void *f, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) > -{ > -#if LJ_TARGET_X64 > - void *cf =3D f; > -#else > - void *cf =3D (char *)f - CFRAME_OFS_SEH; > -#endif > - lua_State *L =3D cframe_L(cf); > - int errcode =3D LJ_EXCODE_CHECK(rec->ExceptionCode) ? > - LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; > - if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ > - /* Unwind internal frames. */ > - err_unwind(L, cf, errcode); > - } else { > - void *cf2 =3D err_unwind(L, cf, 0); > - if (cf2) { /* We catch it, so start unwinding the upper frames. = */ > - if (rec->ExceptionCode =3D=3D LJ_MSVC_EXCODE || > - rec->ExceptionCode =3D=3D LJ_GCC_EXCODE) { > -#if LJ_TARGET_WINDOWS > - __DestructExceptionObject(rec, 1); > -#endif > - setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); > - } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { > - /* Don't catch access violations etc. */ > - return 1; /* ExceptionContinueSearch */ > - } > -#if LJ_TARGET_X64 > - /* Unwind the stack and call all handlers for all lower C = frames > - ** (including ourselves) again with EH_UNWINDING set. Then set > - ** rsp =3D cf, rax =3D errcode and jump to the specified = target. > - */ > - RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode !=3D = LUA_YIELD) ? > - lj_vm_unwind_ff_eh : > - lj_vm_unwind_c_eh), > - rec, (void *)(uintptr_t)errcode, ctx, = dispatch->HistoryTable); > - /* RtlUnwindEx should never return. */ > -#else > - UNUSED(ctx); > - UNUSED(dispatch); > - /* Call all handlers for all lower C frames (including = ourselves) again > - ** with EH_UNWINDING set. Then call the specified function, = passing cf > - ** and errcode. > - */ > - lj_vm_rtlunwind(cf, (void *)rec, > - (cframe_unwind_ff(cf2) && errcode !=3D LUA_YIELD) ? > - (void *)lj_vm_unwind_ff : (void *)lj_vm_unwind_c, errcode); > - /* lj_vm_rtlunwind does not return. */ > -#endif > - } > - } > - return 1; /* ExceptionContinueSearch */ > -} > - > -/* Raise Windows exception. */ > -static void err_raise_ext(int errcode) > -{ > - RaiseException(LJ_EXCODE_MAKE(errcode), 1 /* EH_NONCONTINUABLE */, = 0, NULL); > -} > - > #endif >=20 > /* -- Error handling = ------------------------------------------------------ */ > @@ -508,22 +522,23 @@ LJ_NOINLINE void LJ_FASTCALL = lj_err_throw(lua_State *L, int errcode) > { > global_State *g =3D G(L); > lj_trace_abort(g); > - setmref(g->jit_base, NULL); > L->status =3D LUA_OK; > #if LJ_UNWIND_EXT > - err_raise_ext(errcode); > + err_raise_ext(g, errcode); > /* > ** A return from this function signals a corrupt C stack that cannot = be > ** unwound. We have no choice but to call the panic function and exit. > ** > ** Usually this is caused by a C function without unwind information. > - ** This should never happen on x64, but may happen if you've = manually > - ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* > - ** non-C++ file with -funwind-tables. > + ** This may happen if you've manually enabled = LUAJIT_UNWIND_EXTERNAL > + ** and forgot to recompile *every* non-C++ file with = -funwind-tables. > */ > if (G(L)->panic) > G(L)->panic(L); > #else > +#if LJ_HASJIT > + setmref(g->jit_base, NULL); > +#endif > { > void *cf =3D err_unwind(L, NULL, errcode); > if (cframe_unwind_ff(cf)) > --=20 > 2.32.1 (Apple Git-133) >=20