Skip to content

Commit 72eade3

Browse files
committed
Fix most of the errors when building WasmKit for WASI
Wasm is the only unsupported platform for WasmKit in the Swift Package Index build matrix. One possible use case is when an implementation for a future Wasm feature is emulated with older Wasm features, when running WasmKit itself in an older Wasm engine. The only remaining roadblock is the lack of `swiftasynccall`, which prevents `_CWasmKit` module from building, but the rest of the modules seem to build fine. For proper testing we also need to fix `swift test` in the Swift toolchain.
1 parent 8eed37f commit 72eade3

File tree

11 files changed

+95
-61
lines changed

11 files changed

+95
-61
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ let package = Package(
121121
if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
122122
package.dependencies += [
123123
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.2"),
124-
.package(url: "https://github.com/apple/swift-system", .upToNextMajor(from: "1.3.0")),
124+
.package(url: "https://github.com/apple/swift-system", from: "1.6.0"),
125125
]
126126
} else {
127127
package.dependencies += [

Sources/SystemExtras/Clock.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Android
1212
#elseif os(Windows)
1313
import CSystem
1414
import ucrt
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif
@@ -41,12 +43,12 @@ extension Clock {
4143
public static var rawMonotonic: Clock { Clock(rawValue: _CLOCK_MONOTONIC_RAW) }
4244
#endif
4345

44-
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD) || os(WASI)
46+
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD)
4547
@_alwaysEmitIntoClient
4648
public static var monotonic: Clock { Clock(rawValue: _CLOCK_MONOTONIC) }
4749
#endif
4850

49-
#if os(OpenBSD) || os(FreeBSD) || os(WASI)
51+
#if os(OpenBSD) || os(FreeBSD)
5052
@_alwaysEmitIntoClient
5153
public static var uptime: Clock { Clock(rawValue: _CLOCK_UPTIME) }
5254
#endif
@@ -92,10 +94,10 @@ extension Clock {
9294
public var rawValue: CInterop.TimeSpec
9395

9496
@_alwaysEmitIntoClient
95-
public var seconds: Int { rawValue.tv_sec }
97+
public var seconds: Int64 { .init(rawValue.tv_sec) }
9698

9799
@_alwaysEmitIntoClient
98-
public var nanoseconds: Int { rawValue.tv_nsec }
100+
public var nanoseconds: Int64 { .init(rawValue.tv_nsec) }
99101

100102
@_alwaysEmitIntoClient
101103
public init(rawValue: CInterop.TimeSpec) {
@@ -104,17 +106,17 @@ extension Clock {
104106

105107
@_alwaysEmitIntoClient
106108
public init(seconds: Int, nanoseconds: Int) {
107-
self.init(rawValue: CInterop.TimeSpec(tv_sec: seconds, tv_nsec: nanoseconds))
109+
self.init(rawValue: CInterop.TimeSpec(tv_sec: .init(seconds), tv_nsec: nanoseconds))
108110
}
109111

110112
@_alwaysEmitIntoClient
111113
public static var now: TimeSpec {
112-
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(_UTIME_NOW)))
114+
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(UTIME_NOW)))
113115
}
114116

115117
@_alwaysEmitIntoClient
116118
public static var omit: TimeSpec {
117-
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(_UTIME_OMIT)))
119+
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(UTIME_OMIT)))
118120
}
119121
}
120122
}

Sources/SystemExtras/Constants.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Android
1212
#elseif os(Windows)
1313
import CSystem
1414
import ucrt
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif
@@ -43,7 +45,7 @@ internal var _AT_NO_AUTOMOUNT: CInt { AT_NO_AUTOMOUNT }
4345
#endif
4446
*/
4547

46-
#if !os(Windows)
48+
#if !os(Windows) && !os(WASI)
4749
@_alwaysEmitIntoClient
4850
internal var _F_GETFL: CInt { F_GETFL }
4951
@_alwaysEmitIntoClient
@@ -61,7 +63,7 @@ internal var _O_SYNC: CInt { O_SYNC }
6163
internal var _O_RSYNC: CInt { O_RSYNC }
6264
#endif
6365

64-
#if !os(Windows)
66+
#if !os(Windows) && !os(WASI)
6567
@_alwaysEmitIntoClient
6668
internal var _UTIME_NOW: CInt {
6769
#if os(Linux) || os(Android)
@@ -132,16 +134,15 @@ internal var _CLOCK_BOOTTIME: CInterop.ClockId { CLOCK_BOOTTIME }
132134
@_alwaysEmitIntoClient
133135
internal var _CLOCK_MONOTONIC_RAW: CInterop.ClockId { CLOCK_MONOTONIC_RAW }
134136
#endif
135-
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD) || os(WASI)
137+
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD)
136138
@_alwaysEmitIntoClient
137139
internal var _CLOCK_MONOTONIC: CInterop.ClockId { CLOCK_MONOTONIC }
138140
#endif
139-
140141
#if SYSTEM_PACKAGE_DARWIN
141142
@_alwaysEmitIntoClient
142143
internal var _CLOCK_UPTIME_RAW: CInterop.ClockId { CLOCK_UPTIME_RAW }
143144
#endif
144-
#if os(OpenBSD) || os(FreeBSD) || os(WASI)
145+
#if os(OpenBSD) || os(FreeBSD)
145146
@_alwaysEmitIntoClient
146147
internal var _CLOCK_UPTIME: CInterop.ClockId { CLOCK_UPTIME }
147148
#endif

Sources/SystemExtras/FileAtOperations.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Android
1212
#elseif os(Windows)
1313
import ucrt
1414
import WinSDK
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif

Sources/SystemExtras/FileOperations.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Android
1212
#elseif os(Windows)
1313
import ucrt
1414
import WinSDK
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif
@@ -344,6 +346,8 @@ extension FileDescriptor {
344346
#if os(Windows)
345347
// FIXME: Need to query by `NtQueryInformationFile`?
346348
return .success(OpenOptions(rawValue: 0))
349+
#elseif os(WASI)
350+
return .failure(Errno.notSupported)
347351
#else
348352
valueOrErrno(retryOnInterrupt: false) {
349353
system_fcntl(self.rawValue, _F_GETFL)
@@ -511,15 +515,31 @@ extension FileDescriptor {
511515

512516
@_alwaysEmitIntoClient
513517
public var name: String {
518+
#if os(WASI)
519+
// ClangImporter can't handle `char d_name[]`, but it's right after `unsigned char d_type`.
520+
withUnsafePointer(to: &rawValue.pointee.d_type) { dType in
521+
let dName = dType + 1
522+
return dName.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: dName)) {
523+
// String initializer copies the given buffer contents, so it's safe.
524+
return String(cString: $0)
525+
}
526+
}
527+
#else
514528
withUnsafePointer(to: &rawValue.pointee.d_name) { dName in
515529
dName.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: dName)) {
516530
// String initializer copies the given buffer contents, so it's safe.
517531
return String(cString: $0)
518532
}
519533
}
534+
#endif
520535
}
521536

522537
public var fileType: FileType {
538+
#if os(WASI)
539+
// https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-filetype-variant
540+
// https://github.com/WebAssembly/wasi-libc/blob/6b45da5b05bc0edda355a6de46101d4b21631985/libc-bottom-half/headers/public/wasi/api.h#L780C9-L780C32
541+
FileType(rawValue: .init(rawValue.pointee.d_type))
542+
#else
523543
switch CInt(rawValue.pointee.d_type) {
524544
case _DT_REG: return .file
525545
case _DT_BLK: return .blockDevice
@@ -529,6 +549,7 @@ extension FileDescriptor {
529549
case _DT_SOCK: return .socket
530550
default: return .unknown
531551
}
552+
#endif
532553
}
533554
}
534555

@@ -657,7 +678,7 @@ public enum FileTime {
657678
public typealias FileTime = Clock.TimeSpec
658679
#endif
659680

660-
#if !os(Windows)
681+
#if !os(Windows) && !os(WASI)
661682

662683
// MARK: - Synchronized Input and Output
663684

Sources/SystemExtras/Syscalls.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Android
1212
#elseif os(Windows)
1313
import ucrt
1414
import WinSDK
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif
@@ -127,7 +129,7 @@ internal func system_symlinkat(
127129
extension CInterop {
128130
#if SYSTEM_PACKAGE_DARWIN
129131
public typealias DirP = UnsafeMutablePointer<DIR>
130-
#elseif os(Linux) || os(Android)
132+
#elseif os(Linux) || os(Android) || os(WASI)
131133
public typealias DirP = OpaquePointer
132134
#else
133135
#error("Unsupported Platform")

Sources/WASI/Platform/PlatformTypes.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ extension WASIAbi.Fdflags {
4040
if platformOpenOptions.contains(.append) {
4141
fdFlags.insert(.APPEND)
4242
}
43-
if platformOpenOptions.contains(.dataSync) {
44-
fdFlags.insert(.DSYNC)
45-
}
4643
if platformOpenOptions.contains(.nonBlocking) {
4744
fdFlags.insert(.NONBLOCK)
4845
}
46+
#if !os(WASI)
47+
if platformOpenOptions.contains(.dataSync) {
48+
fdFlags.insert(.DSYNC)
49+
}
4950
if platformOpenOptions.contains(.fileSync) {
5051
fdFlags.insert(.SYNC)
5152
}
53+
#endif
5254
#if os(Linux)
5355
if platformOpenOptions.contains(.readSync) {
5456
fdFlags.insert(.RSYNC)
@@ -64,15 +66,17 @@ extension WASIAbi.Fdflags {
6466
flags.insert(.append)
6567
}
6668
#if !os(Windows)
67-
if self.contains(.DSYNC) {
68-
flags.insert(.dataSync)
69-
}
7069
if self.contains(.NONBLOCK) {
7170
flags.insert(.nonBlocking)
7271
}
72+
#if !os(WASI)
73+
if self.contains(.DSYNC) {
74+
flags.insert(.dataSync)
75+
}
7376
if self.contains(.SYNC) {
7477
flags.insert(.fileSync)
7578
}
79+
#endif
7680
#if os(Linux)
7781
if self.contains(.RSYNC) {
7882
flags.insert(.readSync)

Sources/WASI/Platform/SandboxPrimitives/Open.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import SystemPackage
1515
#elseif os(Windows)
1616
import CSystem
1717
import ucrt
18+
#elseif os(WASI)
19+
import WASILibc
1820
#else
1921
#error("Unsupported Platform")
2022
#endif

Sources/WASI/WASI.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import WasmTypes
1212
import Android
1313
#elseif os(Windows)
1414
import ucrt
15+
#elseif os(WASI)
16+
import WASILibc
1517
#else
1618
#error("Unsupported Platform")
1719
#endif
@@ -1391,7 +1393,7 @@ public class WASIBridgeToHost: WASI {
13911393
fdTable[2] = .file(StdioFileEntry(fd: stderr, accessMode: .write))
13921394

13931395
for (guestPath, hostPath) in preopens {
1394-
#if os(Windows)
1396+
#if os(Windows) || os(WASI)
13951397
let fd = try FileDescriptor.open(FilePath(hostPath), .readWrite)
13961398
#else
13971399
let fd = try hostPath.withCString { cHostPath in

Sources/WIT/PackageResolver.swift

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -195,52 +195,50 @@ extension SourceFileSyntax {
195195
}
196196
}
197197

198-
#if !os(WASI)
199-
/// A ``PackageFileLoader`` adapter for local file system.
200-
public struct LocalFileLoader: PackageFileLoader {
201-
public typealias FilePath = String
198+
/// A ``PackageFileLoader`` adapter for local file system.
199+
public struct LocalFileLoader: PackageFileLoader {
200+
public typealias FilePath = String
202201

203-
let fileManager: FileManager
202+
let fileManager: FileManager
204203

205-
public init(fileManager: FileManager = .default) {
206-
self.fileManager = fileManager
207-
}
204+
public init(fileManager: FileManager = .default) {
205+
self.fileManager = fileManager
206+
}
208207

209-
enum Error: Swift.Error {
210-
case failedToLoadFile(FilePath)
211-
}
208+
enum Error: Swift.Error {
209+
case failedToLoadFile(FilePath)
210+
}
212211

213-
private func isDirectory(filePath: String) -> Bool {
214-
var isDirectory: ObjCBool = false
215-
let exists = fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory)
216-
return exists && isDirectory.boolValue
217-
}
212+
private func isDirectory(filePath: String) -> Bool {
213+
var isDirectory: ObjCBool = false
214+
let exists = fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory)
215+
return exists && isDirectory.boolValue
216+
}
218217

219-
public func contentsOfWITFile(at filePath: String) throws -> String {
220-
guard let bytes = fileManager.contents(atPath: filePath) else {
221-
throw Error.failedToLoadFile(filePath)
222-
}
223-
return String(decoding: bytes, as: UTF8.self)
218+
public func contentsOfWITFile(at filePath: String) throws -> String {
219+
guard let bytes = fileManager.contents(atPath: filePath) else {
220+
throw Error.failedToLoadFile(filePath)
224221
}
222+
return String(decoding: bytes, as: UTF8.self)
223+
}
225224

226-
public func packageFiles(in packageDirectory: String) throws -> [String] {
227-
let dirURL = URL(fileURLWithPath: packageDirectory)
228-
return try fileManager.contentsOfDirectory(atPath: packageDirectory).filter { fileName in
229-
return fileName.hasSuffix(".wit")
230-
&& {
231-
let filePath = dirURL.appendingPathComponent(fileName)
232-
return !isDirectory(filePath: filePath.path)
233-
}()
234-
}
235-
.map { dirURL.appendingPathComponent($0).path }
225+
public func packageFiles(in packageDirectory: String) throws -> [String] {
226+
let dirURL = URL(fileURLWithPath: packageDirectory)
227+
return try fileManager.contentsOfDirectory(atPath: packageDirectory).filter { fileName in
228+
return fileName.hasSuffix(".wit")
229+
&& {
230+
let filePath = dirURL.appendingPathComponent(fileName)
231+
return !isDirectory(filePath: filePath.path)
232+
}()
236233
}
234+
.map { dirURL.appendingPathComponent($0).path }
235+
}
237236

238-
public func dependencyDirectories(from packageDirectory: String) throws -> [String] {
239-
let dirURL = URL(fileURLWithPath: packageDirectory)
240-
let depsDir = dirURL.appendingPathComponent("deps")
241-
guard isDirectory(filePath: depsDir.path) else { return [] }
242-
return try fileManager.contentsOfDirectory(atPath: depsDir.path)
243-
}
237+
public func dependencyDirectories(from packageDirectory: String) throws -> [String] {
238+
let dirURL = URL(fileURLWithPath: packageDirectory)
239+
let depsDir = dirURL.appendingPathComponent("deps")
240+
guard isDirectory(filePath: depsDir.path) else { return [] }
241+
return try fileManager.contentsOfDirectory(atPath: depsDir.path)
244242
}
243+
}
245244

246-
#endif

0 commit comments

Comments
 (0)