Skip to content

Commit 1fa232d

Browse files
[wasm] Mark errno as nonisolated(unsafe) in wasi-libc
This patch is a workaround to reflect the fact that `errno` is thread-local and can be accessed from any actor. This is a temporary solution until we have `__swift_attr__` support in apinotes or `thread_local` support in ClangImporter. This change is required to build swift-corelibs-foundation with Swift 6 language mode.
1 parent 920c560 commit 1fa232d

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

test/stdlib/WASILibcAPI.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -typecheck -swift-version 6 %s -verify
2+
// REQUIRES: executable_test
3+
// REQUIRES: OS=wasi
4+
5+
import WASILibc
6+
7+
// errno is a global thread-local variable, so it should be accessible
8+
// from any context.
9+
10+
enum TestErrno {
11+
static func testSyncContext() {
12+
_ = errno
13+
errno = 0
14+
}
15+
static func testAsyncContext() async {
16+
_ = errno
17+
errno = 0
18+
}
19+
}

utils/swift_build_support/swift_build_support/products/wasisysroot.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def _build(self, host_target, thread_model='single', target_triple='wasm32-wasi'
5858

5959
sysroot_build_dir = WASILibc.sysroot_build_path(
6060
build_root, host_target, target_triple)
61+
sysroot_install_dir = WASILibc.sysroot_install_path(build_root, target_triple)
6162
# FIXME: Manually create an empty dir that is usually created during
6263
# check-symbols. The directory is required during sysroot installation step.
6364
os.makedirs(os.path.join(sysroot_build_dir, "share"), exist_ok=True)
@@ -74,14 +75,46 @@ def _build(self, host_target, thread_model='single', target_triple='wasm32-wasi'
7475
'-C', self.source_dir,
7576
'OBJDIR=' + os.path.join(self.build_dir, 'obj-' + thread_model),
7677
'SYSROOT=' + sysroot_build_dir,
77-
'INSTALL_DIR=' + WASILibc.sysroot_install_path(build_root, target_triple),
78+
'INSTALL_DIR=' + sysroot_install_dir,
7879
'CC=' + os.path.join(clang_tools_path, 'clang'),
7980
'AR=' + os.path.join(llvm_tools_path, 'llvm-ar'),
8081
'NM=' + os.path.join(llvm_tools_path, 'llvm-nm'),
8182
'THREAD_MODEL=' + thread_model,
8283
'TARGET_TRIPLE=' + target_triple,
8384
])
8485

86+
# FIXME(katei): Workaround to access `errno` without actor isolation.
87+
# Remove the workaround once we fixed
88+
# https://github.com/swiftlang/swift/issues/75819 or
89+
# https://github.com/swiftlang/swift/issues/75820
90+
errno_patch = """diff --git a/__errno.h b/__errno.h
91+
index 4fd983a..7e9e2d9 100644
92+
--- a/__errno.h
93+
+++ b/__errno.h
94+
@@ -5,6 +5,15 @@
95+
extern "C" {
96+
#endif
97+
98+
+// BEGIN SWIFT PATCH
99+
+#if __swift__
100+
+// NOTE: Mark errno as nonisolated(unsafe) so that it can be accessed from any
101+
+// actor. This is a workaround until we have one of the following:
102+
+// - `__swift_attr__` support in apinotes
103+
+// - `thread_local` support in ClangImporter
104+
+__attribute__((__swift_attr__("nonisolated(unsafe)")))
105+
+#endif
106+
+// END SWIFT PATCH
107+
#ifdef __cplusplus
108+
extern thread_local int errno;
109+
#else
110+
"""
111+
to_patch = os.path.join(sysroot_install_dir, "include", "__errno.h")
112+
import tempfile
113+
with tempfile.NamedTemporaryFile(mode='w') as f:
114+
f.write(errno_patch)
115+
f.flush()
116+
shell.call(["patch", to_patch, f.name])
117+
85118
@classmethod
86119
def get_dependencies(cls):
87120
return [llvm.LLVM]

0 commit comments

Comments
 (0)