Skip to content
Merged
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
15 changes: 15 additions & 0 deletions Sources/WAT/BinaryInstructionEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ extension BinaryInstructionEncoder {
case .i64Load16U: opcode = [0x33]
case .i64Load32S: opcode = [0x34]
case .i64Load32U: opcode = [0x35]
case .i32AtomicLoad: opcode = [0xFE, 0x10]
case .i64AtomicLoad: opcode = [0xFE, 0x11]
case .i32AtomicLoad8U: opcode = [0xFE, 0x12]
case .i32AtomicLoad16U: opcode = [0xFE, 0x13]
case .i64AtomicLoad8U: opcode = [0xFE, 0x14]
case .i64AtomicLoad16U: opcode = [0xFE, 0x15]
case .i64AtomicLoad32U: opcode = [0xFE, 0x16]
}

try encodeInstruction(opcode)
Expand All @@ -142,6 +149,13 @@ extension BinaryInstructionEncoder {
case .i64Store8: opcode = [0x3C]
case .i64Store16: opcode = [0x3D]
case .i64Store32: opcode = [0x3E]
case .i32AtomicStore: opcode = [0xFE, 0x17]
case .i64AtomicStore: opcode = [0xFE, 0x18]
case .i32AtomicStore8: opcode = [0xFE, 0x19]
case .i32AtomicStore16: opcode = [0xFE, 0x1A]
case .i64AtomicStore8: opcode = [0xFE, 0x1B]
case .i64AtomicStore16: opcode = [0xFE, 0x1C]
case .i64AtomicStore32: opcode = [0xFE, 0x1D]
}

try encodeInstruction(opcode)
Expand Down Expand Up @@ -392,4 +406,5 @@ extension BinaryInstructionEncoder {
try encodeInstruction([0xFC, 0x10])
try encodeImmediates(table: table)
}
mutating func visitAtomicFence() throws { try encodeInstruction([0xFE, 0x03, 0x00]) }
}
43 changes: 43 additions & 0 deletions Sources/WAT/ParseTextInstruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,49 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
case "i64.trunc_sat_f32_u": return { return try $0.visitConversion(.i64TruncSatF32U) }
case "i64.trunc_sat_f64_s": return { return try $0.visitConversion(.i64TruncSatF64S) }
case "i64.trunc_sat_f64_u": return { return try $0.visitConversion(.i64TruncSatF64U) }
case "atomic.fence": return { return try $0.visitAtomicFence() }
case "i32.atomic.load":
let (memarg) = try expressionParser.visitLoad(.i32AtomicLoad, wat: &wat)
return { return try $0.visitLoad(.i32AtomicLoad, memarg: memarg) }
case "i64.atomic.load":
let (memarg) = try expressionParser.visitLoad(.i64AtomicLoad, wat: &wat)
return { return try $0.visitLoad(.i64AtomicLoad, memarg: memarg) }
case "i32.atomic.load8_u":
let (memarg) = try expressionParser.visitLoad(.i32AtomicLoad8U, wat: &wat)
return { return try $0.visitLoad(.i32AtomicLoad8U, memarg: memarg) }
case "i32.atomic.load16_u":
let (memarg) = try expressionParser.visitLoad(.i32AtomicLoad16U, wat: &wat)
return { return try $0.visitLoad(.i32AtomicLoad16U, memarg: memarg) }
case "i64.atomic.load8_u":
let (memarg) = try expressionParser.visitLoad(.i64AtomicLoad8U, wat: &wat)
return { return try $0.visitLoad(.i64AtomicLoad8U, memarg: memarg) }
case "i64.atomic.load16_u":
let (memarg) = try expressionParser.visitLoad(.i64AtomicLoad16U, wat: &wat)
return { return try $0.visitLoad(.i64AtomicLoad16U, memarg: memarg) }
case "i64.atomic.load32_u":
let (memarg) = try expressionParser.visitLoad(.i64AtomicLoad32U, wat: &wat)
return { return try $0.visitLoad(.i64AtomicLoad32U, memarg: memarg) }
case "i32.atomic.store":
let (memarg) = try expressionParser.visitStore(.i32AtomicStore, wat: &wat)
return { return try $0.visitStore(.i32AtomicStore, memarg: memarg) }
case "i64.atomic.store":
let (memarg) = try expressionParser.visitStore(.i64AtomicStore, wat: &wat)
return { return try $0.visitStore(.i64AtomicStore, memarg: memarg) }
case "i32.atomic.store8":
let (memarg) = try expressionParser.visitStore(.i32AtomicStore8, wat: &wat)
return { return try $0.visitStore(.i32AtomicStore8, memarg: memarg) }
case "i32.atomic.store16":
let (memarg) = try expressionParser.visitStore(.i32AtomicStore16, wat: &wat)
return { return try $0.visitStore(.i32AtomicStore16, memarg: memarg) }
case "i64.atomic.store8":
let (memarg) = try expressionParser.visitStore(.i64AtomicStore8, wat: &wat)
return { return try $0.visitStore(.i64AtomicStore8, memarg: memarg) }
case "i64.atomic.store16":
let (memarg) = try expressionParser.visitStore(.i64AtomicStore16, wat: &wat)
return { return try $0.visitStore(.i64AtomicStore16, memarg: memarg) }
case "i64.atomic.store32":
let (memarg) = try expressionParser.visitStore(.i64AtomicStore32, wat: &wat)
return { return try $0.visitStore(.i64AtomicStore32, memarg: memarg) }
default: return nil
}
}
126 changes: 126 additions & 0 deletions Sources/WasmKit/Execution/DispatchInstruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,20 @@ extension Execution {
case 197: return self.execute_onEnter(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 198: return self.execute_onExit(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 199: return try self.execute_breakpoint(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 200: return try self.execute_i32AtomicLoad(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 201: return try self.execute_i64AtomicLoad(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 202: return try self.execute_i32AtomicLoad8U(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 203: return try self.execute_i32AtomicLoad16U(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 204: return try self.execute_i64AtomicLoad8U(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 205: return try self.execute_i64AtomicLoad16U(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 206: return try self.execute_i64AtomicLoad32U(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 207: return try self.execute_i32AtomicStore(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 208: return try self.execute_i64AtomicStore(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 209: return try self.execute_i32AtomicStore8(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 210: return try self.execute_i32AtomicStore16(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 211: return try self.execute_i64AtomicStore8(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 212: return try self.execute_i64AtomicStore16(sp: &sp, pc: &pc, md: &md, ms: &ms)
case 213: return try self.execute_i64AtomicStore32(sp: &sp, pc: &pc, md: &md, ms: &ms)
default: preconditionFailure("Unknown instruction!?")

}
Expand Down Expand Up @@ -1802,6 +1816,118 @@ extension Execution {
(pc.pointee, next) = try self.breakpoint(sp: &sp.pointee, pc: pc.pointee)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicLoad") @inline(__always)
mutating func execute_i32AtomicLoad(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt32.self, castToValue: { .i32($0) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicLoad") @inline(__always)
mutating func execute_i64AtomicLoad(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt64.self, castToValue: { .i64($0) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicLoad8U") @inline(__always)
mutating func execute_i32AtomicLoad8U(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt8.self, castToValue: { .i32(UInt32($0)) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicLoad16U") @inline(__always)
mutating func execute_i32AtomicLoad16U(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt16.self, castToValue: { .i32(UInt32($0)) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicLoad8U") @inline(__always)
mutating func execute_i64AtomicLoad8U(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt8.self, castToValue: { .i64(UInt64($0)) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicLoad16U") @inline(__always)
mutating func execute_i64AtomicLoad16U(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt16.self, castToValue: { .i64(UInt64($0)) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicLoad32U") @inline(__always)
mutating func execute_i64AtomicLoad32U(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.LoadOperand.load(from: &pc.pointee)
try memoryLoad(sp: sp.pointee, md: md.pointee, ms: ms.pointee, loadOperand: immediate, loadAs: UInt32.self, castToValue: { .i64(UInt64($0)) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicStore") @inline(__always)
mutating func execute_i32AtomicStore(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { $0.i32 })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicStore") @inline(__always)
mutating func execute_i64AtomicStore(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { $0.i64 })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicStore8") @inline(__always)
mutating func execute_i32AtomicStore8(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { UInt8(truncatingIfNeeded: $0.i32) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i32AtomicStore16") @inline(__always)
mutating func execute_i32AtomicStore16(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { UInt16(truncatingIfNeeded: $0.i32) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicStore8") @inline(__always)
mutating func execute_i64AtomicStore8(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { UInt8(truncatingIfNeeded: $0.i64) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicStore16") @inline(__always)
mutating func execute_i64AtomicStore16(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { UInt16(truncatingIfNeeded: $0.i64) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
@_silgen_name("wasmkit_execute_i64AtomicStore32") @inline(__always)
mutating func execute_i64AtomicStore32(sp: UnsafeMutablePointer<Sp>, pc: UnsafeMutablePointer<Pc>, md: UnsafeMutablePointer<Md>, ms: UnsafeMutablePointer<Ms>) throws -> CodeSlot {
let immediate = Instruction.StoreOperand.load(from: &pc.pointee)
try memoryStore(sp: sp.pointee, md: md.pointee, ms: ms.pointee, storeOperand: immediate, castFromValue: { UInt32(truncatingIfNeeded: $0.i64) })
let next = pc.pointee.pointee
pc.pointee = pc.pointee.advanced(by: 1)
return next
}
}

extension Instruction {
Expand Down
Loading