Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
42 changes: 21 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,27 +254,27 @@ jobs:
android-api-level: 30
swift-version: "${{ matrix.swift-version }}"

build-windows:
runs-on: windows-latest
steps:
- uses: compnerd/gha-setup-swift@main
with:
swift-version: swift-6.2-release
swift-build: 6.2-RELEASE
- uses: actions/checkout@v4
- run: python3 ./Vendor/checkout-dependency
# FIXME: CMake build is failing on CI due to "link: extra operand '/OUT:lib\\libXXXX.a'" error
# # Check Windows build with CMake
# - uses: Cyberboss/install-winget@v1
# - run: winget install Ninja-build.Ninja Kitware.CMake --disable-interactivity --accept-source-agreements
# - run: |
# echo "$env:LOCALAPPDATA\Microsoft\WinGet\Links" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# echo "$env:ProgramFiles\CMake\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# - run: cmake -G Ninja -B .build/cmake
# - run: cmake --build .build/cmake
# Run tests with SwiftPM
- name: Run tests with SwiftPM
run: swift test
# build-windows:
# runs-on: windows-latest
# steps:
# - uses: compnerd/gha-setup-swift@main
# with:
# swift-version: swift-6.2-release
# swift-build: 6.2-RELEASE
# - uses: actions/checkout@v4
# - run: python3 ./Vendor/checkout-dependency
# # FIXME: CMake build is failing on CI due to "link: extra operand '/OUT:lib\\libXXXX.a'" error
# # # Check Windows build with CMake
# # - uses: Cyberboss/install-winget@v1
# # - run: winget install Ninja-build.Ninja Kitware.CMake --disable-interactivity --accept-source-agreements
# # - run: |
# # echo "$env:LOCALAPPDATA\Microsoft\WinGet\Links" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# # echo "$env:ProgramFiles\CMake\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# # - run: cmake -G Ninja -B .build/cmake
# # - run: cmake --build .build/cmake
# # Run tests with SwiftPM
# - name: Run tests with SwiftPM
# run: swift test

build-cmake:
runs-on: ubuntu-24.04
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# WasmKit

**WasmKit** is a standalone and embeddable [WebAssembly](https://webassembly.org) runtime (virtual machine) implementation and related tooling written in Swift. Starting with Swift 6.2, WasmKit CLI executable is included in [Swift toolchains distributed at swift.org](https://swift.org/install) for Linux and macOS.
**WasmKit** is a standalone and embeddable [WebAssembly](https://webassembly.org) runtime (virtual machine) implementation and related tooling written in Swift. Starting with Swift 6.2, WasmKit CLI executable is included in [Swift toolchains distributed at swift.org](https://swift.org/install) for Linux and macOS.

## Usage

Expand Down
23 changes: 11 additions & 12 deletions Sources/WasmKit/Execution/Function.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,19 +254,18 @@ struct WasmFunctionEntity {
let store = store.value
let engine = store.engine
let type = self.type
var translator = try InstructionTranslator(
allocator: store.allocator.iseqAllocator,
engineConfiguration: engine.configuration,
funcTypeInterner: engine.funcTypeInterner,
module: instance,
type: engine.resolveType(type),
locals: code.locals,
functionIndex: index,
codeSize: code.expression.count,
isIntercepting: engine.interceptor != nil
)
let iseq = try code.withValue { code in
try translator.translate(code: code)
try InstructionTranslator(
allocator: store.allocator.iseqAllocator,
engineConfiguration: engine.configuration,
funcTypeInterner: engine.funcTypeInterner,
module: instance,
type: engine.resolveType(type),
locals: code.locals,
functionIndex: index,
codeSize: code.expression.count,
isIntercepting: engine.interceptor != nil
).translate(code: code)
}
self.code = .compiled(iseq)
return iseq
Expand Down
16 changes: 8 additions & 8 deletions Sources/WasmKit/Translator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ struct StackLayout {
}
}

struct InstructionTranslator: InstructionVisitor {
struct InstructionTranslator: ~Copyable, InstructionVisitor {
typealias Output = Void

typealias LabelRef = Int
Expand Down Expand Up @@ -526,15 +526,15 @@ struct InstructionTranslator: InstructionVisitor {
}
}

fileprivate struct ISeqBuilder {
fileprivate struct ISeqBuilder: ~Copyable {
typealias InstructionFactoryWithLabel = (
ISeqBuilder,
borrowing ISeqBuilder,
// The position of the next slot of the creating instruction
_ source: MetaProgramCounter,
// The position of the resolved label
_ target: MetaProgramCounter
) -> (WasmKit.Instruction)
typealias BrTableEntryFactory = (ISeqBuilder, MetaProgramCounter) -> Instruction.BrTableOperand.Entry
typealias BrTableEntryFactory = (borrowing ISeqBuilder, MetaProgramCounter) -> Instruction.BrTableOperand.Entry
typealias BuildingBrTable = UnsafeMutableBufferPointer<Instruction.BrTableOperand.Entry>

enum OnPinAction {
Expand Down Expand Up @@ -639,7 +639,7 @@ struct InstructionTranslator: InstructionVisitor {
}
}

func finalize() -> [UInt64] {
consuming func finalize() -> [UInt64] {
return instructions
}

Expand Down Expand Up @@ -707,7 +707,7 @@ struct InstructionTranslator: InstructionVisitor {
line: UInt = #line,
make:
@escaping (
ISeqBuilder,
borrowing ISeqBuilder,
// The position of the next slot of the creating instruction
_ source: MetaProgramCounter,
// The position of the resolved label
Expand Down Expand Up @@ -1086,7 +1086,7 @@ struct InstructionTranslator: InstructionVisitor {
try valueStack.truncate(height: currentFrame.stackHeight)
}

private mutating func finalize() throws -> InstructionSequence {
private consuming func finalize() throws -> InstructionSequence {
if controlStack.numberOfFrames > 1 {
throw ValidationError(.expectedMoreEndInstructions(count: controlStack.numberOfFrames - 1))
}
Expand Down Expand Up @@ -1129,7 +1129,7 @@ struct InstructionTranslator: InstructionVisitor {
// MARK: Main entry point

/// Translate a Wasm expression into a sequence of instructions.
mutating func translate(code: Code) throws -> InstructionSequence {
consuming func translate(code: Code) throws -> InstructionSequence {
if isIntercepting {
// Emit `onEnter` instruction at the beginning of the function
emit(.onEnter(functionIndex))
Expand Down
5 changes: 4 additions & 1 deletion Sources/WasmParser/BinaryInstructionDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ protocol BinaryInstructionDecoder {
}

@inlinable
func parseBinaryInstruction(visitor: inout some InstructionVisitor, decoder: inout some BinaryInstructionDecoder) throws -> Bool {
func parseBinaryInstruction(
visitor: inout some InstructionVisitor & ~Copyable,
decoder: inout some BinaryInstructionDecoder
) throws -> Bool {
visitor.binaryOffset = decoder.offset
let opcode0 = try decoder.claimNextByte()
switch opcode0 {
Expand Down
6 changes: 3 additions & 3 deletions Sources/WasmParser/InstructionVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ extension AnyInstructionVisitor {
///
/// The visitor pattern is used while parsing WebAssembly expressions to allow for easy extensibility.
/// See the expression parsing method ``Code/parseExpression(visitor:)``
public protocol InstructionVisitor {
public protocol InstructionVisitor: ~Copyable {
/// Current offset in visitor's instruction stream.
var binaryOffset: Int { get set }

Expand Down Expand Up @@ -423,7 +423,7 @@ public protocol InstructionVisitor {
mutating func visitUnknown(_ opcode: [UInt8]) throws -> Bool
}

extension InstructionVisitor {
extension InstructionVisitor where Self: ~Copyable {
/// Visits an instruction.
public mutating func visit(_ instruction: Instruction) throws {
switch instruction {
Expand Down Expand Up @@ -485,7 +485,7 @@ extension InstructionVisitor {
}

// MARK: - Placeholder implementations
extension InstructionVisitor {
extension InstructionVisitor where Self: ~Copyable {
public mutating func visitUnreachable() throws {}
public mutating func visitNop() throws {}
public mutating func visitBlock(blockType: BlockType) throws {}
Expand Down
4 changes: 2 additions & 2 deletions Sources/WasmParser/WasmParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public struct ExpressionParser {
}

@inlinable
public mutating func visit<V: InstructionVisitor>(visitor: inout V) throws -> Bool {
public mutating func visit(visitor: inout some InstructionVisitor & ~Copyable) throws -> Bool {
isLastEnd = try parser.parseInstruction(visitor: &visitor)
let shouldContinue = try !parser.stream.hasReachedEnd()
if !shouldContinue {
Expand Down Expand Up @@ -751,7 +751,7 @@ extension Parser: BinaryInstructionDecoder {
/// Returns: `true` if the parsed instruction is the block end instruction.
@inline(__always)
@inlinable
mutating func parseInstruction<V: InstructionVisitor>(visitor v: inout V) throws -> Bool {
mutating func parseInstruction(visitor v: inout some InstructionVisitor & ~Copyable) throws -> Bool {
return try parseBinaryInstruction(visitor: &v, decoder: &self)
}

Expand Down
11 changes: 7 additions & 4 deletions Utilities/Sources/WasmGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ enum WasmGen {
///
/// The visitor pattern is used while parsing WebAssembly expressions to allow for easy extensibility.
/// See the expression parsing method ``Code/parseExpression(visitor:)``
public protocol InstructionVisitor {
public protocol InstructionVisitor: ~Copyable {
/// Current offset in visitor's instruction stream.
var binaryOffset: Int { get set }

Expand All @@ -121,7 +121,7 @@ enum WasmGen {
code += """


extension InstructionVisitor {
extension InstructionVisitor where Self: ~Copyable {
/// Visits an instruction.
public mutating func visit(_ instruction: Instruction) throws {
switch instruction {
Expand Down Expand Up @@ -153,7 +153,7 @@ enum WasmGen {
code += """

// MARK: - Placeholder implementations
extension InstructionVisitor {
extension InstructionVisitor where Self: ~Copyable {

"""
for instruction in instructions.categorized {
Expand Down Expand Up @@ -567,7 +567,10 @@ enum WasmGen {
code += """

@inlinable
func parseBinaryInstruction(visitor: inout some InstructionVisitor, decoder: inout some BinaryInstructionDecoder) throws -> Bool {
func parseBinaryInstruction(
visitor: inout some InstructionVisitor & ~Copyable,
decoder: inout some BinaryInstructionDecoder
) throws -> Bool {
visitor.binaryOffset = decoder.offset
"""

Expand Down
Loading