Skip to content

Commit ca22e2d

Browse files
committed
Start adding WasmKit support
1 parent bddde66 commit ca22e2d

File tree

5 files changed

+70
-1
lines changed

5 files changed

+70
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Package.resolved

tools/swift-plugin-server/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,7 @@ if (SWIFT_BUILD_SWIFT_SYNTAX)
5757
add_custom_command(TARGET swift-wasm-plugin-server POST_BUILD COMMAND
5858
codesign -fs - $<TARGET_FILE:swift-wasm-plugin-server> --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/allow-jit.plist
5959
)
60+
else()
61+
# TODO: Add dependency on WasmKit
6062
endif()
6163
endif()

tools/swift-plugin-server/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ let package = Package(
1414
dependencies: [
1515
.package(path: "../../../swift-syntax"),
1616
.package(path: "../../lib/ASTGen"),
17+
.package(path: "../../../wasmkit"),
1718
],
1819
targets: [
1920
.target(
@@ -54,6 +55,8 @@ let package = Package(
5455
.product(name: "SwiftCompilerPluginMessageHandling", package: "swift-syntax"),
5556
"CSwiftPluginServer",
5657
"SwiftPluginServerSupport",
58+
.product(name: "WasmKit", package: "WasmKit", condition: .when(platforms: [.linux, .windows])),
59+
.product(name: "WASI", package: "WasmKit", condition: .when(platforms: [.linux, .windows])),
5760
],
5861
swiftSettings: [.interoperabilityMode(.Cxx)]
5962
),

tools/swift-plugin-server/Sources/swift-wasm-plugin-server/JSCWasmPlugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async (wasmData) => {
4444
}
4545
"""
4646

47-
final class JSCWasmPlugin: WasmPlugin {
47+
struct JSCWasmPlugin: WasmPlugin {
4848
private static let factory = JSContext()?.evaluateScript(js)
4949

5050
private let handler: JSValue
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#if !os(macOS)
14+
15+
import Foundation
16+
import WasmKit
17+
import WASI
18+
19+
typealias DefaultWasmPlugin = WasmKitPlugin
20+
21+
struct WasmKitMacroRunner: WasmPlugin {
22+
let instance: ModuleInstance
23+
let runtime: Runtime
24+
25+
init(wasm: Data) throws {
26+
let module = try parseWasm(bytes: Array(wasm))
27+
let bridge = try WASIBridgeToHost()
28+
runtime = Runtime(hostModules: bridge.hostModules)
29+
instance = try runtime.instantiate(module: module)
30+
_ = try bridge.start(instance, runtime: runtime)
31+
}
32+
33+
func handleMessage(_ json: Data) throws -> Data {
34+
let exports = instance.exports
35+
guard case let .memory(memoryAddr) = exports["memory"] else { fatalError("bad memory") }
36+
guard case let .function(malloc) = exports["wacro_malloc"] else { fatalError("bad wacro_malloc") }
37+
guard case let .function(parse) = exports["wacro_parse"] else { fatalError("bad wacro_parse") }
38+
guard case let .function(free) = exports["wacro_free"] else { fatalError("bad wacro_free") }
39+
40+
let inAddr = try malloc.invoke([.i32(UInt32(json.count))], runtime: runtime)[0].i32
41+
42+
runtime.store.withMemory(at: memoryAddr) { mem in
43+
mem.data.replaceSubrange(Int(inAddr)..<(Int(inAddr) + json.count), with: json)
44+
}
45+
46+
let outAddr = try parse.invoke([.i32(inAddr), .i32(UInt32(json.count))], runtime: runtime)[0].i32
47+
let out = runtime.store.withMemory(at: memoryAddr) { mem in
48+
let bytes = Array(mem.data[Int(outAddr)..<(Int(outAddr) + 4)])
49+
let len =
50+
(UInt32(bytes[0]) << 0) |
51+
(UInt32(bytes[1]) << 8) |
52+
(UInt32(bytes[2]) << 16) |
53+
(UInt32(bytes[3]) << 24)
54+
return Data(mem.data[(Int(outAddr) + 4)...].prefix(Int(len)))
55+
}
56+
57+
_ = try free.invoke([.i32(outAddr)], runtime: runtime)
58+
59+
return out
60+
}
61+
}
62+
63+
#endif

0 commit comments

Comments
 (0)