Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ 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-system", from: "1.6.0"),
]
} else {
package.dependencies += [
Expand Down
20 changes: 15 additions & 5 deletions Sources/SystemExtras/Clock.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 @@ -41,12 +43,12 @@ 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(OpenBSD) || os(FreeBSD)
@_alwaysEmitIntoClient
public static var uptime: Clock { Clock(rawValue: _CLOCK_UPTIME) }
#endif
Expand Down Expand Up @@ -92,10 +94,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 +106,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
16 changes: 10 additions & 6 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 !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 !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
2 changes: 2 additions & 0 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
4 changes: 3 additions & 1 deletion Sources/WASI/WASI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import WasmTypes
import Android
#elseif os(Windows)
import ucrt
#elseif os(WASI)
import WASILibc
#else
#error("Unsupported Platform")
#endif
Expand Down Expand Up @@ -1391,7 +1393,7 @@ public class WASIBridgeToHost: WASI {
fdTable[2] = .file(StdioFileEntry(fd: stderr, accessMode: .write))

for (guestPath, hostPath) in preopens {
#if os(Windows)
#if os(Windows) || os(WASI)
let fd = try FileDescriptor.open(FilePath(hostPath), .readWrite)
#else
let fd = try hostPath.withCString { cHostPath in
Expand Down
74 changes: 36 additions & 38 deletions Sources/WIT/PackageResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,52 +195,50 @@ extension SourceFileSyntax {
}
}

#if !os(WASI)
/// A ``PackageFileLoader`` adapter for local file system.
public struct LocalFileLoader: PackageFileLoader {
public typealias FilePath = String
/// A ``PackageFileLoader`` adapter for local file system.
public struct LocalFileLoader: PackageFileLoader {
public typealias FilePath = String

let fileManager: FileManager
let fileManager: FileManager

public init(fileManager: FileManager = .default) {
self.fileManager = fileManager
}
public init(fileManager: FileManager = .default) {
self.fileManager = fileManager
}

enum Error: Swift.Error {
case failedToLoadFile(FilePath)
}
enum Error: Swift.Error {
case failedToLoadFile(FilePath)
}

private func isDirectory(filePath: String) -> Bool {
var isDirectory: ObjCBool = false
let exists = fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory)
return exists && isDirectory.boolValue
}
private func isDirectory(filePath: String) -> Bool {
var isDirectory: ObjCBool = false
let exists = fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory)
return exists && isDirectory.boolValue
}

public func contentsOfWITFile(at filePath: String) throws -> String {
guard let bytes = fileManager.contents(atPath: filePath) else {
throw Error.failedToLoadFile(filePath)
}
return String(decoding: bytes, as: UTF8.self)
public func contentsOfWITFile(at filePath: String) throws -> String {
guard let bytes = fileManager.contents(atPath: filePath) else {
throw Error.failedToLoadFile(filePath)
}
return String(decoding: bytes, as: UTF8.self)
}

public func packageFiles(in packageDirectory: String) throws -> [String] {
let dirURL = URL(fileURLWithPath: packageDirectory)
return try fileManager.contentsOfDirectory(atPath: packageDirectory).filter { fileName in
return fileName.hasSuffix(".wit")
&& {
let filePath = dirURL.appendingPathComponent(fileName)
return !isDirectory(filePath: filePath.path)
}()
}
.map { dirURL.appendingPathComponent($0).path }
public func packageFiles(in packageDirectory: String) throws -> [String] {
let dirURL = URL(fileURLWithPath: packageDirectory)
return try fileManager.contentsOfDirectory(atPath: packageDirectory).filter { fileName in
return fileName.hasSuffix(".wit")
&& {
let filePath = dirURL.appendingPathComponent(fileName)
return !isDirectory(filePath: filePath.path)
}()
}
.map { dirURL.appendingPathComponent($0).path }
}

public func dependencyDirectories(from packageDirectory: String) throws -> [String] {
let dirURL = URL(fileURLWithPath: packageDirectory)
let depsDir = dirURL.appendingPathComponent("deps")
guard isDirectory(filePath: depsDir.path) else { return [] }
return try fileManager.contentsOfDirectory(atPath: depsDir.path)
}
public func dependencyDirectories(from packageDirectory: String) throws -> [String] {
let dirURL = URL(fileURLWithPath: packageDirectory)
let depsDir = dirURL.appendingPathComponent("deps")
guard isDirectory(filePath: depsDir.path) else { return [] }
return try fileManager.contentsOfDirectory(atPath: depsDir.path)
}
}

#endif
2 changes: 1 addition & 1 deletion Sources/WITExtractor/SwiftAPIDigester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ struct SwiftAPIDigester {

@available(macOS 11, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
func dumpSDK(moduleName: String, arguments: [String]) throws -> Output {
#if os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
#if os(iOS) || os(watchOS) || os(tvOS) || os(visionOS) || os(WASI)
fatalError("WITExtractor does not support platforms where Foundation.Process is unavailable")
#else
var args = [
Expand Down
Loading