Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ jobs:
wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
test-args: "-Xswiftc -DWASMKIT_CI_TOOLCHAIN_NIGHTLY"

runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
name: "build-linux (${{ matrix.swift }})"

steps:
Expand Down Expand Up @@ -240,7 +240,7 @@ jobs:
run: swift test

build-cmake:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
container:
image: swift:6.2-noble
steps:
Expand All @@ -254,3 +254,17 @@ jobs:
- run: cmake -G Ninja -B ./build
- run: cmake --build ./build
- run: ./build/bin/wasmkit-cli --version

build-wasi:
runs-on: ubuntu-24.04
container:
image: swift:6.2-noble
steps:
- uses: actions/checkout@v4
- name: Install jq
run: apt-get update && apt-get install -y jq
- name: Install Swift SDK
run: swift sdk install https://download.swift.org/swift-6.2-release/wasm/swift-6.2-RELEASE/swift-6.2-RELEASE_wasm.artifactbundle.tar.gz --checksum fe4e8648309fce86ea522e9e0d1dc48e82df6ba6e5743dbf0c53db8429fb5224
- name: Build with the Swift SDK
run: swift build --swift-sdk "$(swiftc -print-target-info | jq -r '.swiftCompilerTag')_wasm"

9 changes: 6 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,17 @@ let package = Package(
.target(
name: "SystemExtras",
dependencies: [
.product(name: "SystemPackage", package: "swift-system")
.product(name: "SystemPackage", package: "swift-system"),
.target(name: "CSystemExtras", condition: .when(platforms: [.wasi])),
],
exclude: ["CMakeLists.txt"],
swiftSettings: [
.define("SYSTEM_PACKAGE_DARWIN", .when(platforms: DarwinPlatforms))
]
),

.target(name: "CSystemExtras"),

.executableTarget(
name: "WITTool",
dependencies: [
Expand All @@ -120,8 +123,8 @@ let package = Package(

if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
package.dependencies += [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.2"),
.package(url: "https://github.com/apple/swift-system", .upToNextMajor(from: "1.3.0")),
.package(url: "https://github.com/apple/swift-argument-parser", branch: "release/1.6.2"),
.package(url: "https://github.com/apple/swift-system", from: "1.5.0"),
]
} else {
package.dependencies += [
Expand Down
8 changes: 6 additions & 2 deletions Sources/CLI/Commands/Run.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,16 @@ struct Run: ParsableCommand {
var directories: [String] = []

enum ThreadingModel: String, ExpressibleByArgument, CaseIterable {
case direct
#if !os(WASI)
case direct
#endif
case token

func resolve() -> EngineConfiguration.ThreadingModel {
switch self {
case .direct: return .direct
#if !os(WASI)
case .direct: return .direct
#endif
case .token: return .token
}
}
Expand Down
Empty file.
5 changes: 5 additions & 0 deletions Sources/CSystemExtras/include/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <time.h>

inline static clockid_t csystemextras_monotonic_clockid() {
return CLOCK_MONOTONIC;
}
26 changes: 21 additions & 5 deletions Sources/SystemExtras/Clock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import Android
#elseif os(Windows)
import CSystem
import ucrt
#elseif os(WASI)
import CSystemExtras
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -41,12 +44,17 @@ extension Clock {
public static var rawMonotonic: Clock { Clock(rawValue: _CLOCK_MONOTONIC_RAW) }
#endif

#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD) || os(WASI)
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD)
@_alwaysEmitIntoClient
public static var monotonic: Clock { Clock(rawValue: _CLOCK_MONOTONIC) }
#endif

#if os(OpenBSD) || os(FreeBSD) || os(WASI)
#if os(WASI)
@_alwaysEmitIntoClient
public static var monotonic: Clock { Clock(rawValue: csystemextras_monotonic_clockid()) }
#endif

#if os(OpenBSD) || os(FreeBSD)
@_alwaysEmitIntoClient
public static var uptime: Clock { Clock(rawValue: _CLOCK_UPTIME) }
#endif
Expand Down Expand Up @@ -92,10 +100,10 @@ extension Clock {
public var rawValue: CInterop.TimeSpec

@_alwaysEmitIntoClient
public var seconds: Int { rawValue.tv_sec }
public var seconds: Int64 { .init(rawValue.tv_sec) }

@_alwaysEmitIntoClient
public var nanoseconds: Int { rawValue.tv_nsec }
public var nanoseconds: Int64 { .init(rawValue.tv_nsec) }

@_alwaysEmitIntoClient
public init(rawValue: CInterop.TimeSpec) {
Expand All @@ -104,17 +112,25 @@ extension Clock {

@_alwaysEmitIntoClient
public init(seconds: Int, nanoseconds: Int) {
self.init(rawValue: CInterop.TimeSpec(tv_sec: seconds, tv_nsec: nanoseconds))
self.init(rawValue: CInterop.TimeSpec(tv_sec: .init(seconds), tv_nsec: nanoseconds))
}

@_alwaysEmitIntoClient
public static var now: TimeSpec {
#if os(WASI)
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(UTIME_NOW)))
#else
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(_UTIME_NOW)))
#endif
}

@_alwaysEmitIntoClient
public static var omit: TimeSpec {
#if os(WASI)
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(UTIME_OMIT)))
#else
return TimeSpec(rawValue: CInterop.TimeSpec(tv_sec: 0, tv_nsec: Int(_UTIME_OMIT)))
#endif
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions Sources/SystemExtras/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Android
#elseif os(Windows)
import CSystem
import ucrt
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -43,7 +45,7 @@ internal var _AT_NO_AUTOMOUNT: CInt { AT_NO_AUTOMOUNT }
#endif
*/

#if !os(Windows)
#if !os(Windows) && !os(WASI)
@_alwaysEmitIntoClient
internal var _F_GETFL: CInt { F_GETFL }
@_alwaysEmitIntoClient
Expand All @@ -61,7 +63,7 @@ internal var _O_SYNC: CInt { O_SYNC }
internal var _O_RSYNC: CInt { O_RSYNC }
#endif

#if !os(Windows)
#if !os(Windows) && !os(WASI)
@_alwaysEmitIntoClient
internal var _UTIME_NOW: CInt {
#if os(Linux) || os(Android)
Expand Down Expand Up @@ -132,16 +134,15 @@ internal var _CLOCK_BOOTTIME: CInterop.ClockId { CLOCK_BOOTTIME }
@_alwaysEmitIntoClient
internal var _CLOCK_MONOTONIC_RAW: CInterop.ClockId { CLOCK_MONOTONIC_RAW }
#endif
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD) || os(WASI)
#if SYSTEM_PACKAGE_DARWIN || os(Linux) || os(Android) || os(OpenBSD) || os(FreeBSD)
@_alwaysEmitIntoClient
internal var _CLOCK_MONOTONIC: CInterop.ClockId { CLOCK_MONOTONIC }
#endif

#if SYSTEM_PACKAGE_DARWIN
@_alwaysEmitIntoClient
internal var _CLOCK_UPTIME_RAW: CInterop.ClockId { CLOCK_UPTIME_RAW }
#endif
#if os(OpenBSD) || os(FreeBSD) || os(WASI)
#if os(OpenBSD) || os(FreeBSD)
@_alwaysEmitIntoClient
internal var _CLOCK_UPTIME: CInterop.ClockId { CLOCK_UPTIME }
#endif
2 changes: 2 additions & 0 deletions Sources/SystemExtras/FileAtOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Android
#elseif os(Windows)
import ucrt
import WinSDK
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down
23 changes: 22 additions & 1 deletion Sources/SystemExtras/FileOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Android
#elseif os(Windows)
import ucrt
import WinSDK
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -344,6 +346,8 @@ extension FileDescriptor {
#if os(Windows)
// FIXME: Need to query by `NtQueryInformationFile`?
return .success(OpenOptions(rawValue: 0))
#elseif os(WASI)
return .failure(Errno.notSupported)
#else
valueOrErrno(retryOnInterrupt: false) {
system_fcntl(self.rawValue, _F_GETFL)
Expand Down Expand Up @@ -511,15 +515,31 @@ extension FileDescriptor {

@_alwaysEmitIntoClient
public var name: String {
#if os(WASI)
// ClangImporter can't handle `char d_name[]`, but it's right after `unsigned char d_type`.
withUnsafePointer(to: &rawValue.pointee.d_type) { dType in
let dName = dType + 1
return dName.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: dName)) {
// String initializer copies the given buffer contents, so it's safe.
return String(cString: $0)
}
}
#else
withUnsafePointer(to: &rawValue.pointee.d_name) { dName in
dName.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: dName)) {
// String initializer copies the given buffer contents, so it's safe.
return String(cString: $0)
}
}
#endif
}

public var fileType: FileType {
#if os(WASI)
// https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-filetype-variant
// https://github.com/WebAssembly/wasi-libc/blob/6b45da5b05bc0edda355a6de46101d4b21631985/libc-bottom-half/headers/public/wasi/api.h#L780C9-L780C32
FileType(rawValue: .init(rawValue.pointee.d_type))
#else
switch CInt(rawValue.pointee.d_type) {
case _DT_REG: return .file
case _DT_BLK: return .blockDevice
Expand All @@ -529,6 +549,7 @@ extension FileDescriptor {
case _DT_SOCK: return .socket
default: return .unknown
}
#endif
}
}

Expand Down Expand Up @@ -657,7 +678,7 @@ public enum FileTime {
public typealias FileTime = Clock.TimeSpec
#endif

#if !os(Windows)
#if !os(Windows) && !os(WASI)

// MARK: - Synchronized Input and Output

Expand Down
4 changes: 3 additions & 1 deletion Sources/SystemExtras/Syscalls.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Android
#elseif os(Windows)
import ucrt
import WinSDK
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -127,7 +129,7 @@ internal func system_symlinkat(
extension CInterop {
#if SYSTEM_PACKAGE_DARWIN
public typealias DirP = UnsafeMutablePointer<DIR>
#elseif os(Linux) || os(Android)
#elseif os(Linux) || os(Android) || os(WASI)
public typealias DirP = OpaquePointer
#else
#error("Unsupported Platform")
Expand Down
4 changes: 1 addition & 3 deletions Sources/WASI/Clock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,10 @@ public protocol MonotonicClock {
/// A monotonic clock that uses the system's monotonic clock.
public struct SystemMonotonicClock: MonotonicClock {
private var underlying: SystemExtras.Clock {
#if os(Linux) || os(Android)
#if os(Linux) || os(Android) || os(WASI)
return .monotonic
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
return .rawUptime
#elseif os(WASI)
return .monotonic
#elseif os(OpenBSD) || os(FreeBSD)
return .uptime
#else
Expand Down
28 changes: 16 additions & 12 deletions Sources/WASI/Platform/PlatformTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,17 @@ extension WASIAbi.Fdflags {
if platformOpenOptions.contains(.append) {
fdFlags.insert(.APPEND)
}
if platformOpenOptions.contains(.dataSync) {
fdFlags.insert(.DSYNC)
}
if platformOpenOptions.contains(.nonBlocking) {
fdFlags.insert(.NONBLOCK)
}
if platformOpenOptions.contains(.fileSync) {
fdFlags.insert(.SYNC)
}
#if !os(WASI)
if platformOpenOptions.contains(.dataSync) {
fdFlags.insert(.DSYNC)
}
if platformOpenOptions.contains(.fileSync) {
fdFlags.insert(.SYNC)
}
#endif
#if os(Linux)
if platformOpenOptions.contains(.readSync) {
fdFlags.insert(.RSYNC)
Expand All @@ -64,15 +66,17 @@ extension WASIAbi.Fdflags {
flags.insert(.append)
}
#if !os(Windows)
if self.contains(.DSYNC) {
flags.insert(.dataSync)
}
if self.contains(.NONBLOCK) {
flags.insert(.nonBlocking)
}
if self.contains(.SYNC) {
flags.insert(.fileSync)
}
#if !os(WASI)
if self.contains(.DSYNC) {
flags.insert(.dataSync)
}
if self.contains(.SYNC) {
flags.insert(.fileSync)
}
#endif
#if os(Linux)
if self.contains(.RSYNC) {
flags.insert(.readSync)
Expand Down
10 changes: 8 additions & 2 deletions Sources/WASI/Platform/SandboxPrimitives/Open.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import SystemPackage
#elseif os(Windows)
import CSystem
import ucrt
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -127,13 +129,17 @@ struct PathResolution {
throw openErrno
}

try self.symlink(component: component)
#if os(WASI)
throw Errno.notSupported
#else
try self.symlink(component: component)
#endif
#endif
}
}
}

#if !os(Windows)
#if !os(Windows) && !os(WASI)
mutating func symlink(component: FilePath.Component) throws {
/// Thin wrapper around readlinkat(2)
func _readlinkat(_ fd: CInt, _ path: UnsafePointer<CChar>) throws -> FilePath {
Expand Down
Loading