From 4acfd490d14810f959e938d32efc6af9432d20b5 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Mon, 16 Aug 2021 15:45:05 +0100 Subject: [PATCH] Disable file/dispatch-related code in Foundation for WASI --- Sources/Foundation/CGFloat.swift | 4 ++-- Sources/Foundation/CharacterSet.swift | 2 ++ Sources/Foundation/Data.swift | 28 +++++++++++++++++++--- Sources/Foundation/JSONSerialization.swift | 2 ++ Sources/Foundation/NSArray.swift | 4 ++++ Sources/Foundation/NSCalendar.swift | 2 ++ Sources/Foundation/NSCharacterSet.swift | 2 ++ Sources/Foundation/NSData.swift | 12 ++++++++++ Sources/Foundation/NSDictionary.swift | 13 ++++++++++ Sources/Foundation/NSIndexSet.swift | 8 +++++++ Sources/Foundation/NSKeyedArchiver.swift | 10 ++++++++ Sources/Foundation/NSKeyedUnarchiver.swift | 6 +++++ Sources/Foundation/NSLocale.swift | 2 ++ Sources/Foundation/NSLock.swift | 15 ++++++++++++ Sources/Foundation/NSNumber.swift | 4 ++-- Sources/Foundation/NSObject.swift | 2 ++ Sources/Foundation/NSPathUtilities.swift | 14 +++++++++++ Sources/Foundation/NSPlatform.swift | 3 +++ Sources/Foundation/NSRange.swift | 2 +- 19 files changed, 127 insertions(+), 8 deletions(-) diff --git a/Sources/Foundation/CGFloat.swift b/Sources/Foundation/CGFloat.swift index 96bf8de4e0..61276c8394 100644 --- a/Sources/Foundation/CGFloat.swift +++ b/Sources/Foundation/CGFloat.swift @@ -9,7 +9,7 @@ @frozen public struct CGFloat { -#if arch(i386) || arch(arm) +#if arch(i386) || arch(arm) || arch(wasm32) /// The native type used to store the CGFloat, which is Float on /// 32-bit architectures and Double on 64-bit architectures. public typealias NativeType = Float @@ -185,7 +185,7 @@ extension CGFloat : BinaryFloatingPoint { @_transparent public init(bitPattern: UInt) { -#if arch(i386) || arch(arm) +#if arch(i386) || arch(arm) || arch(wasm32) native = NativeType(bitPattern: UInt32(bitPattern)) #elseif arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) native = NativeType(bitPattern: UInt64(bitPattern)) diff --git a/Sources/Foundation/CharacterSet.swift b/Sources/Foundation/CharacterSet.swift index 9a7b87ff53..d5a4540006 100644 --- a/Sources/Foundation/CharacterSet.swift +++ b/Sources/Foundation/CharacterSet.swift @@ -157,6 +157,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb _wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(bitmapRepresentation: data)) } +#if !os(WASI) /// Initialize with the contents of a file. /// /// Returns `nil` if there was an error reading the file. @@ -168,6 +169,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb return nil } } +#endif public func hash(into hasher: inout Hasher) { hasher.combine(_mapUnmanaged { $0 }) diff --git a/Sources/Foundation/Data.swift b/Sources/Foundation/Data.swift index 1d21b6067e..a808240b33 100644 --- a/Sources/Foundation/Data.swift +++ b/Sources/Foundation/Data.swift @@ -12,6 +12,22 @@ #if DEPLOYMENT_RUNTIME_SWIFT +#if canImport(Glibc) +@usableFromInline let calloc = Glibc.calloc +@usableFromInline let malloc = Glibc.malloc +@usableFromInline let free = Glibc.free +@usableFromInline let memset = Glibc.memset +@usableFromInline let memcpy = Glibc.memcpy +@usableFromInline let memcmp = Glibc.memcmp +#elseif canImport(WASILibc) +@usableFromInline let calloc = WASILibc.calloc +@usableFromInline let malloc = WASILibc.malloc +@usableFromInline let free = WASILibc.free +@usableFromInline let memset = WASILibc.memset +@usableFromInline let memcpy = WASILibc.memcpy +@usableFromInline let memcmp = WASILibc.memcmp +#endif + #if !canImport(Darwin) @inlinable // This is @inlinable as trivially computable. internal func malloc_good_size(_ size: Int) -> Int { @@ -23,6 +39,8 @@ internal func malloc_good_size(_ size: Int) -> Int { #if canImport(Glibc) import Glibc +#elseif canImport(WASILibc) +import WASILibc #endif internal func __NSDataInvokeDeallocatorUnmap(_ mem: UnsafeMutableRawPointer, _ length: Int) { @@ -654,7 +672,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl @usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len //enum @usableFromInline var bytes: Buffer -#elseif arch(i386) || arch(arm) +#elseif arch(i386) || arch(arm) || arch(wasm32) @usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len //enum @usableFromInline var bytes: Buffer @@ -683,7 +701,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl assert(count <= MemoryLayout.size) #if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0)) -#elseif arch(i386) || arch(arm) +#elseif arch(i386) || arch(arm) || arch(wasm32) bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0)) #else #error("This architecture isn't known. Add it to the 32-bit or 64-bit line.") @@ -866,7 +884,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl #if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) @usableFromInline internal typealias HalfInt = Int32 -#elseif arch(i386) || arch(arm) +#elseif arch(i386) || arch(arm) || arch(wasm32) @usableFromInline internal typealias HalfInt = Int16 #else #error("This architecture isn't known. Add it to the 32-bit or 64-bit line.") @@ -2012,6 +2030,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl } } +#if !os(WASI) /// Initialize a `Data` with the contents of a `URL`. /// /// - parameter url: The `URL` to read. @@ -2024,6 +2043,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl return Data(bytes: d.bytes, count: d.length) } } +#endif /// Initialize a `Data` from a Base-64 encoded String using the given options. /// @@ -2287,6 +2307,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl } #endif +#if !os(WASI) /// Write the contents of the `Data` to a location. /// /// - parameter url: The location to write the data into. @@ -2307,6 +2328,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl #endif } } +#endif // MARK: - diff --git a/Sources/Foundation/JSONSerialization.swift b/Sources/Foundation/JSONSerialization.swift index 262175d8f3..581c2dc4fd 100644 --- a/Sources/Foundation/JSONSerialization.swift +++ b/Sources/Foundation/JSONSerialization.swift @@ -267,6 +267,7 @@ open class JSONSerialization : NSObject { } +#if !os(WASI) /* Write JSON data into a stream. The stream should be opened and configured. The return value is the number of bytes written to the stream, or 0 on error. All other behavior of this method is the same as the dataWithJSONObject:options:error: method. */ open class func writeJSONObject(_ obj: Any, toStream stream: OutputStream, options opt: WritingOptions) throws -> Int { @@ -298,6 +299,7 @@ open class JSONSerialization : NSObject { } while stream.hasBytesAvailable return try jsonObject(with: data, options: opt) } +#endif } //MARK: - Encoding Detection diff --git a/Sources/Foundation/NSArray.swift b/Sources/Foundation/NSArray.swift index a02bf1b5c9..096c090b51 100644 --- a/Sources/Foundation/NSArray.swift +++ b/Sources/Foundation/NSArray.swift @@ -440,6 +440,7 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo return objects } +#if !os(WASI) open func write(to url: URL) throws { let pListData = try PropertyListSerialization.data(fromPropertyList: self, format: .xml, options: 0) try pListData.write(to: url, options: .atomic) @@ -463,6 +464,7 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo return false } } +#endif open func objects(at indexes: IndexSet) -> [Any] { var objs = [Any]() @@ -653,6 +655,7 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo return lastEqual ? result + 1 : result } +#if !os(WASI) public convenience init(contentsOf url: URL, error: ()) throws { let plistDoc = try Data(contentsOf: url) guard let plistArray = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Array @@ -679,6 +682,7 @@ open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCo return nil } } +#endif open func pathsMatchingExtensions(_ filterTypes: [String]) -> [String] { guard !filterTypes.isEmpty else { diff --git a/Sources/Foundation/NSCalendar.swift b/Sources/Foundation/NSCalendar.swift index 4f6d7c3a3f..2a885ed2a8 100644 --- a/Sources/Foundation/NSCalendar.swift +++ b/Sources/Foundation/NSCalendar.swift @@ -1378,6 +1378,7 @@ internal class _NSCopyOnWriteCalendar: NSCalendar { } } +#if !os(WASI) // This notification is posted through [NSNotificationCenter defaultCenter] // when the system day changes. Register with "nil" as the object of this // notification. If the computer/device is asleep when the day changed, @@ -1391,6 +1392,7 @@ internal class _NSCopyOnWriteCalendar: NSCalendar { extension NSNotification.Name { public static let NSCalendarDayChanged = NSNotification.Name(rawValue: "NSCalendarDayChangedNotification") } +#endif extension NSCalendar: _SwiftBridgeable { diff --git a/Sources/Foundation/NSCharacterSet.swift b/Sources/Foundation/NSCharacterSet.swift index 1cddaf139a..757eef31fe 100644 --- a/Sources/Foundation/NSCharacterSet.swift +++ b/Sources/Foundation/NSCharacterSet.swift @@ -184,6 +184,7 @@ open class NSCharacterSet : NSObject, NSCopying, NSMutableCopying, NSSecureCodin _CFCharacterSetInitWithBitmapRepresentation(_cfMutableObject, data._cfObject) } +#if !os(WASI) public convenience init?(contentsOfFile fName: String) { do { let data = try Data(contentsOf: URL(fileURLWithPath: fName)) @@ -329,6 +330,7 @@ open class NSCharacterSet : NSObject, NSCopying, NSMutableCopying, NSSecureCodin aCoder.encode(true, forKey: .characterSetIsInvertedKey) } } +#endif open func characterIsMember(_ aCharacter: unichar) -> Bool { return longCharacterIsMember(UInt32(aCharacter)) diff --git a/Sources/Foundation/NSData.swift b/Sources/Foundation/NSData.swift index 0ccab73cd2..5c468f1f4c 100644 --- a/Sources/Foundation/NSData.swift +++ b/Sources/Foundation/NSData.swift @@ -8,7 +8,9 @@ // @_implementationOnly import CoreFoundation +#if !os(WASI) import Dispatch +#endif extension NSData { public struct ReadingOptions : OptionSet { @@ -149,6 +151,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { _init(bytes: bytes, length: length, copy: false, deallocator: deallocator) } +#if !os(WASI) /// Initializes a data object with the contents of the file at a given path. public init(contentsOfFile path: String, options readOptionsMask: ReadingOptions = []) throws { super.init() @@ -171,6 +174,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { return nil } } +#endif /// Initializes a data object with the contents of another data object. public init(data: Data) { @@ -180,6 +184,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { } } +#if !os(WASI) /// Initializes a data object with the data from the location specified by a given URL. public init(contentsOf url: URL, options readOptionsMask: ReadingOptions = []) throws { super.init() @@ -212,6 +217,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { return try _NSNonfileURLContentLoader.current.contentsOf(url: url) } } +#endif /// Initializes a data object with the given Base64 encoded string. public init?(base64Encoded base64String: String, options: Base64DecodingOptions = []) { @@ -291,6 +297,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { return isEqual(to: data._swiftObject) } +#if !os(WASI) if let data = value as? DispatchData { if data.count != length { return false @@ -300,6 +307,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { return memcmp(bytes1, bytes2, length) == 0 } } +#endif return false } @@ -425,6 +433,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { } } +#if !os(WASI) internal static func readBytesFromFileWithExtendedAttributes(_ path: String, options: ReadingOptions) throws -> NSDataReadResult { guard let handle = FileHandle(path: path, flags: O_RDONLY, createMode: 0) else { throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil) @@ -528,6 +537,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { } try write(toFile: url.path, options: writeOptionsMask) } +#endif // MARK: - Bytes /// Copies a number of bytes from the start of the data object into a given buffer. @@ -994,6 +1004,7 @@ open class NSMutableData : NSData { super.init(data: data) } +#if !os(WASI) public override init?(contentsOfFile path: String) { super.init(contentsOfFile: path) } @@ -1009,6 +1020,7 @@ open class NSMutableData : NSData { public override init(contentsOf url: URL, options: NSData.ReadingOptions = []) throws { try super.init(contentsOf: url, options: options) } +#endif public override init?(base64Encoded base64Data: Data, options: NSData.Base64DecodingOptions = []) { super.init(base64Encoded: base64Data, options: options) diff --git a/Sources/Foundation/NSDictionary.swift b/Sources/Foundation/NSDictionary.swift index de9544e206..5668103ff5 100644 --- a/Sources/Foundation/NSDictionary.swift +++ b/Sources/Foundation/NSDictionary.swift @@ -9,7 +9,10 @@ @_implementationOnly import CoreFoundation + +#if !os(WASI) import Dispatch +#endif open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSCoding, ExpressibleByDictionaryLiteral { private let _cfinfo = _CFInfo(typeID: CFDictionaryGetTypeID()) @@ -48,6 +51,7 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, return NSGeneratorEnumerator(_storage.keys.map { __SwiftValue.fetch(nonOptional: $0) }.makeIterator()) } +#if !os(WASI) @available(*, deprecated) public convenience init?(contentsOfFile path: String) { self.init(contentsOf: URL(fileURLWithPath: path)) @@ -64,6 +68,7 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, return nil } } +#endif public override convenience init() { self.init(objects: [], forKeys: [], count: 0) @@ -494,6 +499,7 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, return objects } +#if !os(WASI) open func write(toFile path: String, atomically useAuxiliaryFile: Bool) -> Bool { return write(to: URL(fileURLWithPath: path), atomically: useAuxiliaryFile) } @@ -508,6 +514,7 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, return false } } +#endif open func enumerateKeysAndObjects(_ block: (Any, Any, UnsafeMutablePointer) -> Swift.Void) { enumerateKeysAndObjects(options: [], using: block) @@ -538,6 +545,7 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, } } +#if !os(WASI) if opts.contains(.concurrent) { DispatchQueue.concurrentPerform(iterations: count, execute: iteration) } else { @@ -545,6 +553,11 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, iteration(idx) } } +#else + for idx in 0.. Bool { +#if os(WASI) + assertionFailure("\(#function) does not support file access on WASI") + return false +#else var fd : Int32 = -1 var auxFilePath : String var finishedEncoding : Bool = false @@ -183,6 +187,7 @@ open class NSKeyedArchiver : NSCoder { finishedEncoding = keyedArchiver._flags.contains(.finishedEncoding) return finishedEncoding +#endif } public convenience init(requiringSecureCoding: Bool) { @@ -223,8 +228,13 @@ open class NSKeyedArchiver : NSCoder { success = true } } else { +#if !os(WASI) let stream = unsafeBitCast(self._stream, to: CFWriteStream.self) success = CFPropertyListWrite(plist, stream, kCFPropertyListXMLFormat_v1_0, 0, nil) > 0 +#else + assertionFailure("\(#function) only supports data streams on WASI") + return false +#endif } return success diff --git a/Sources/Foundation/NSKeyedUnarchiver.swift b/Sources/Foundation/NSKeyedUnarchiver.swift index efacffb421..a72b3213cd 100644 --- a/Sources/Foundation/NSKeyedUnarchiver.swift +++ b/Sources/Foundation/NSKeyedUnarchiver.swift @@ -51,7 +51,9 @@ open class NSKeyedUnarchiver : NSCoder { private enum Stream { case data(Data) +#if !os(WASI) case stream(CFReadStream) +#endif } private var _stream : Stream @@ -91,6 +93,7 @@ open class NSKeyedUnarchiver : NSCoder { return try? unarchiveTopLevelObjectWithData(data) } +#if !os(WASI) @available(swift, deprecated: 9999, renamed: "unarchivedObject(ofClass:from:)") open class func unarchiveObject(withFile path: String) -> Any? { let url = URL(fileURLWithPath: path) @@ -109,6 +112,7 @@ open class NSKeyedUnarchiver : NSCoder { return root } +#endif public init(forReadingFrom data: Data) throws { self._stream = .data(data) @@ -143,8 +147,10 @@ open class NSKeyedUnarchiver : NSCoder { switch self._stream { case .data(let data): try plist = PropertyListSerialization.propertyList(from: data, options: [], format: &format) +#if !os(WASI) case .stream(let readStream): try plist = PropertyListSerialization.propertyList(with: readStream, options: [], format: &format) +#endif } guard let unwrappedPlist = plist as? Dictionary else { diff --git a/Sources/Foundation/NSLocale.swift b/Sources/Foundation/NSLocale.swift index 08eb2abc3a..6670fb24c9 100644 --- a/Sources/Foundation/NSLocale.swift +++ b/Sources/Foundation/NSLocale.swift @@ -199,9 +199,11 @@ extension NSLocale { } +#if !os(WASI) extension NSLocale { public static let currentLocaleDidChangeNotification = NSNotification.Name(rawValue: "kCFLocaleCurrentLocaleDidChangeNotification") } +#endif extension CFLocale : _NSBridgeable, _SwiftBridgeable { diff --git a/Sources/Foundation/NSLock.swift b/Sources/Foundation/NSLock.swift index 6cc1813c39..55694cebe9 100644 --- a/Sources/Foundation/NSLock.swift +++ b/Sources/Foundation/NSLock.swift @@ -22,6 +22,11 @@ public protocol NSLocking { func unlock() } +#if canImport(Glibc) +typealias pthread_mutex_t = Glibc.pthread_mutex_t +typealias pthread_cond_t = Glibc.pthread_cond_t +#endif + #if os(Windows) private typealias _MutexPointer = UnsafeMutablePointer private typealias _RecursiveMutexPointer = UnsafeMutablePointer @@ -120,7 +125,11 @@ open class NSLock: NSObject, NSLocking { guard var endTime = timeSpecFrom(date: limit) else { return false } +#if os(WASI) + return true +#else return pthread_mutex_timedlock(mutex, &endTime) == 0 +#endif #endif } @@ -135,6 +144,7 @@ extension NSLock { } } +#if !os(WASI) open class NSConditionLock : NSObject, NSLocking { internal var _cond = NSCondition() internal var _value: Int @@ -227,6 +237,7 @@ open class NSConditionLock : NSObject, NSLocking { open var name: String? } +#endif open class NSRecursiveLock: NSObject, NSLocking { internal var mutex = _RecursiveMutexPointer.allocate(capacity: 1) @@ -327,7 +338,11 @@ open class NSRecursiveLock: NSObject, NSLocking { guard var endTime = timeSpecFrom(date: limit) else { return false } +#if os(WASI) + return true +#else return pthread_mutex_timedlock(mutex, &endTime) == 0 +#endif #endif } diff --git a/Sources/Foundation/NSNumber.swift b/Sources/Foundation/NSNumber.swift index fb4b7324e6..38e89043ec 100644 --- a/Sources/Foundation/NSNumber.swift +++ b/Sources/Foundation/NSNumber.swift @@ -738,7 +738,7 @@ open class NSNumber : NSValue { var value = value #if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) self.init(bytes: &value, numberType: kCFNumberSInt64Type) - #elseif arch(i386) || arch(arm) + #elseif arch(i386) || arch(arm) || arch(wasm32) self.init(bytes: &value, numberType: kCFNumberSInt32Type) #else #error("This architecture isn't known. Add it to the 32-bit or 64-bit line.") @@ -754,7 +754,7 @@ open class NSNumber : NSValue { var value = Int64(value) self.init(bytes: &value, numberType: kCFNumberSInt64Type) } - #elseif arch(i386) || arch(arm) + #elseif arch(i386) || arch(arm) || arch(wasm32) var value = Int64(value) self.init(bytes: &value, numberType: kCFNumberSInt64Type) #else diff --git a/Sources/Foundation/NSObject.swift b/Sources/Foundation/NSObject.swift index c80cf658a4..a2bbd0b77d 100644 --- a/Sources/Foundation/NSObject.swift +++ b/Sources/Foundation/NSObject.swift @@ -10,7 +10,9 @@ // @_exported import of Dispatch here makes it available to all // classes in Foundation and all sources that import Foundation. // This brings it into line with Darwin usage for compatibility. +#if !os(WASI) @_exported import Dispatch +#endif @_implementationOnly import CoreFoundation diff --git a/Sources/Foundation/NSPathUtilities.swift b/Sources/Foundation/NSPathUtilities.swift index a5dc023fb9..b4c6a2889e 100644 --- a/Sources/Foundation/NSPathUtilities.swift +++ b/Sources/Foundation/NSPathUtilities.swift @@ -63,9 +63,11 @@ public func NSTemporaryDirectory() -> String { } } #endif +#if !os(WASI) if let tmpdir = ProcessInfo.processInfo.environment["TMPDIR"] { return normalizedPath(with: tmpdir) } +#endif #if os(Android) // Bionic uses /data/local/tmp/ as temporary directory. TMPDIR is rarely // defined. @@ -190,6 +192,7 @@ extension String { return temp } +#if !os(WASI) internal func _tryToRemovePathPrefix(_ prefix: String) -> String? { guard self != prefix else { return nil @@ -202,6 +205,7 @@ extension String { return nil } +#endif } extension NSString { @@ -331,6 +335,7 @@ extension NSString { return result._stringByFixingSlashes() } +#if !os(WASI) public var expandingTildeInPath: String { guard hasPrefix("~") else { return _swiftObject @@ -351,6 +356,7 @@ extension NSString { return result } +#endif #if os(Windows) public var unixPath: String { @@ -365,6 +371,7 @@ extension NSString { } #endif +#if !os(WASI) public var standardizingPath: String { #if os(Windows) let expanded = unixPath.expandingTildeInPath @@ -412,6 +419,7 @@ extension NSString { return resolvedPath } +#endif public func stringsByAppendingPaths(_ paths: [String]) -> [String] { if self == "" { @@ -420,6 +428,7 @@ extension NSString { return paths.map(appendingPathComponent) } +#if !os(WASI) /// - Experiment: This is a draft API currently under consideration for official import into Foundation /// - Note: Since this API is under consideration it may be either removed or revised in the near future public func completePath(into outputName: inout String?, caseSensitive flag: Bool, matchesInto outputArray: inout [String], filterTypes: [String]?) -> Int { @@ -522,6 +531,7 @@ extension NSString { return { $0.lowercased().hasPrefix(prefix) } } } +#endif internal func _longestCommonPrefix(_ strings: [String], caseSensitive: Bool) -> String? { guard !strings.isEmpty else { @@ -569,9 +579,11 @@ extension NSString { return path + "/" } +#if !os(WASI) public var fileSystemRepresentation: UnsafePointer { return FileManager.default.fileSystemRepresentation(withPath: self._swiftObject) } +#endif public func getFileSystemRepresentation(_ cname: UnsafeMutablePointer, maxLength max: Int) -> Bool { #if os(Windows) @@ -640,6 +652,7 @@ extension NSString { } +#if !os(WASI) extension FileManager { public enum SearchPathDirectory: UInt { @@ -814,3 +827,4 @@ internal func _NSCleanupTemporaryFile(_ auxFilePath: String, _ filePath: String) #endif }) } +#endif diff --git a/Sources/Foundation/NSPlatform.swift b/Sources/Foundation/NSPlatform.swift index 8a66a4af3f..a18090265d 100644 --- a/Sources/Foundation/NSPlatform.swift +++ b/Sources/Foundation/NSPlatform.swift @@ -18,6 +18,9 @@ fileprivate var _NSPageSize: Int { GetSystemInfo(&siInfo) return Int(siInfo.dwPageSize) } +#elseif os(WASI) +// WebAssembly defines a fixed page size +fileprivate let _NSPageSize: Int = 65_536 #endif public func NSPageSize() -> Int { diff --git a/Sources/Foundation/NSRange.swift b/Sources/Foundation/NSRange.swift index 6453307f23..ee6eec8460 100644 --- a/Sources/Foundation/NSRange.swift +++ b/Sources/Foundation/NSRange.swift @@ -379,7 +379,7 @@ extension NSRange: NSSpecialValueCoding { } static func objCType() -> String { -#if arch(i386) || arch(arm) +#if arch(i386) || arch(arm) || arch(wasm32) return "{_NSRange=II}" #elseif arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) return "{_NSRange=QQ}"