From ce17dbe240cdf2ab6d6036d261f7535c0de4c009 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 2 Jul 2024 02:48:48 +0200 Subject: [PATCH] Bug fix for rethrow + defer catch. More types and functions for win32 --- lib/std/os/win32/gdi.c3 | 107 +++++++++++++++++++++++++++++++ releasenotes.md | 1 + src/compiler/llvm_codegen_expr.c | 3 + src/compiler/llvm_codegen_stmt.c | 2 + 4 files changed, 113 insertions(+) create mode 100644 lib/std/os/win32/gdi.c3 diff --git a/lib/std/os/win32/gdi.c3 b/lib/std/os/win32/gdi.c3 new file mode 100644 index 000000000..3eddbb7e4 --- /dev/null +++ b/lib/std/os/win32/gdi.c3 @@ -0,0 +1,107 @@ +module std::os::win32 @if(env::WIN32); + +struct Win32_RECT +{ + Win32_LONG left; + Win32_LONG top; + Win32_LONG right; + Win32_LONG bottom; +} + +struct Win32_POINT +{ + Win32_LONG x; + Win32_LONG y; +} + +struct Win32_SIZE +{ + Win32_LONG cx; + Win32_LONG cy; +} + +struct Win32_PAINTSTRUCT +{ + Win32_HDC hdc; + Win32_BOOL fErase; + Win32_RECT rcPaint; + Win32_BOOL fRestore; + Win32_BOOL fIncUpdate; + Win32_BYTE[32] rgbReserved; +} + +struct Win32_MSG +{ + Win32_HWND hwnd; + Win32_UINT message; + Win32_WPARAM wParam; + Win32_LPARAM lParam; + Win32_DWORD time; + Win32_POINT pt; + Win32_DWORD lPrivate; +} + +struct Win32_WNDCLASSEXW +{ + Win32_UINT cbSize; + Win32_UINT style; + Win32_WNDPROC lpfnWndProc; + CInt cbClsExtra; + CInt cbWndExtra; + Win32_HINSTANCE hInstance; + Win32_HICON hIcon; + Win32_HCURSOR hCursor; + Win32_HBRUSH hbrBackground; + Win32_LPCWSTR lpszMenuName; + Win32_LPCWSTR lpszClassName; + Win32_HICON hIconSm; +} + +def Win32_PSIZE = Win32_SIZE*; +def Win32_NPSIZE = Win32_SIZE*; +def Win32_LPSIZE = Win32_SIZE*; + +def Win32_PPOINT = Win32_POINT*; +def Win32_NPOINT = Win32_POINT*; +def Win32_LPOINT = Win32_POINT*; + +def Win32_PRECT = Win32_RECT*; +def Win32_NPRECT = Win32_RECT*; +def Win32_LPRECT = Win32_RECT*; + +def Win32_PMSG = Win32_MSG*; +def Win32_LPMSG = Win32_MSG*; +def Win32_NPMSG = Win32_MSG*; + +def Win32_PPAINTSTRUCT = Win32_PAINTSTRUCT*; +def Win32_LPPAINTSTRUCT = Win32_PAINTSTRUCT*; +def Win32_NPPAINTSTRUCT = Win32_PAINTSTRUCT*; + +def Win32_PWNDCLASSEXW = Win32_WNDCLASSEXW*; +def Win32_LPWNDCLASSEXW = Win32_WNDCLASSEXW*; +def Win32_NPWNDCLASSEXW = Win32_WNDCLASSEXW*; + +def Win32_ATOM = ushort; + +def Win32_WNDPROC = fn Win32_LRESULT(Win32_HWND, Win32_UINT, Win32_WPARAM, Win32_LPARAM); + +extern fn int messageBoxW(Win32_HWND hWnd, Win32_LPCWSTR lpText, Win32_LPCWSTR lpCaption, Win32_UINT uType) @extern("MessageBoxW"); +extern fn Win32_HCURSOR loadCursorW(Win32_HINSTANCE instance, Win32_LPCWSTR cursorName) @extern("LoadCursorW"); +extern fn Win32_HICON loadIconW(Win32_HINSTANCE instance, Win32_LPCWSTR iconName) @extern("LoadIconW"); +extern fn Win32_ATOM registerClassExW(Win32_WNDCLASSEXW*) @extern("RegisterClassExW"); +extern fn Win32_HWND createWindowExW(Win32_DWORD, Win32_LPCWSTR, Win32_LPCWSTR, Win32_DWORD, CInt, CInt, CInt, CInt, Win32_HWND, Win32_HMENU, Win32_HINSTANCE, Win32_LPVOID) @extern("CreateWindowExW"); +extern fn Win32_BOOL showWindow(Win32_HWND, CInt) @extern("ShowWindow"); +extern fn Win32_BOOL updateWindow(Win32_HWND) @extern("UpdateWindow"); +extern fn Win32_BOOL getMessageW(Win32_LPMSG, Win32_HWND, Win32_UINT, Win32_UINT) @extern("GetMessageW"); +extern fn Win32_BOOL translateMessage(Win32_MSG* lpMsg) @extern("TranslateMessage"); +extern fn Win32_BOOL dispatchMessage(Win32_MSG* lpMsg) @extern("DispatchMessageW"); +extern fn Win32_LRESULT defWindowProcW(Win32_HWND, Win32_UINT, Win32_WPARAM, Win32_LPARAM) @extern("DefWindowProcW"); +extern fn void postQuitMessage(CInt) @extern("PostQuitMessage"); +extern fn Win32_HDC beginPaint(Win32_HWND, Win32_LPPAINTSTRUCT) @extern("BeginPaint"); +extern fn Win32_BOOL endPaint(Win32_HWND, Win32_LPPAINTSTRUCT) @extern("EndPaint"); + +// Function declarations from gdi32.dll +extern fn Win32_HBRUSH createSolidBrush(Win32_COLORREF) @extern("CreateSolidBrush"); +extern fn Win32_COLORREF setTextColor(Win32_HDC, Win32_COLORREF) @extern("SetTextColor"); +extern fn CInt setBkMode(Win32_HDC, CInt) @extern("SetBkMode"); +extern fn Win32_BOOL textOut(Win32_HDC, CInt, CInt, Win32_LPCWSTR, CInt) @extern("TextOutW"); \ No newline at end of file diff --git a/releasenotes.md b/releasenotes.md index 882e28fdd..881f92e89 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -27,6 +27,7 @@ - Fix distinct inline conversions. - Bit negating const zero flags would give an incorrect result. - Fix to scalar -> vector conversions. +- Bug fix for rethrow + defer catch. ### Stdlib changes - Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions. diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index e17bd155c..50a73e081 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4367,7 +4367,9 @@ static inline void llvm_emit_rethrow_expr(GenContext *c, BEValue *be_value, Expr // Ensure we are on a branch that is non-empty. if (llvm_emit_check_block_branch(c)) { + c->defer_error_var = error_var; llvm_emit_statement_chain(c, expr->rethrow_expr.cleanup); + c->defer_error_var = NULL; BEValue value; llvm_value_set_address_abi_aligned(&value, error_var, type_anyfault); if (expr->rethrow_expr.in_block) @@ -6804,6 +6806,7 @@ static LLVMValueRef llvm_get_benchmark_hook_global(GenContext *c, Expr *expr) INLINE void llvm_emit_last_fault(GenContext *c, BEValue *value) { + assert(c->defer_error_var); llvm_value_set_address_abi_aligned(value, c->defer_error_var, type_anyfault); } diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 876c58a9a..c08b242b9 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -274,6 +274,7 @@ static inline void llvm_emit_return(GenContext *c, Ast *ast) llvm_emit_block(c, error_return_block); c->defer_error_var = error_out; llvm_emit_statement_chain(c, ast->return_stmt.cleanup_fail); + c->defer_error_var = NULL; BEValue value; llvm_value_set_address_abi_aligned(&value, error_out, type_anyfault); llvm_emit_return_abi(c, NULL, &value); @@ -322,6 +323,7 @@ static inline void llvm_emit_block_exit_return(GenContext *c, Ast *ast) llvm_emit_block(c, err_cleanup_block); c->defer_error_var = exit->block_error_var; llvm_emit_statement_chain(c, err_cleanup); + c->defer_error_var = NULL; llvm_emit_jmp(c, exit->block_optional_exit); } else