From 94aa33a7d3efac649856918dcdbc344d6a8feceb Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Tue, 14 Jan 2025 13:12:26 +0100 Subject: [PATCH 1/2] Used fixed initialization for order for global static. The `HILTI_PRE_INIT` macros work on the global `_registered_preinit_functions` container. Since uses of the macro and the global container are likely in different translation units their initialization order can be undetermined (even though we have some manual checks whether the `unique_ptr>` is null). This patch cleans up initialization of the global so it should always be fully initialized when accessed. --- hilti/runtime/include/init.h | 4 ++-- hilti/runtime/src/init.cc | 20 ++++++++------------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/hilti/runtime/include/init.h b/hilti/runtime/include/init.h index 17e8246ea..621ed07b5 100644 --- a/hilti/runtime/include/init.h +++ b/hilti/runtime/include/init.h @@ -48,7 +48,7 @@ extern void registerModule(HiltiModule module); * Macro to schedule a global function to be called at startup time. Execution * will happen either automatically through a static constructor (default), or * if `HILTI_MANUAL_PREINIT` is defined, be triggered through a call to - * `executeCustomPreInits()`. + * `executeManualPreInits()`. */ #ifdef HILTI_MANUAL_PREINIT #define HILTI_PRE_INIT(func) static ::hilti::rt::detail::RegisterManualPreInit __pre_init_##__COUNTER__(func); @@ -62,7 +62,7 @@ class ExecutePreInit { ExecutePreInit(void (*f)()) { (*f)(); } }; -/** Helper class to register a global function to execute through `executeCustomPreInits`. */ +/** Helper class to register a global function to execute through `executeManualPreInits`. */ class RegisterManualPreInit { public: RegisterManualPreInit(void (*f)()); diff --git a/hilti/runtime/src/init.cc b/hilti/runtime/src/init.cc index 1d8d9dc91..b46ca5712 100644 --- a/hilti/runtime/src/init.cc +++ b/hilti/runtime/src/init.cc @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -108,21 +107,18 @@ void hilti::rt::detail::registerModule(HiltiModule module) { globalState()->hilti_modules.emplace_back(module); } -static std::unique_ptr> _registered_preinit_functions; - -RegisterManualPreInit::RegisterManualPreInit(void (*f)()) { - if ( ! _registered_preinit_functions ) - _registered_preinit_functions = std::make_unique>(); - - _registered_preinit_functions->emplace_back(f); +static auto* registered_preinit_functions() { + static std::vector _registered_preinit_functions; + return &_registered_preinit_functions; } +RegisterManualPreInit::RegisterManualPreInit(void (*f)()) { registered_preinit_functions()->emplace_back(f); } + void hilti::rt::executeManualPreInits() { - if ( ! _registered_preinit_functions ) - return; + auto* functions = registered_preinit_functions(); - for ( const auto& f : *_registered_preinit_functions ) + for ( const auto& f : *functions ) (*f)(); - _registered_preinit_functions.reset(); + functions->clear(); } From 2dc508da83aee74789f11cbabf847cc7c6e0a587 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Tue, 14 Jan 2025 13:23:50 +0100 Subject: [PATCH 2/2] Prevent unneeded copy in setting up unit `parseX` functions. --- hilti/toolchain/src/compiler/codegen/codegen.cc | 5 +++-- tests/Baseline/hilti.hiltic.print.yield/output | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hilti/toolchain/src/compiler/codegen/codegen.cc b/hilti/toolchain/src/compiler/codegen/codegen.cc index fe49a16b1..3f6696de8 100644 --- a/hilti/toolchain/src/compiler/codegen/codegen.cc +++ b/hilti/toolchain/src/compiler/codegen/codegen.cc @@ -538,8 +538,9 @@ struct GlobalsVisitor : hilti::visitor::PostOrder { cb.addReturn("::hilti::rt::Nothing()"); } - body.addLambda("cb", "[args_on_heap](::hilti::rt::resumable::Handle* r) -> ::hilti::rt::any", - std::move(cb)); + body.addLambda( + "cb", "[args_on_heap = std::move(args_on_heap)](::hilti::rt::resumable::Handle* r) -> ::hilti::rt::any", + std::move(cb)); body.addLocal({"r", "auto", {}, "std::make_unique<::hilti::rt::Resumable>(std::move(cb))"}); body.addStatement("r->run()"); body.addReturn("std::move(*r)"); diff --git a/tests/Baseline/hilti.hiltic.print.yield/output b/tests/Baseline/hilti.hiltic.print.yield/output index 985b6edd0..a6e4643e1 100644 --- a/tests/Baseline/hilti.hiltic.print.yield/output +++ b/tests/Baseline/hilti.hiltic.print.yield/output @@ -49,7 +49,7 @@ extern auto __hlt::Foo::test(const std::string& x) -> std::string { extern auto hlt::Foo::test(const std::string& x) -> ::hilti::rt::Resumable { auto args = std::make_tuple(::hilti::rt::resumable::detail::copyArg(x)); auto args_on_heap = std::make_shared(std::move(args)); - auto cb = [args_on_heap](::hilti::rt::resumable::Handle* r) -> ::hilti::rt::any { + auto cb = [args_on_heap = std::move(args_on_heap)](::hilti::rt::resumable::Handle* r) -> ::hilti::rt::any { return __hlt::Foo::test(std::get<0>(*args_on_heap)); };