mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Use atexit to fix finalizers on Windows #1361.
This commit is contained in:
committed by
Christoffer Lerno
parent
45a94cfe86
commit
3ab201ce10
@@ -24,6 +24,7 @@
|
||||
- Correct '.so' suffix on dynamic libraries on Linux.
|
||||
- Fix bug where inline index access to array in a struct would crash the compiler.
|
||||
- Asserts are now correctly included and traced in when running tests.
|
||||
- Use atexit to fix finalizers on Windows #1361.
|
||||
|
||||
### Stdlib changes
|
||||
- Additional init functions for hashmap.
|
||||
|
||||
@@ -2,8 +2,8 @@ import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
Path path = path::getcwd()!!;
|
||||
foreach (i, p : path::ls(path)!!)
|
||||
Path path = path::new_cwd()!!;
|
||||
foreach (i, p : path::new_ls(path)!!)
|
||||
{
|
||||
io::printfn("%02d %s", i, p.str_view());
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@ module test;
|
||||
import std::io;
|
||||
import std::collections::map;
|
||||
import std::os;
|
||||
import libc;
|
||||
|
||||
fn void bye() @finalizer
|
||||
{
|
||||
libc::puts("Bye from finalizer!");
|
||||
}
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
|
||||
@@ -406,10 +406,26 @@ void llvm_emit_function_body(GenContext *c, Decl *decl)
|
||||
DEBUG_LOG("Generating function %s.", decl->name);
|
||||
if (decl->func_decl.attr_dynamic) vec_add(c->dynamic_functions, decl);
|
||||
assert(decl->backend_ref);
|
||||
if (decl->func_decl.attr_init || decl->func_decl.attr_finalizer)
|
||||
if (decl->func_decl.attr_init || (decl->func_decl.attr_finalizer && compiler.platform.object_format == OBJ_FORMAT_MACHO))
|
||||
{
|
||||
llvm_append_xxlizer(c, decl->func_decl.priority, decl->func_decl.attr_init, decl->backend_ref);
|
||||
}
|
||||
if (decl->func_decl.attr_finalizer && compiler.platform.object_format != OBJ_FORMAT_MACHO)
|
||||
{
|
||||
LLVMValueRef atexit = LLVMGetNamedFunction(c->module, "atexit");
|
||||
if (!atexit) atexit = LLVMAddFunction(c->module, "atexit", c->atexit_type);
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(".__c3_atexit_");
|
||||
scratch_buffer_set_extern_decl_name(decl, false);
|
||||
LLVMValueRef func = LLVMAddFunction(c->module, scratch_buffer_to_string(), c->xtor_func_type);
|
||||
|
||||
LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL);
|
||||
LLVMValueRef args[1] = { decl->backend_ref };
|
||||
LLVMBuildCall2(builder, c->atexit_type, atexit, args, 1, "");
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
llvm_append_xxlizer(c, decl->func_decl.priority, true, func);
|
||||
}
|
||||
llvm_emit_body(c,
|
||||
decl->backend_ref,
|
||||
type_get_resolved_prototype(decl->type),
|
||||
|
||||
@@ -97,6 +97,7 @@ typedef struct GenContext_
|
||||
LLVMTypeRef bool_type;
|
||||
LLVMTypeRef byte_type;
|
||||
LLVMTypeRef introspect_type;
|
||||
LLVMTypeRef atexit_type;
|
||||
LLVMTypeRef fault_type;
|
||||
LLVMTypeRef size_type;
|
||||
LLVMTypeRef typeid_type;
|
||||
|
||||
@@ -131,13 +131,15 @@ void gencontext_begin_module(GenContext *c)
|
||||
c->ptr_type = LLVMPointerType(c->byte_type, 0);
|
||||
c->size_type = llvm_get_type(c, type_usz);
|
||||
c->typeid_type = llvm_get_type(c, type_typeid);
|
||||
LLVMTypeRef void_type = LLVMVoidTypeInContext(c->context);
|
||||
LLVMTypeRef dtable_type[3] = { c->ptr_type, c->ptr_type, c->ptr_type };
|
||||
c->dtable_type = LLVMStructTypeInContext(c->context, dtable_type, 3, false);
|
||||
c->chars_type = llvm_get_type(c, type_chars);
|
||||
LLVMTypeRef ctor_type[3] = { LLVMInt32TypeInContext(c->context), c->ptr_type, c->ptr_type };
|
||||
c->xtor_entry_type = LLVMStructTypeInContext(c->context, ctor_type, 3, false);
|
||||
c->xtor_func_type = LLVMFunctionType(LLVMVoidTypeInContext(c->context), NULL, 0, false);
|
||||
c->xtor_func_type = LLVMFunctionType(void_type, NULL, 0, false);
|
||||
c->introspect_type = create_introspection_type(c);
|
||||
c->atexit_type = LLVMFunctionType(void_type, &c->ptr_type, 1, false);
|
||||
c->fault_type = create_fault_type(c);
|
||||
c->memcmp_function = NULL;
|
||||
LLVMTypeRef memcmp_types[3] = {c->ptr_type, c->ptr_type, c->size_type };
|
||||
|
||||
@@ -31,8 +31,7 @@ fn void shutdown() @finalizer
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@llvm.global_ctors = appending global [4 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 300, ptr @test.startup2, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @test.start_main, ptr null }, { i32, ptr, ptr } { i32 200, ptr @test.startup1, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @test.empty_startup, ptr null }]
|
||||
@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @test.shutdown, ptr null }]
|
||||
@llvm.global_ctors = appending global [5 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 300, ptr @test.startup2, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @test.start_main, ptr null }, { i32, ptr, ptr } { i32 200, ptr @test.startup1, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @test.empty_startup, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @.__c3_atexit_test.shutdown, ptr null }]
|
||||
|
||||
define void @test.startup2() #0 {
|
||||
entry:
|
||||
@@ -61,3 +60,9 @@ entry:
|
||||
call void @puts(ptr @.str.4)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @.__c3_atexit_test.shutdown() {
|
||||
entry:
|
||||
call void @atexit(ptr @test.shutdown)
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user