From 13d95280114c29339d793800d2f5add384a3cdbc Mon Sep 17 00:00:00 2001 From: IsaacShelton Date: Thu, 2 Dec 2021 18:49:27 -0600 Subject: [PATCH] Added support for global state when using 'WinMain' instead of traditional 'main' entry point --- Makefile | 2 +- include/AST/ast.h | 1 + src/AST/ast.c | 3 +++ src/BKEND/ir_to_llvm.c | 4 ++-- src/IRGEN/ir_gen.c | 4 ++-- src/IRGEN/ir_gen_stmt.c | 4 +++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index e68a3266..64cd5dca 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ UNIX_LLVM_BUILD_INCLUDE= UNIX_LIBCURL_LIB=/opt/homebrew/opt/curl/lib UNIX_LIBCURL_INCLUDE=/opt/homebrew/opt/curl/lib UNIX_LIBCURL_BUILD_INCLUDE= -DEBUG_ADDRESS_SANITIZE=true +DEBUG_ADDRESS_SANITIZE=false #UNIX_CC=gcc #UNIX_CXX=g++ #UNIX_LLVM_LIB=/usr/lib/llvm-7/lib diff --git a/include/AST/ast.h b/include/AST/ast.h index 8b8e5ed9..c097c7f0 100644 --- a/include/AST/ast.h +++ b/include/AST/ast.h @@ -72,6 +72,7 @@ typedef struct { #define AST_FUNC_AUTOGEN TRAIT_9 #define AST_FUNC_VARIADIC TRAIT_A #define AST_FUNC_IMPLICIT TRAIT_B +#define AST_FUNC_WINMAIN TRAIT_C // Additional AST function traits for builtin uses #define AST_FUNC_WARN_BAD_PRINTF_FORMAT TRAIT_2_1 diff --git a/src/AST/ast.c b/src/AST/ast.c index 4367aedf..65aea1b6 100644 --- a/src/AST/ast.c +++ b/src/AST/ast.c @@ -873,6 +873,9 @@ void ast_func_create_template(ast_func_t *func, strong_cstr_t name, bool is_stdc if(is_stdcall) func->traits |= AST_FUNC_STDCALL; if(is_foreign) func->traits |= AST_FUNC_FOREIGN; if(is_implicit) func->traits |= AST_FUNC_IMPLICIT; + + // Handle WinMain + if(strcmp(name, "WinMain") == 0 && export_as && strcmp(export_as, "WinMain") == 0) func->traits |= AST_FUNC_WINMAIN; } bool ast_func_is_polymorphic(ast_func_t *func){ diff --git a/src/BKEND/ir_to_llvm.c b/src/BKEND/ir_to_llvm.c index ea779687..02aa09e8 100644 --- a/src/BKEND/ir_to_llvm.c +++ b/src/BKEND/ir_to_llvm.c @@ -1612,7 +1612,7 @@ errorcode_t ir_to_llvm(compiler_t *compiler, object_t *object){ const char *linker = "ld.exe"; // May need to change depending on system etc. const char *linker_options = "--start-group"; const char *root = compiler->root; - const char *subsystem = (compiler->traits & COMPILER_WINDOWED) ? "-subsystem,windows " : ""; + const char *subsystem = (compiler->traits & COMPILER_WINDOWED) ? "--subsystem windows " : ""; link_command = mallocandsprintf("\"\"%s%s\" -static \"%scrt2.o\" \"%scrtbegin.o\" %s%s \"%s\" \"%slibdep.a\" C:/Windows/System32/msvcrt.dll %s-o \"%s\"\"", root, linker, root, root, linker_options, linker_additional, object_filename, root, subsystem, compiler->output_filename); } #else @@ -1622,7 +1622,7 @@ errorcode_t ir_to_llvm(compiler_t *compiler, object_t *object){ const char *linker = "cross-compile-windows/x86_64-w64-mingw32-ld"; const char *linker_options = ""; const char *root = compiler->root; - const char *subsystem = (compiler->traits & COMPILER_WINDOWED) ? "-subsystem,windows " : ""; + const char *subsystem = (compiler->traits & COMPILER_WINDOWED) ? "--subsystem windows " : ""; strong_cstr_t cross_linker = mallocandsprintf("%s%s", compiler->root, linker); if(!file_exists(cross_linker)){ diff --git a/src/IRGEN/ir_gen.c b/src/IRGEN/ir_gen.c index c0489261..a2d835a3 100644 --- a/src/IRGEN/ir_gen.c +++ b/src/IRGEN/ir_gen.c @@ -340,7 +340,7 @@ errorcode_t ir_gen_functions_body_statements(compiler_t *compiler, object_t *obj ast_expr_t **statements = ast_func->statements; length_t statements_length = ast_func->statements_length; - if(ast_func->traits & AST_FUNC_MAIN){ + if(ast_func->traits & AST_FUNC_MAIN || ast_func->traits & AST_FUNC_WINMAIN){ // Initialize all global variables if(ir_gen_globals_init(&builder)){ module_func->basicblocks = builder.basicblocks; @@ -375,7 +375,7 @@ errorcode_t ir_gen_functions_body_statements(compiler_t *compiler, object_t *obj // Make sure to update references that may have been invalidated ast_func = &object->ast.funcs[ast_func_id]; - if(ast_func->traits & AST_FUNC_MAIN){ + if(ast_func->traits & AST_FUNC_MAIN || ast_func->traits & AST_FUNC_WINMAIN){ handle_deference_for_globals(&builder); build_deinit_svars(&builder); } diff --git a/src/IRGEN/ir_gen_stmt.c b/src/IRGEN/ir_gen_stmt.c index 2e701db6..ff8dbde7 100644 --- a/src/IRGEN/ir_gen_stmt.c +++ b/src/IRGEN/ir_gen_stmt.c @@ -530,6 +530,7 @@ errorcode_t ir_gen_stmt_return(ir_builder_t *builder, ast_expr_return_t *stmt, b bool is_in_main_function; bool is_in_pass_function; bool is_in_defer_function; + bool is_in_winmain_function; bool autogen_enabled; // 'ast_func' is only guaranteed to be valid within this scope. @@ -542,6 +543,7 @@ errorcode_t ir_gen_stmt_return(ir_builder_t *builder, ast_expr_return_t *stmt, b is_in_main_function = ast_func->traits & AST_FUNC_MAIN; is_in_pass_function = ast_func->traits & AST_FUNC_PASS; is_in_defer_function = ast_func->traits & AST_FUNC_DEFER; + is_in_winmain_function = ast_func->traits & AST_FUNC_WINMAIN; autogen_enabled = ast_func->traits & AST_FUNC_AUTOGEN; } @@ -602,7 +604,7 @@ errorcode_t ir_gen_stmt_return(ir_builder_t *builder, ast_expr_return_t *stmt, b if(ir_gen_variable_deference(builder, NULL)) return FAILURE; // Make '__defer__()' calls for global variables and (anonymous) static variables running out of scope - if(is_in_main_function){ + if(is_in_main_function || is_in_winmain_function){ handle_deference_for_globals(builder); build_deinit_svars(builder); }