-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[WebAssembly] Add ifdefs for the WASI target #29530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a huge change. Please split this up into more focused changes. There can be a single change for the runtime, and a single change for the standard library at least.
lib/IRGen/IRGen.cpp
Outdated
@@ -165,6 +165,12 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) { | |||
TargetOpts.FunctionSections = Opts.FunctionSections; | |||
|
|||
auto *Clang = static_cast<ClangImporter *>(Ctx.getClangModuleLoader()); | |||
|
|||
// WebAssembly doesn't support atomics yet, see https://bugs.swift.org/browse/SR-12097 | |||
if (Clang->getTargetInfo().getTriple().isOSBinFormatWasm()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the extraneous braces. IIRC, we set the ThreadModel
for cygwin/MinGW as well. Can we please set the thread model at one site?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I'm aware this is a single place where ThreadModel
is used in the whole Swift project, it's not set for Cygwin anywhere. The only somewhat related settings for Cygwin that I see are set in createTargetMachine
, but that doesn't give access to TargetOpts
:
if (EffectiveTriple.isArch64Bit() && EffectiveTriple.isWindowsCygwinEnvironment())
cmodel = CodeModel::Large;
import Glibc | ||
#elseif os(Windows) | ||
import MSVCRT | ||
import WinSDK | ||
#endif | ||
|
||
internal func _signalToString(_ signal: Int) -> String { | ||
#if os(WASI) | ||
// no signals support on WASI yet, see https://github.com/WebAssembly/WASI/issues/166 | ||
fatalError("\(#function) is not supported on WebAssembly/WASI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that you should stub out _signalToString
. Instead, you need to die earlier at the point where the signal is being handled. Just drop the entire function on WASI.
// WASI doesn't support child processes | ||
public func spawnChild(_ args: [String]) | ||
-> (pid: pid_t, stdinFD: CInt, stdoutFD: CInt, stderrFD: CInt) { | ||
preconditionFailure("\(#function) is not supported on WebAssembly/WASI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fatalError
, not preconditionFailure
.
preconditionFailure("\(#function) is not supported on WebAssembly/WASI") | ||
} | ||
public func posixWaitpid(_ pid: pid_t) -> ProcessTerminationStatus { | ||
preconditionFailure("\(#function) is not supported on WebAssembly/WASI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar
@@ -125,6 +125,8 @@ public func _stdlib_pipe() -> (readEnd: CInt, writeEnd: CInt, error: CInt) { | |||
let ret = fds.withUnsafeMutableBufferPointer { unsafeFds -> CInt in | |||
#if os(Windows) | |||
return _pipe(unsafeFds.baseAddress, 0, 0) | |||
#elseif os(WASI) | |||
preconditionFailure("no pipes available on WebAssembly/WASI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, this is largely used for the reflection tests. Perhaps we should just disable the reflection tests instead. I really think that given the amount of stuff not available in WASI libc yet, the focus should be improving that first (which is why I stopped and started looking at WASI libc instead).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used in RaceTest.swift
in the implementation of _InterruptibleSleep
on non-Windows platforms. Would _InterruptibleSleep
need a dedicated implementation for WASI instead? Could WebAssembly/WASI#77 be somewhat related?
@@ -12,7 +12,7 @@ | |||
|
|||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) | |||
import Darwin | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) || os(WASI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it might be better to just not build SwiftPrivateThreadExtras
on WASI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would make RaceTest
that uses SwiftPrivateThreadExtras
disabled, requiring us to disable quite a few tests. Do you think that be worth it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to disabling the whole module, if it leads to simpler code. Race tests would not work (and are pointless) without threads anyway.
#endif | ||
#endif // _WIN32 | ||
|
||
#endif // __wasi__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the endif should be before the definition of VectoredCrashHandler
.
@@ -562,7 +562,12 @@ class _InterruptibleSleep { | |||
return | |||
} | |||
|
|||
#if os(WASI) | |||
// WebAssembly/WASI on wasm32 is the only 32-bit platform with Int64 time_t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everywhere throughout this patch, I'd appreciate periods at the end of comments.
@@ -562,7 +562,12 @@ class _InterruptibleSleep { | |||
return | |||
} | |||
|
|||
#if os(WASI) | |||
// WebAssembly/WASI on wasm32 is the only 32-bit platform with Int64 time_t | |||
var timeout = timeval(tv_sec: time_t(duration), tv_usec: 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the code would still compile on other platforms if you the time_t(duration)
variant everywhere (no conditional compilation).
@@ -98,6 +98,9 @@ public func _stdlib_thread_create_block<Argument, Result>( | |||
} else { | |||
return (0, ThreadHandle(bitPattern: threadID)) | |||
} | |||
#elseif os(WASI) | |||
// WASI environment has only a single thread, see https://bugs.swift.org/browse/SR-12097 | |||
return (0, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pthread_create
returns 0 on success. Please return an appropriate errno, like ENOTSUP
.
@@ -128,6 +131,9 @@ public func _stdlib_thread_join<Result>( | |||
} else { | |||
return (CInt(result), nil) | |||
} | |||
#elseif os(WASI) | |||
// WASI environment has only a single thread, see https://bugs.swift.org/browse/SR-12097 | |||
return (0, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, please return EINVAL
.
@@ -35,7 +35,9 @@ public struct _stdlib_thread_barrier_t { | |||
var cond: UnsafeMutablePointer<CONDITION_VARIABLE>? | |||
#elseif os(Cygwin) || os(FreeBSD) | |||
var mutex: UnsafeMutablePointer<pthread_mutex_t?>? | |||
var cond: UnsafeMutablePointer<pthread_cond_t?>? | |||
var cond: UnsafeMutablePointer<pthread_cond_t?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we lost a question mark on this line.
var cond: UnsafeMutablePointer<pthread_cond_t?>? | ||
var cond: UnsafeMutablePointer<pthread_cond_t?> | ||
#elseif os(WASI) | ||
// WASI environment has a only single thread, see https://bugs.swift.org/browse/SR-12097 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the code will pretend to succeed, which does not sound great. Can we produce an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this comment refer to some function? It's currently positioned within a struct property declaration, do you mean that the structs init
should invoke fatalError
or preconditionFailure
when it runs on WASI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about sloppy commenting -- yes, I was trying to attach the comment to the init
, and invoking fatalError
is exactly what I meant.
stdlib/public/core/Builtin.swift
Outdated
@@ -379,7 +379,7 @@ internal var _objectPointerLowSpareBitShift: UInt { | |||
} | |||
|
|||
#if arch(i386) || arch(arm) || arch(powerpc64) || arch(powerpc64le) || arch( | |||
s390x) | |||
s390x) || arch(wasm32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe group wasm32 together with the other 32-bit platforms? (That is, i386, arm, wasm32, and then everything else.)
e3c7637
to
50e5c4a
Compare
@MaxDesiatov Could you reflect this change also for WASI? #29536 |
aa2d6e6
to
a71ae92
Compare
a71ae92
to
0fa22c4
Compare
@@ -12,7 +12,7 @@ | |||
|
|||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) | |||
import Darwin | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) || os(WASI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to disabling the whole module, if it leads to simpler code. Race tests would not work (and are pointless) without threads anyway.
@@ -380,7 +382,7 @@ public var SEM_FAILED: UnsafeMutablePointer<sem_t>? { | |||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) | |||
// The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS. | |||
return UnsafeMutablePointer<sem_t>(bitPattern: -1) | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) | |||
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) || os(WASI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does sem_open()
exist and work on WASI? If not, ifdef out the whole variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does exist and whole semaphore.h
is available too.
@@ -65,7 +65,7 @@ internal func _swift_stdlib_atomicCompareExchangeStrongInt( | |||
object target: UnsafeMutablePointer<Int>, | |||
expected: UnsafeMutablePointer<Int>, | |||
desired: Int) -> Bool { | |||
#if arch(i386) || arch(arm) | |||
#if arch(i386) || arch(arm) || arch(wasm32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other comments that you left say that WebAssembly has no atomics right now. So how do these functions get compiled? Regular loads and stores?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is set in IRGen.cpp
change in this same PR:
if (Clang->getTargetInfo().getTriple().isOSBinFormatWasm())
TargetOpts.ThreadModel = llvm::ThreadModel::Single;
b11dec8
to
b6e79b0
Compare
b6e79b0
to
1d7e592
Compare
Hi @gribozavr @compnerd I've addressed your feedback and added comments with clarifications, could you have another look. Thank you! |
I don't see where in the patch you disable building If you want to submit this change as an incremental improvement, LGTM, but just noting that it seems that some work is still needed to disable building some modules. |
@gribozavr in Would you mind triggering CI for this PR? Thanks again for your help. |
@MaxDesiatov That will avoid linking the |
@swift-ci Please test |
Build failed |
Build failed |
1d7e592
to
31f38f4
Compare
31f38f4
to
6729790
Compare
@gribozavr I've updated
Could you trigger another CI run? Thanks |
I think we need both |
@gribozavr yeah, it does have both, I've restored |
@swift-ci Please test |
@swift-ci Please smoke test |
Thanks for triggering CI! As it has passed and PR got the approval, can it be merged now to avoid potential conflicts appearing and preventing it from being merged as the diff is big enough? |
In |
Do you mean line 80 that precedes |
Yes, that one; the fields of a |
Well, it does build it seems, but thanks for having a look, I'll keep that in mind 👍 |
Disabled by mistake in swiftlang#29530.
Disables/enables stdlib and IRGen code appropriately when targeting WebAssembly/WASI.
This is a part of SR-9307 and #24684.
(cc @kateinoigakukun)