cgen,dl: remove workaround in dl, generate a DllMain() in cgen instead for -shared on windows (#23961)

This commit is contained in:
kbkpbot 2025-03-17 23:04:10 +08:00 committed by GitHub
parent ebfa7d86cf
commit bd2ec679f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 34 additions and 36 deletions

View file

@ -20,25 +20,11 @@ type FN_vcleanup_caller = fn ()
// open loads a given module into the address space of the calling process. // open loads a given module into the address space of the calling process.
pub fn open(filename string, flags int) voidptr { pub fn open(filename string, flags int) voidptr {
res := C.LoadLibrary(filename.to_wide()) res := C.LoadLibrary(filename.to_wide())
// Because LoadLibrary has no constructor, this is a workaround
if !isnil(res) {
vinit_caller := FN_vinit_caller(sym(res, '_vinit_caller'))
if !isnil(vinit_caller) {
vinit_caller()
}
}
return res return res
} }
// close frees the loaded a given module. // close frees the loaded a given module.
pub fn close(handle voidptr) bool { pub fn close(handle voidptr) bool {
// Because FreeLibrary has no destructor, this is a workaround
if !isnil(handle) {
vcleanup_caller := FN_vcleanup_caller(sym(handle, '_vcleanup_caller'))
if !isnil(vcleanup_caller) {
vcleanup_caller()
}
}
return C.FreeLibrary(handle) return C.FreeLibrary(handle)
} }

View file

@ -1082,6 +1082,9 @@ pub fn (mut g Gen) finish() {
g.handle_embedded_files_finish() g.handle_embedded_files_finish()
if g.pref.is_test { if g.pref.is_test {
g.gen_c_main_for_tests() g.gen_c_main_for_tests()
} else if (g.pref.is_shared || g.pref.is_liveshared) && g.pref.os == .windows {
// create DllMain() for windows .dll
g.gen_dll_main()
} else { } else {
g.gen_c_main() g.gen_c_main()
} }

View file

@ -392,3 +392,33 @@ pub fn (mut g Gen) gen_c_main_trace_calls_hook() {
should_trace_c_main := g.pref.should_trace_fn_name('C.main') should_trace_c_main := g.pref.should_trace_fn_name('C.main')
g.writeln('\tu8 bottom_of_stack = 0; g_stack_base = &bottom_of_stack; v__trace_calls__on_c_main(${should_trace_c_main});') g.writeln('\tu8 bottom_of_stack = 0; g_stack_base = &bottom_of_stack; v__trace_calls__on_c_main(${should_trace_c_main});')
} }
// gen_dll_main create DllMain() for windows .dll
pub fn (mut g Gen) gen_dll_main() {
g.writeln('VV_EXPORTED_SYMBOL BOOL DllMain(HINSTANCE hinst,DWORD fdwReason,LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH : {
#if defined(_VGCBOEHM)
GC_set_pages_executable(0);
GC_INIT();
#endif
_vinit_caller();
break;
}
case DLL_THREAD_ATTACH : {
break;
}
case DLL_THREAD_DETACH : {
break;
}
case DLL_PROCESS_DETACH : {
_vcleanup_caller();
break;
}
default:
return false;
}
return true;
}
')
}

View file

@ -1,2 +1 @@
__closure_init(); // vinit_caller() __closure_init(); // vinit_caller()
__closure_init(); // main()

View file

@ -9,23 +9,3 @@ const bar = (foo << 5) + 9
pub fn test_tatltuae() int { pub fn test_tatltuae() int {
return foo + bar return foo + bar
} }
@[callconv: stdcall]
@[export: DllMain]
fn main(hinst voidptr, fdw_reason int, lp_reserved voidptr) bool {
match fdw_reason {
C.DLL_PROCESS_ATTACH {
$if static_boehm ? {
C.GC_INIT()
}
C._vinit(0, 0)
}
C.DLL_THREAD_ATTACH {}
C.DLL_THREAD_DETACH {}
C.DLL_PROCESS_DETACH {}
else {
return false
}
}
return true
}