diff --git a/ci/rebuild-libwit-bindgen-cabi.sh b/ci/rebuild-libwit-bindgen-cabi.sh index 8c311f083..6e2251819 100755 --- a/ci/rebuild-libwit-bindgen-cabi.sh +++ b/ci/rebuild-libwit-bindgen-cabi.sh @@ -48,6 +48,7 @@ wasip3_set=wit_bindgen_${version}_set_task_context rm -f crates/guest-rust/src/rt/wit_bindgen_*.{rs,o,c} rm -f crates/guest-rust/src/rt/libwit_bindgen_cabi_realloc.a rm -f crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a +rm -f crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3_tls.a cat >./crates/guest-rust/src/rt/wit_bindgen_cabi_realloc.rs <<-EOF // This file is generated by $0 @@ -100,6 +101,15 @@ void *wasip3_task_set(void *ptr) { WASIP3_TASK = ptr; return ret; } +EOF + +# On WASIp3, wasi-libc switches TLS blocks between tasks. Compile this helper +# for that target so `_Thread_local` remains TLS; compiling it as MVP would +# silently turn `task_context` into a global shared by all tasks. +cat >./crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.c <<-EOF +// This file is generated by $0 + +#include static _Thread_local void *task_context = NULL; @@ -114,19 +124,30 @@ EOF build() { file=$1 - $WASI_SDK_PATH/bin/clang crates/guest-rust/src/rt/$1.c \ - -O -c -o crates/guest-rust/src/rt/$1.o -mcpu=mvp -fPIC + shift + $WASI_SDK_PATH/bin/clang crates/guest-rust/src/rt/$file.c \ + -O -c -o crates/guest-rust/src/rt/$file.o -fPIC "$@" # Remove the `producers` section. This appears to differ whether the host for # clang is either macOS or Linux. Not needed here anyway, so discard it to help # either host produce the same object. - wasm-tools strip -d producers ./crates/guest-rust/src/rt/$1.o \ - -o ./crates/guest-rust/src/rt/$1.o + wasm-tools strip -d producers ./crates/guest-rust/src/rt/$file.o \ + -o ./crates/guest-rust/src/rt/$file.o } -build wit_bindgen_cabi_realloc -build wit_bindgen_cabi_wasip3 +build wit_bindgen_cabi_realloc -mcpu=mvp +build wit_bindgen_cabi_wasip3 -mcpu=mvp +build wit_bindgen_cabi_wasip3_tls --target=wasm32-wasip3 + +# Catch accidentally compiling the task-local state as a plain global again. +if ! wasm-tools print crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.o \ + | grep -qF '(import "env" "__wasm_get_tls_base"'; then + echo "error: WASIp3 task context must use TLS" >&2 + exit 1 +fi $WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/src/rt/libwit_bindgen_cabi_realloc.a \ crates/guest-rust/src/rt/wit_bindgen_cabi_realloc.o $WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a \ crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.o +$WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3_tls.a \ + crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.o diff --git a/crates/guest-rust/build.rs b/crates/guest-rust/build.rs index 148370c46..0793c250d 100644 --- a/crates/guest-rust/build.rs +++ b/crates/guest-rust/build.rs @@ -18,6 +18,12 @@ fn main() { link_lib("cabi_realloc"); } link_lib("cabi_wasip3"); + + // The no-std async runtime's task context uses WASIp3 TLS. Keep this + // separate from the MVP task helper needed by every wasm32 target. + if target_env == "p3" && !cfg!(feature = "std") { + link_lib("cabi_wasip3_tls"); + } } fn link_lib(name: &str) { diff --git a/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a b/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a index 505ec53ac..8a75b1c3c 100644 Binary files a/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a and b/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3.a differ diff --git a/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3_tls.a b/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3_tls.a new file mode 100644 index 000000000..f9c26bd0d Binary files /dev/null and b/crates/guest-rust/src/rt/libwit_bindgen_cabi_wasip3_tls.a differ diff --git a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.c b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.c index 2f125db01..2e4a50617 100644 --- a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.c +++ b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.c @@ -10,13 +10,3 @@ void *wasip3_task_set(void *ptr) { WASIP3_TASK = ptr; return ret; } - -static _Thread_local void *task_context = NULL; - -void *wit_bindgen_0_62_0_get_task_context(void) { - return task_context; -} - -void wit_bindgen_0_62_0_set_task_context(void *ptr) { - task_context = ptr; -} diff --git a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.o b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.o index fb82a7f8f..5e7eea4c8 100644 Binary files a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.o and b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3.o differ diff --git a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.c b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.c new file mode 100644 index 000000000..3148544ad --- /dev/null +++ b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.c @@ -0,0 +1,13 @@ +// This file is generated by ./ci/rebuild-libwit-bindgen-cabi.sh + +#include + +static _Thread_local void *task_context = NULL; + +void *wit_bindgen_0_62_0_get_task_context(void) { + return task_context; +} + +void wit_bindgen_0_62_0_set_task_context(void *ptr) { + task_context = ptr; +} diff --git a/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.o b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.o new file mode 100644 index 000000000..f569ffab0 Binary files /dev/null and b/crates/guest-rust/src/rt/wit_bindgen_cabi_wasip3_tls.o differ