Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/coreclr/debug/datadescriptor-shared/contract-descriptor.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,33 @@ struct ContractDescriptor CONTRACT_NAME = {
// Due to linking order, the export may also need to be added to
// the EXPORTED_FUNCTIONS setting for emcc.
// See https://emscripten.org/docs/getting_started/FAQ.html#why-do-functions-in-my-c-c-source-code-vanish-when-i-compile-to-webassembly
#define _GETTER_NAME(exportname) Get ## exportname
#define GETTER_NAME(exportname) _GETTER_NAME(exportname)
#define _GETTER_NAME_STR(exportname) "Get" #exportname
#define GETTER_NAME_STR(exportname) _GETTER_NAME_STR(exportname)
Comment thread
lewing marked this conversation as resolved.

#if defined(EXPORT_CONTRACT) && defined(__EMSCRIPTEN__)
#include <emscripten.h>

#define _GETTER_NAME(exportname) Get ## exportname
#define GETTER_NAME(exportname) _GETTER_NAME(exportname)
extern void* EMSCRIPTEN_KEEPALIVE GETTER_NAME(CONTRACT_NAME)()
{
return (void*)&CONTRACT_NAME;
}
#endif // EXPORT_CONTRACT && __EMSCRIPTEN__
#elif defined(EXPORT_CONTRACT) && defined(__wasm__)
// Non-emscripten wasm (e.g. wasi-sdk): export the getter with an explicit export name so the
// descriptor symbol is both reachable by a native host and, critically, kept alive by the linker.
// Without an export rooting it, --gc-sections removes the descriptor from the final module (the
// emscripten path above relies on EMSCRIPTEN_KEEPALIVE for the same reason).
//
// This intentionally keys on the compiler-provided __wasm__ rather than the CoreCLR TARGET_WASM
// define. datadescriptor-shared is compiled by multiple consumers and TARGET_WASM (set only by
// CoreCLR's configurecompiler.cmake, and gated on IGNORE_DEFAULT_TARGET_ARCH) is not guaranteed to
// reach every one of them. Since the whole point of this branch is to keep the descriptor alive on
// any wasm toolchain, it must depend on a macro that is always defined when targeting wasm; __wasm__
// is set by the compiler itself for exactly that.
__attribute__((export_name(GETTER_NAME_STR(CONTRACT_NAME))))
void* GETTER_NAME(CONTRACT_NAME)()
{
return (void*)&CONTRACT_NAME;
}
#endif // EXPORT_CONTRACT && (__EMSCRIPTEN__ || __wasm__)