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
6 changes: 6 additions & 0 deletions Examples/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ let package = Package(
.package(path: "../")
],
targets: [
.executableTarget(
name: "embedded-wat",
dependencies: [
.product(name: "WAT", package: "WasmKit")
]
),
.executableTarget(name: "Factorial", dependencies: [
.product(name: "WasmKit", package: "WasmKit"),
.product(name: "WAT", package: "WasmKit")
Expand Down
24 changes: 24 additions & 0 deletions Examples/Sources/embedded-wat/Entrypoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import WAT

@main
struct Entrypoint {
static func main() {
var watString = ""
while let line = readLine() {
if !watString.isEmpty {
watString += "\n"
}
watString += line
}
guard !watString.isEmpty else { return }

do throws(WatParserError) {
let bytes = try wat2wasm(watString)
for byte in bytes {
print("0x" + String(byte, radix: 16))
}
} catch {
print(error)
}
}
}
13 changes: 10 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ let package = Package(
.target(
name: "WAT",
dependencies: [
"WasmParser",
"WasmParserCore",
.target(
name: "ComponentModel",
condition: .when(traits: ["ComponentModel"])
Expand All @@ -97,17 +97,24 @@ let package = Package(
),

.target(
name: "WasmParser",
name: "WasmParserCore",
dependencies: [
"WasmTypes",
.product(name: "SystemPackage", package: "swift-system"),
.target(
name: "ComponentModel",
condition: .when(traits: ["ComponentModel"])
),
],
exclude: ["CMakeLists.txt"]
),
.target(
name: "WasmParser",
dependencies: [
"WasmParserCore",
.product(name: "SystemPackage", package: "swift-system"),
],
exclude: ["CMakeLists.txt"]
),
.testTarget(
name: "WasmParserTests",
dependencies: [
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_subdirectory(SystemExtras)
add_subdirectory(WASI)
add_subdirectory(WasmTypes)
add_subdirectory(WasmParser)
add_subdirectory(WasmParserCore)
add_subdirectory(WAT)

if(WASMKIT_BUILD_CLI)
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/BinaryEncoding/BinaryInstructionEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//// Automatically generated by Utilities/Sources/WasmGen.swift
//// DO NOT EDIT DIRECTLY

import WasmParser
import WasmParserCore
import WasmTypes

/// An instruction encoder that is responsible for encoding opcodes and immediates
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/BinaryEncoding/ComponentEncoder.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if ComponentModel
import ComponentModel
import WasmParser
import WasmParserCore
import WasmTypes

/// Binary component encoder, implementing CM proposal `Binary.md` spec: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md
Expand Down
16 changes: 8 additions & 8 deletions Sources/WAT/BinaryEncoding/Encoder.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

package struct Encoder {
Expand Down Expand Up @@ -511,7 +511,7 @@ struct ExpressionEncoder: BinaryInstructionEncoder {
mutating func encodeInstruction(_ opcode: [UInt8]) {
encoder.output.append(contentsOf: opcode)
}
mutating func encodeImmediates(blockType: WasmParser.BlockType) {
mutating func encodeImmediates(blockType: WasmParserCore.BlockType) {
switch blockType {
case .empty: encoder.output.append(0x40)
case .type(let valueType): encoder.encode(valueType)
Expand All @@ -528,12 +528,12 @@ struct ExpressionEncoder: BinaryInstructionEncoder {
mutating func encodeImmediates(globalIndex: UInt32) { encodeUnsigned(globalIndex) }
mutating func encodeImmediates(localIndex: UInt32) { encodeUnsigned(localIndex) }
mutating func encodeImmediates(typeIndex: UInt32) { encodeUnsigned(typeIndex) }
mutating func encodeImmediates(memarg: WasmParser.MemArg) {
mutating func encodeImmediates(memarg: WasmParserCore.MemArg) {
encodeUnsigned(UInt(memarg.align))
encodeUnsigned(memarg.offset)
}
mutating func encodeImmediates(lane: UInt8) { encoder.output.append(lane) }
mutating func encodeImmediates(memarg: WasmParser.MemArg, lane: UInt8) {
mutating func encodeImmediates(memarg: WasmParserCore.MemArg, lane: UInt8) {
encodeImmediates(memarg: memarg)
encodeImmediates(lane: lane)
}
Expand All @@ -543,7 +543,7 @@ struct ExpressionEncoder: BinaryInstructionEncoder {
mutating func encodeImmediates(memory: UInt32) { encodeUnsigned(memory) }
mutating func encodeImmediates(relativeDepth: UInt32) { encodeUnsigned(relativeDepth) }
mutating func encodeImmediates(table: UInt32) { encodeUnsigned(table) }
mutating func encodeImmediates(targets: WasmParser.BrTable) {
mutating func encodeImmediates(targets: WasmParserCore.BrTable) {
encoder.encodeVector(targets.labelIndices) { value, encoder in
encoder.writeUnsignedLEB128(value)
}
Expand All @@ -554,8 +554,8 @@ struct ExpressionEncoder: BinaryInstructionEncoder {
mutating func encodeImmediates(value: Int32) { encodeSigned(value) }
mutating func encodeImmediates(value: Int64) { encodeSigned(value) }
mutating func encodeImmediates(value: WasmTypes.V128) { encoder.output.append(contentsOf: value.bytes) }
mutating func encodeImmediates(value: WasmParser.IEEE754.Float32) { encodeFixedWidth(value.bitPattern) }
mutating func encodeImmediates(value: WasmParser.IEEE754.Float64) { encodeFixedWidth(value.bitPattern) }
mutating func encodeImmediates(value: WasmParserCore.IEEE754.Float32) { encodeFixedWidth(value.bitPattern) }
mutating func encodeImmediates(value: WasmParserCore.IEEE754.Float64) { encodeFixedWidth(value.bitPattern) }
mutating func encodeImmediates(dstMem: UInt32, srcMem: UInt32) {
encodeUnsigned(dstMem)
encodeUnsigned(srcMem)
Expand Down Expand Up @@ -625,7 +625,7 @@ func encode(module: inout Wat, options: EncodeOptions) throws(WatParserError) ->
// Section 1: Type section
if !module.types.isEmpty {
encoder.section(id: 0x01) { encoder in
encoder.encodeVector(module.types, transform: \.type.signature)
encoder.encodeVector(module.types, transform: { $0.type.signature })
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ add_wasmkit_library(WAT
)

target_link_wasmkit_libraries(WAT PUBLIC
WasmParser)
WasmParserCore)
5 changes: 3 additions & 2 deletions Sources/WAT/Lexer.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import WasmParser
import WasmParserCore
import WasmTypes

enum TokenKind: Equatable {
case leftParen
Expand Down Expand Up @@ -471,7 +472,7 @@ func parseHexDigit(_ char: Unicode.Scalar) throws(WatParserError) -> UInt8? {

extension Lexer.Cursor {
mutating func parseHexNumber() throws(WatParserError) -> String {
return try parseUnderscoredChars(continueParsing: \.properties.isASCIIHexDigit)
return try parseUnderscoredChars(continueParsing: { $0.properties.isASCIIHexDigit })
}

mutating func parseDecimalNumber() throws(WatParserError) -> String {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/NameMapping.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

/// A name with its location in the source file
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/ParseTextInstruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//// Automatically generated by Utilities/Sources/WasmGen.swift
//// DO NOT EDIT DIRECTLY

import WasmParser
import WasmParserCore
import WasmTypes

/// Parses a text instruction, consuming immediate tokens as necessary.
Expand Down
6 changes: 3 additions & 3 deletions Sources/WAT/Parser.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

internal struct Parser {
Expand Down Expand Up @@ -266,7 +266,7 @@ internal struct Parser {

mutating func expectFloat32() throws(WatParserError) -> IEEE754.Float32 {
let bitPattern = try expectFloatingPoint(
Float32.self, toBitPattern: \.bitPattern,
Float32.self, toBitPattern: { $0.bitPattern },
isNaN: { Float32(bitPattern: $0).isNaN },
buildBitPattern: {
UInt32(
Expand All @@ -280,7 +280,7 @@ internal struct Parser {

mutating func expectFloat64() throws(WatParserError) -> IEEE754.Float64 {
let bitPattern = try expectFloatingPoint(
Float64.self, toBitPattern: \.bitPattern,
Float64.self, toBitPattern: { $0.bitPattern },
isNaN: { Float64(bitPattern: $0).isNaN },
buildBitPattern: {
UInt64(
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/Parser/ComponentDef.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if ComponentModel

import ComponentModel
import WasmParser
import WasmParserCore
import WasmTypes

extension ComponentWatParser {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/Parser/ComponentWastParser.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if ComponentModel

import ComponentModel
import WasmParser
import WasmParserCore
import WasmTypes

// MARK: - Component WAST Directive Types
Expand Down
12 changes: 4 additions & 8 deletions Sources/WAT/Parser/ComponentWatParser.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if ComponentModel

import ComponentModel
import WasmParser
import WasmParserCore
import WasmTypes

public struct ComponentWatParser: ~Copyable {
Expand Down Expand Up @@ -832,14 +832,10 @@
parser = tempParser.parser

// Core types must be simple value types (i32, i64, f32, f64), not type references.
// Resolve immediately using a dummy resolver since these types don't reference other definitions.
struct DummyResolver: NameToIndexResolver {
func resolveIndex(use: Parser.IndexOrId) throws(WatParserError) -> Int {
throw WatParserError("Core value types cannot reference other types", location: use.location)
}
// Resolve immediately using a throwing resolver since these types don't reference other definitions.
return try unresolvedType.resolve { (use: Parser.IndexOrId) throws(WatParserError) in
throw WatParserError("Core value types cannot reference other types", location: use.location)
}

return try unresolvedType.resolve(DummyResolver())
}

/// Resolve an outer alias reference to a component's type
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/Parser/ExpressionParser.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

struct ExpressionParser<Visitor: InstructionVisitor> where Visitor.VisitorError == WatParserError {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/Parser/NormalizedDefinition.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if ComponentModel

import ComponentModel
import WasmParser
import WasmParserCore
import WasmTypes

extension ComponentWatParser {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WAT/Parser/WastParser.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

protocol WastConstInstructionVisitor: InstructionVisitor {
Expand Down
60 changes: 32 additions & 28 deletions Sources/WAT/Parser/WatParser.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WasmParser
import WasmParserCore
import WasmTypes

struct WatParser {
Expand Down Expand Up @@ -36,32 +36,40 @@ struct WatParser {
}

struct UnresolvedType<T> {
private let make: (any NameToIndexResolver) -> Result<T, WatParserError>
typealias IndexResolver = (Parser.IndexOrId) throws(WatParserError) -> Int

init(make: @escaping (any NameToIndexResolver) -> Result<T, WatParserError>) {
private let make: (IndexResolver) throws(WatParserError) -> T

init(make: @escaping (IndexResolver) throws(WatParserError) -> T) {
self.make = make
}

init(_ value: T) {
self.make = { _ in .success(value) }
self.make = { _ in value }
}

func project<U>(_ keyPath: KeyPath<T, U>) -> UnresolvedType<U> {
return UnresolvedType<U> {
let parent = make($0)
return parent.map { $0[keyPath: keyPath] }
return UnresolvedType<U> { (resolveIndex: IndexResolver) throws(WatParserError) in
try self.make(resolveIndex)[keyPath: keyPath]
}
}

func map<U>(_ transform: @escaping (T) -> U) -> UnresolvedType<U> {
return UnresolvedType<U>(make: { resolver in Result { () throws(WatParserError) in transform(try resolve(resolver)) } })
return UnresolvedType<U> { (resolveIndex: IndexResolver) throws(WatParserError) in
try transform(self.make(resolveIndex))
}
}

func resolve(_ typeMap: TypesMap) throws(WatParserError) -> T {
return try resolve(typeMap.nameMapping)
return try make(typeMap.nameMapping.resolveIndex)
}
func resolve(_ resolver: any NameToIndexResolver) throws(WatParserError) -> T {
return try make(resolver).get()

func resolve(_ resolver: some NameToIndexResolver) throws(WatParserError) -> T {
return try make(resolver.resolveIndex)
}

func resolve(_ resolveIndex: IndexResolver) throws(WatParserError) -> T {
return try make(resolveIndex)
}
}

Expand Down Expand Up @@ -324,7 +332,7 @@ struct WatParser {
if try parser.peek(.leftParen) != nil {
let (numberOfItems, indices) = try parseExprList()
inlineElement = ElementDecl(
mode: .inline, type: tableType.project(\.elementType), indices: indices
mode: .inline, type: tableType.map({ $0.elementType }), indices: indices
)
tableType = tableType.map {
var value = $0
Expand Down Expand Up @@ -650,13 +658,11 @@ struct WatParser {
let (params, names) = try params(mayHaveName: true)
let results = try results()
try parser.expect(.rightParen)
return UnresolvedType<FunctionType> { typeMap in
Result { () throws(WatParserError) in
let params = try params.map { param throws(WatParserError) in try param.resolve(typeMap) }
let results = try results.map { result throws(WatParserError) in try result.resolve(typeMap) }
let signature = WasmTypes.FunctionType(parameters: params, results: results)
return FunctionType(signature: signature, parameterNames: names)
}
return UnresolvedType<FunctionType> { (resolveIndex: UnresolvedType<ValueType>.IndexResolver) throws(WatParserError) in
let params = try params.map { param throws(WatParserError) in try param.resolve(resolveIndex) }
let results = try results.map { result throws(WatParserError) in try result.resolve(resolveIndex) }
let signature = WasmTypes.FunctionType(parameters: params, results: results)
return FunctionType(signature: signature, parameterNames: names)
}
}

Expand All @@ -666,13 +672,11 @@ struct WatParser {
if results.isEmpty, params.isEmpty {
return nil
}
return UnresolvedType<FunctionType> { typeMap in
Result { () throws(WatParserError) in
let params = try params.map { resolver throws(WatParserError) in try resolver.resolve(typeMap) }
let results = try results.map { resolver throws(WatParserError) in try resolver.resolve(typeMap) }
let signature = WasmTypes.FunctionType(parameters: params, results: results)
return FunctionType(signature: signature, parameterNames: names)
}
return UnresolvedType<FunctionType> { (resolveIndex: UnresolvedType<ValueType>.IndexResolver) throws(WatParserError) in
let params = try params.map { param throws(WatParserError) in try param.resolve(resolveIndex) }
let results = try results.map { result throws(WatParserError) in try result.resolve(resolveIndex) }
let signature = WasmTypes.FunctionType(parameters: params, results: results)
return FunctionType(signature: signature, parameterNames: names)
}
}

Expand Down Expand Up @@ -746,8 +750,8 @@ struct WatParser {
} else if try parser.takeKeyword("extern") {
return UnresolvedType(.abstract(.externRef))
} else if let id = try parser.takeIndexOrId() {
return UnresolvedType(make: { resolver in
Result { () throws(WatParserError) in try .concrete(typeIndex: UInt32(resolver.resolveIndex(use: id))) }
return UnresolvedType(make: { (resolveIndex: UnresolvedType<HeapType>.IndexResolver) throws(WatParserError) in
try .concrete(typeIndex: UInt32(resolveIndex(id)))
})
}
throw WatParserError("expected heap type", location: parser.lexer.location())
Expand Down
Loading
Loading