Over in wasi-sdk land we've recently been trying to get the whole 9 yards of major ABI-related features all working at the same time for componentize-py which uses:
- Dynamic linking - used so the python interpreter can "dlopen" native extensions, although for our purposes these are pre-bundled into a single component so it's mostly dynamically discovering where things were placed by the linker.
- Threads - with wasip3 we're in the process of stressing/testing coop threads and making sure it works in all the places
- Exceptions - some popular Python extensions use C++ exceptions as well
I think we're almost to the point where we can get everything working, including some refactors to how TLS works in wasip3, but there's one final piece that I'm not sure how to get working. I think that this is a limitation of tooling today which can't be supported, but I'm not sure of this -- hence the issue!
The specific case we're running into is that I'm not sure how dynamic library A can refer to a thread-local variable in dynamic library B. One example of this is the __wasm_lpad_context symbol used in the codegen of C++ exceptions. Right now libraries import a single "TLS base" value, either a global or a __wasm_tls_base function, which is the base of that dynamic library's TLS block. References to TLS values are then static offsets from that base, but this doesn't work when library A tries to access library B's TLS since A only has access to its own base pointer. The example in this situation is that the main module is trying to modify __wasm_lpad_context in the libunwind.so module, but it has no means of getting the base pointer to that location.
This issue boils down to: is it possible for cross-library thread-local symbols to work right now in the face of threading being enabled? We worked around the one instance of this in wasi-libc, for example, by defining errno to be *__errno_location() like it is on some native platforms as well. In the case of __wasm_lpad_context the accesses here are internal within LLVM's codegen for exception handling so it's not as easy to modify.
Over in wasi-sdk land we've recently been trying to get the whole 9 yards of major ABI-related features all working at the same time for componentize-py which uses:
I think we're almost to the point where we can get everything working, including some refactors to how TLS works in wasip3, but there's one final piece that I'm not sure how to get working. I think that this is a limitation of tooling today which can't be supported, but I'm not sure of this -- hence the issue!
The specific case we're running into is that I'm not sure how dynamic library A can refer to a thread-local variable in dynamic library B. One example of this is the
__wasm_lpad_contextsymbol used in the codegen of C++ exceptions. Right now libraries import a single "TLS base" value, either a global or a__wasm_tls_basefunction, which is the base of that dynamic library's TLS block. References to TLS values are then static offsets from that base, but this doesn't work when library A tries to access library B's TLS since A only has access to its own base pointer. The example in this situation is that the main module is trying to modify__wasm_lpad_contextin thelibunwind.somodule, but it has no means of getting the base pointer to that location.This issue boils down to: is it possible for cross-library thread-local symbols to work right now in the face of threading being enabled? We worked around the one instance of this in wasi-libc, for example, by defining
errnoto be*__errno_location()like it is on some native platforms as well. In the case of__wasm_lpad_contextthe accesses here are internal within LLVM's codegen for exception handling so it's not as easy to modify.