Skip to content

Commit 40b6b0e

Browse files
Add support for WASILibc module (#159)
Quoting the [wasi.dev landing page](https://wasi.dev): > The WebAssembly System Interface (WASI) is a group of standard API specifications for software compiled to the W3C WebAssembly (Wasm) standard. WASI is designed to provide a secure standard interface for applications that can be compiled to Wasm from any language, and that may run anywhere—from browsers to clouds to embedded devices. Currently support for WASI in Swift is based on [`wasi-libc`](https://github.com/WebAssembly/wasi-libc). Adding support for `wasi-libc` mostly amounted to excluding unsupported errnos, adding TLS dictionary storage shim for single-threaded environment, and adding constants in C headers for macros that Clang importer currently doesn't support. Co-authored-by: Guillaume Lessard <[email protected]>
1 parent dae787c commit 40b6b0e

File tree

8 files changed

+180
-22
lines changed

8 files changed

+180
-22
lines changed

Sources/CSystem/include/CSystemWASI.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
This source file is part of the Swift System open source project
3+
4+
Copyright (c) 2024 Apple Inc. and the Swift System project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
*/
9+
10+
#pragma once
11+
12+
#if __wasi__
13+
14+
#include <errno.h>
15+
#include <fcntl.h>
16+
17+
// wasi-libc defines the following constants in a way that Clang Importer can't
18+
// understand, so we need to expose them manually.
19+
static inline int32_t _getConst_O_ACCMODE(void) { return O_ACCMODE; }
20+
static inline int32_t _getConst_O_APPEND(void) { return O_APPEND; }
21+
static inline int32_t _getConst_O_CREAT(void) { return O_CREAT; }
22+
static inline int32_t _getConst_O_DIRECTORY(void) { return O_DIRECTORY; }
23+
static inline int32_t _getConst_O_EXCL(void) { return O_EXCL; }
24+
static inline int32_t _getConst_O_NONBLOCK(void) { return O_NONBLOCK; }
25+
static inline int32_t _getConst_O_TRUNC(void) { return O_TRUNC; }
26+
static inline int32_t _getConst_O_WRONLY(void) { return O_WRONLY; }
27+
28+
static inline int32_t _getConst_EWOULDBLOCK(void) { return EWOULDBLOCK; }
29+
static inline int32_t _getConst_EOPNOTSUPP(void) { return EOPNOTSUPP; }
30+
31+
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module CSystem {
22
header "CSystemLinux.h"
3+
header "CSystemWASI.h"
34
header "CSystemWindows.h"
45
export *
56
}

Sources/System/Errno.swift

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2021 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -229,7 +229,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
229229
@available(*, unavailable, renamed: "badAddress")
230230
public static var EFAULT: Errno { badAddress }
231231

232-
#if !os(Windows)
232+
#if !os(Windows) && !os(WASI)
233233
/// Not a block device.
234234
///
235235
/// You attempted a block device operation on a nonblock device or file.
@@ -621,6 +621,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
621621
@available(*, unavailable, renamed: "protocolNotSupported")
622622
public static var EPROTONOSUPPORT: Errno { protocolNotSupported }
623623

624+
#if !os(WASI)
624625
/// Socket type not supported.
625626
///
626627
/// Support for the socket type hasn't been configured into the system
@@ -633,6 +634,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
633634
@_alwaysEmitIntoClient
634635
@available(*, unavailable, renamed: "socketTypeNotSupported")
635636
public static var ESOCKTNOSUPPORT: Errno { socketTypeNotSupported }
637+
#endif
636638

637639
/// Not supported.
638640
///
@@ -647,6 +649,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
647649
@available(*, unavailable, renamed: "notSupported")
648650
public static var ENOTSUP: Errno { notSupported }
649651

652+
#if !os(WASI)
650653
/// Protocol family not supported.
651654
///
652655
/// The protocol family hasn't been configured into the system
@@ -659,6 +662,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
659662
@_alwaysEmitIntoClient
660663
@available(*, unavailable, renamed: "protocolFamilyNotSupported")
661664
public static var EPFNOSUPPORT: Errno { protocolFamilyNotSupported }
665+
#endif
662666

663667
/// The address family isn't supported by the protocol family.
664668
///
@@ -805,6 +809,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
805809
@available(*, unavailable, renamed: "socketNotConnected")
806810
public static var ENOTCONN: Errno { socketNotConnected }
807811

812+
#if !os(WASI)
808813
/// Can't send after socket shutdown.
809814
///
810815
/// A request to send data wasn't permitted
@@ -818,6 +823,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
818823
@_alwaysEmitIntoClient
819824
@available(*, unavailable, renamed: "socketShutdown")
820825
public static var ESHUTDOWN: Errno { socketShutdown }
826+
#endif
821827

822828
/// Operation timed out.
823829
///
@@ -874,6 +880,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
874880
@available(*, unavailable, renamed: "fileNameTooLong")
875881
public static var ENAMETOOLONG: Errno { fileNameTooLong }
876882

883+
#if !os(WASI)
877884
/// The host is down.
878885
///
879886
/// A socket operation failed because the destination host was down.
@@ -885,6 +892,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
885892
@_alwaysEmitIntoClient
886893
@available(*, unavailable, renamed: "hostIsDown")
887894
public static var EHOSTDOWN: Errno { hostIsDown }
895+
#endif
888896

889897
/// No route to host.
890898
///
@@ -923,6 +931,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
923931
public static var EPROCLIM: Errno { tooManyProcesses }
924932
#endif
925933

934+
#if !os(WASI)
926935
/// Too many users.
927936
///
928937
/// The quota system ran out of table entries.
@@ -934,6 +943,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
934943
@_alwaysEmitIntoClient
935944
@available(*, unavailable, renamed: "tooManyUsers")
936945
public static var EUSERS: Errno { tooManyUsers }
946+
#endif
937947

938948
/// Disk quota exceeded.
939949
///
@@ -1287,6 +1297,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
12871297
@available(*, unavailable, renamed: "multiHop")
12881298
public static var EMULTIHOP: Errno { multiHop }
12891299

1300+
#if !os(WASI)
12901301
/// No message available.
12911302
///
12921303
/// No message was available to be received by the requested operation.
@@ -1298,6 +1309,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
12981309
@_alwaysEmitIntoClient
12991310
@available(*, unavailable, renamed: "noData")
13001311
public static var ENODATA: Errno { noData }
1312+
#endif
13011313

13021314
/// Reserved.
13031315
///
@@ -1311,6 +1323,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13111323
@available(*, unavailable, renamed: "noLink")
13121324
public static var ENOLINK: Errno { noLink }
13131325

1326+
#if !os(WASI)
13141327
/// Reserved.
13151328
///
13161329
/// This error is reserved for future use.
@@ -1334,6 +1347,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13341347
@_alwaysEmitIntoClient
13351348
@available(*, unavailable, renamed: "notStream")
13361349
public static var ENOSTR: Errno { notStream }
1350+
#endif
13371351
#endif
13381352

13391353
/// Protocol error.
@@ -1350,7 +1364,7 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13501364
@available(*, unavailable, renamed: "protocolError")
13511365
public static var EPROTO: Errno { protocolError }
13521366

1353-
#if !os(OpenBSD)
1367+
#if !os(OpenBSD) && !os(WASI)
13541368
/// Reserved.
13551369
///
13561370
/// This error is reserved for future use.
@@ -1382,7 +1396,6 @@ public struct Errno: RawRepresentable, Error, Hashable, Codable {
13821396
// Constants defined in header but not man page
13831397
@available(/*System 0.0.1: macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0*/iOS 8, *)
13841398
extension Errno {
1385-
13861399
/// Operation would block.
13871400
///
13881401
/// The corresponding C error is `EWOULDBLOCK`.
@@ -1393,6 +1406,7 @@ extension Errno {
13931406
@available(*, unavailable, renamed: "wouldBlock")
13941407
public static var EWOULDBLOCK: Errno { wouldBlock }
13951408

1409+
#if !os(WASI)
13961410
/// Too many references: can't splice.
13971411
///
13981412
/// The corresponding C error is `ETOOMANYREFS`.
@@ -1412,6 +1426,7 @@ extension Errno {
14121426
@_alwaysEmitIntoClient
14131427
@available(*, unavailable, renamed: "tooManyRemoteLevels")
14141428
public static var EREMOTE: Errno { tooManyRemoteLevels }
1429+
#endif
14151430

14161431
#if SYSTEM_PACKAGE_DARWIN
14171432
/// No such policy registered.

Sources/System/FileOperations.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -369,6 +369,7 @@ extension FileDescriptor {
369369
}
370370
}
371371

372+
#if !os(WASI)
372373
@available(/*System 0.0.2: macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0*/iOS 8, *)
373374
extension FileDescriptor {
374375
/// Duplicates this file descriptor and return the newly created copy.
@@ -433,8 +434,9 @@ extension FileDescriptor {
433434
fatalError("Not implemented")
434435
}
435436
}
437+
#endif
436438

437-
#if !os(Windows)
439+
#if !os(Windows) && !os(WASI)
438440
@available(/*System 1.1.0: macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4*/iOS 8, *)
439441
extension FileDescriptor {
440442
/// Creates a unidirectional data channel, which can be used for interprocess communication.

Sources/System/Internals/CInterop.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 - 2021 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -18,6 +18,8 @@ import Glibc
1818
#elseif canImport(Musl)
1919
@_implementationOnly import CSystem
2020
import Musl
21+
#elseif canImport(WASILibc)
22+
import WASILibc
2123
#else
2224
#error("Unsupported Platform")
2325
#endif

0 commit comments

Comments
 (0)