Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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 .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ jobs:
curl -L https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-linux-x86_64.tar.gz | tar xz --strip-component 1 -C /usr/local/
- run: cmake -G Ninja -B ./build
- run: cmake --build ./build
- run: ./build/bin/wasmkit-cli --version
- run: ./build/bin/wasmkit --version

build-wasi:
runs-on: ubuntu-24.04
Expand Down
24 changes: 12 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,6 @@ add_compile_definitions(

include(FetchContent)

find_package(SwiftSystem CONFIG)
if(NOT SwiftSystem_FOUND)
message("-- Vending SwiftSystem")
FetchContent_Declare(SwiftSystem
GIT_REPOSITORY https://github.com/apple/swift-system
GIT_TAG 1.5.0
)
FetchContent_MakeAvailable(SwiftSystem)
endif()

option(WASMKIT_BUILD_CLI "Build wasmkit-cli" ON)

if(WASMKIT_BUILD_CLI)
set(BUILD_TESTING OFF) # disable ArgumentParser tests
find_package(ArgumentParser CONFIG)
Expand All @@ -77,6 +65,18 @@ if(WASMKIT_BUILD_CLI)
endif()
endif()

find_package(SwiftSystem CONFIG)
if(NOT SwiftSystem_FOUND)
message("-- Vending SwiftSystem")
FetchContent_Declare(SwiftSystem
GIT_REPOSITORY https://github.com/apple/swift-system
GIT_TAG 1.5.0
)
FetchContent_MakeAvailable(SwiftSystem)
endif()

option(WASMKIT_BUILD_CLI "Build wasmkit-cli" ON)

add_subdirectory(Sources)
add_subdirectory(Tests)
add_subdirectory(cmake/modules)
8 changes: 8 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ let package = Package(
targets: [
.executableTarget(
name: "CLI",
dependencies: [
"CLICommands"
],
exclude: ["CMakeLists.txt"]
),

.target(
name: "CLICommands",
dependencies: [
"WAT",
"WasmKit",
Expand Down
13 changes: 9 additions & 4 deletions Package@swift-6.1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import class Foundation.ProcessInfo

let DarwinPlatforms: [Platform] = [.macOS, .iOS, .watchOS, .tvOS, .visionOS]

let cliTarget = Target.executableTarget(
name: "CLI",
let cliCommandsTarget = Target.target(
name: "CLICommands",
dependencies: [
"WAT",
"WasmKit",
Expand Down Expand Up @@ -36,7 +36,12 @@ let package = Package(
"WasmDebuggingSupport",
],
targets: [
cliTarget,
cliCommandsTarget,
.executableTarget(
name: "CLI",
dependencies: ["CLICommands"],
exclude: ["CMakeLists.txt"]
),
.target(
name: "WasmKit",
dependencies: [
Expand Down Expand Up @@ -193,7 +198,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
),
])

cliTarget.dependencies.append(contentsOf: [
cliCommandsTarget.dependencies.append(contentsOf: [
.product(name: "Logging", package: "swift-log", condition: .when(traits: ["WasmDebuggingSupport"])),
.product(name: "NIOCore", package: "swift-nio", condition: .when(traits: ["WasmDebuggingSupport"])),
.product(name: "NIOPosix", package: "swift-nio", condition: .when(traits: ["WasmDebuggingSupport"])),
Expand Down
1 change: 1 addition & 0 deletions Sources/CLI/CLI.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ArgumentParser
import CLICommands

@main
struct CLI: AsyncParsableCommand {
Expand Down
15 changes: 8 additions & 7 deletions Sources/CLI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
add_executable(wasmkit-cli
Commands/Explore.swift
Commands/Run.swift
Commands/Wat2wasm.swift
add_executable(wasmkit
CLI.swift
)

target_link_wasmkit_libraries(wasmkit-cli PUBLIC
ArgumentParser WAT WasmKitWASI)
target_compile_options(wasmkit PRIVATE
-package-name WasmKitPackage
)

target_link_wasmkit_libraries(wasmkit PUBLIC
CLICommands)

install(TARGETS wasmkit-cli
install(TARGETS wasmkit
RUNTIME DESTINATION bin)
20 changes: 0 additions & 20 deletions Sources/CLI/Commands/Parse.swift

This file was deleted.

8 changes: 8 additions & 0 deletions Sources/CLICommands/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_wasmkit_library(CLICommands
Explore.swift
Run.swift
Wat2wasm.swift
)

target_link_wasmkit_libraries(CLICommands PUBLIC
ArgumentParser WAT WasmKitWASI)
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import ArgumentParser
import SystemPackage
@_spi(OnlyForCLI) import WasmKit

struct Explore: ParsableCommand {
package struct Explore: ParsableCommand {

static let configuration = CommandConfiguration(
package static let configuration = CommandConfiguration(
abstract: "Explore the compiled functions of a WebAssembly module",
discussion: """
This command will parse a WebAssembly module and dump the compiled functions.
Expand All @@ -22,7 +22,9 @@ struct Explore: ParsableCommand {
}
}

func run() throws {
package init() {}

package func run() throws {
let module = try parseWasm(filePath: FilePath(path))
// Instruction dumping requires token threading model for now
let configuration = EngineConfiguration(threadingModel: .token)
Expand Down
68 changes: 48 additions & 20 deletions Sources/CLI/Commands/Run.swift → Sources/CLICommands/Run.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import ArgumentParser
import SystemPackage
import WAT
import WasmKit
import WasmKitWASI

#if canImport(os.signpost)
import os.signpost
#endif

struct Run: AsyncParsableCommand {
static let configuration = CommandConfiguration(
package struct Run: AsyncParsableCommand {
package static let configuration = CommandConfiguration(
abstract: "Run a WebAssembly module",
discussion: """
This command will parse a WebAssembly module and run it.
Expand Down Expand Up @@ -128,7 +129,9 @@ struct Run: AsyncParsableCommand {
)
var arguments: [String] = []

func run() async throws {
package init() {}

package func run() async throws {
#if WasmDebuggingSupport

if let debuggerPort {
Expand Down Expand Up @@ -257,23 +260,7 @@ struct Run: AsyncParsableCommand {
}

func instantiateNonWASI(module: Module, interceptor: EngineInterceptor?) throws -> (() throws -> Void)? {
let functionName = arguments.first
let arguments = arguments.dropFirst()

var parameters: [Value] = []
for argument in arguments {
let parameter: Value
let type = argument.prefix { $0 != ":" }
let value = argument.drop { $0 != ":" }.dropFirst()
switch type {
case "i32": parameter = Value(signed: Int32(value)!)
case "i64": parameter = Value(signed: Int64(value)!)
case "f32": parameter = .f32(Float32(value)!.bitPattern)
case "f64": parameter = .f64(Float64(value)!.bitPattern)
default: fatalError("unknown type")
}
parameters.append(parameter)
}
let (functionName, parameters) = Run.parseInvocation(arguments: self.arguments)
guard let functionName else {
log("Error: No function specified to run in a given module.")
return nil
Expand Down Expand Up @@ -311,3 +298,44 @@ struct Run: AsyncParsableCommand {
}
}
}

/// Parses a `.wasm` or `.wat` module.
func parseWasm(filePath: FilePath) throws -> Module {
if filePath.extension == "wat", #available(macOS 11.0, iOS 14.0, macCatalyst 14.0, tvOS 14.0, visionOS 1.0, watchOS 7.0, *) {
let fileHandle = try FileDescriptor.open(filePath, .readOnly)
defer { try? fileHandle.close() }

let size = try fileHandle.seek(offset: 0, from: .end)

let wat = try String(unsafeUninitializedCapacity: Int(size)) {
try fileHandle.read(fromAbsoluteOffset: 0, into: .init($0))
}
return try WasmKit.parseWasm(bytes: wat2wasm(wat))
} else {
return try WasmKit.parseWasm(filePath: filePath)
}
}

extension Run {
package static func parseInvocation(arguments: [String]) -> (functionName: String?, parameters: [Value]) {
Comment thread
MaxDesiatov marked this conversation as resolved.
let functionName = arguments.first
let arguments = arguments.dropFirst()

var parameters: [Value] = []
for argument in arguments {
let parameter: Value
let type = argument.prefix { $0 != ":" }
let value = argument.drop { $0 != ":" }.dropFirst()
switch type {
case "i32": parameter = Value(signed: Int32(value)!)
case "i64": parameter = Value(signed: Int64(value)!)
case "f32": parameter = .f32(Float32(value)!.bitPattern)
case "f64": parameter = .f64(Float64(value)!.bitPattern)
default: fatalError("unknown type")
}
parameters.append(parameter)
}

return (functionName, parameters)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import SystemPackage
import WAT
import WasmKit

struct Wat2wasm: ParsableCommand {
static let configuration = CommandConfiguration(
package struct Wat2wasm: ParsableCommand {
package static let configuration = CommandConfiguration(
abstract: "Assemble WebAssembly text into a WebAssembly binary",
discussion: """
Parse a file in WebAssembly Text Format (`.wat`), \
Expand Down Expand Up @@ -58,7 +58,9 @@ struct Wat2wasm: ParsableCommand {
)
var output: String?

func run() throws {
package init() {}

package func run() throws {
let filePath = FilePath(path)
guard filePath.extension == "wat" else { throw Error.unknownFileExtension(filePath.extension) }
let fileHandle = try FileDescriptor.open(filePath, .readOnly)
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ add_subdirectory(WAT)

if(WASMKIT_BUILD_CLI)
add_subdirectory(CLI)
add_subdirectory(CLICommands)
endif()
Loading