Skip to content

Commit 456b52b

Browse files
committed
Threads: parsing of atomic instructions
1 parent d9b56a7 commit 456b52b

File tree

6 files changed

+28
-1
lines changed

6 files changed

+28
-1
lines changed

Sources/WAT/BinaryInstructionEncoder.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,5 @@ extension BinaryInstructionEncoder {
392392
try encodeInstruction([0xFC, 0x10])
393393
try encodeImmediates(table: table)
394394
}
395+
mutating func visitAtomicFence() throws { try encodeInstruction([0xFE, 0x03, 0x00]) }
395396
}

Sources/WAT/ParseTextInstruction.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
332332
case "i64.trunc_sat_f32_u": return { return try $0.visitConversion(.i64TruncSatF32U) }
333333
case "i64.trunc_sat_f64_s": return { return try $0.visitConversion(.i64TruncSatF64S) }
334334
case "i64.trunc_sat_f64_u": return { return try $0.visitConversion(.i64TruncSatF64U) }
335+
case "atomic.fence": return { return try $0.visitAtomicFence() }
335336
default: return nil
336337
}
337338
}

Sources/WasmParser/BinaryInstructionDecoder.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ protocol BinaryInstructionDecoder {
99
/// Claim the next byte to be decoded
1010
@inlinable func claimNextByte() throws -> UInt8
1111

12+
/// Throw an error due to unknown opcode.
1213
func throwUnknown(_ opcode: [UInt8]) throws -> Never
1314
/// Decode `block` immediates
1415
@inlinable mutating func visitBlock() throws -> BlockType
@@ -565,6 +566,22 @@ func parseBinaryInstruction(visitor: inout some InstructionVisitor, decoder: ino
565566
default:
566567
if try !visitor.visitUnknown([opcode0, opcode1]) { try decoder.throwUnknown([opcode0, opcode1]) }
567568
}
569+
case 0xFE:
570+
571+
let opcode1 = try decoder.claimNextByte()
572+
switch opcode1 {
573+
case 0x03:
574+
575+
let opcode2 = try decoder.claimNextByte()
576+
switch opcode2 {
577+
case 0x00:
578+
try visitor.visitAtomicFence()
579+
default:
580+
if try !visitor.visitUnknown([opcode0, opcode1, opcode2]) { try decoder.throwUnknown([opcode0, opcode1, opcode2]) }
581+
}
582+
default:
583+
if try !visitor.visitUnknown([opcode0, opcode1]) { try decoder.throwUnknown([opcode0, opcode1]) }
584+
}
568585
default:
569586
if try !visitor.visitUnknown([opcode0]) { try decoder.throwUnknown([opcode0]) }
570587
}

Sources/WasmParser/InstructionVisitor.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public enum Instruction: Equatable {
226226
case `tableSet`(table: UInt32)
227227
case `tableGrow`(table: UInt32)
228228
case `tableSize`(table: UInt32)
229+
case `atomicFence`
229230
}
230231

231232
/// A visitor that visits all instructions by a single visit method.
@@ -287,6 +288,7 @@ extension AnyInstructionVisitor {
287288
public mutating func visitTableSet(table: UInt32) throws { return try self.visit(.tableSet(table: table)) }
288289
public mutating func visitTableGrow(table: UInt32) throws { return try self.visit(.tableGrow(table: table)) }
289290
public mutating func visitTableSize(table: UInt32) throws { return try self.visit(.tableSize(table: table)) }
291+
public mutating func visitAtomicFence() throws { return try self.visit(.atomicFence) }
290292
}
291293

292294
/// A visitor for WebAssembly instructions.
@@ -398,6 +400,8 @@ public protocol InstructionVisitor {
398400
mutating func visitTableGrow(table: UInt32) throws
399401
/// Visiting `table.size` instruction.
400402
mutating func visitTableSize(table: UInt32) throws
403+
/// Visiting `atomic.fence` instruction.
404+
mutating func visitAtomicFence() throws
401405
/// Returns: `true` if the parser should silently proceed parsing.
402406
mutating func visitUnknown(_ opcode: [UInt8]) throws -> Bool
403407
}
@@ -458,6 +462,7 @@ extension InstructionVisitor {
458462
case let .tableSet(table): return try visitTableSet(table: table)
459463
case let .tableGrow(table): return try visitTableGrow(table: table)
460464
case let .tableSize(table): return try visitTableSize(table: table)
465+
case .atomicFence: return try visitAtomicFence()
461466
}
462467
}
463468
}
@@ -516,6 +521,7 @@ extension InstructionVisitor {
516521
public mutating func visitTableSet(table: UInt32) throws {}
517522
public mutating func visitTableGrow(table: UInt32) throws {}
518523
public mutating func visitTableSize(table: UInt32) throws {}
524+
public mutating func visitAtomicFence() throws {}
519525
public mutating func visitUnknown(_ opcode: [UInt8]) throws -> Bool { false }
520526
}
521527

Sources/_CWasmKit/include/_CWasmKit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef WASMKIT__CWASMKIT_H
22
#define WASMKIT__CWASMKIT_H
33

4+
#include <stdatomic.h>
45
#include <stddef.h>
56
#include <stdint.h>
67
#include <stdio.h>

Utilities/Instructions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,5 +201,6 @@
201201
["saturatingFloatToInt", "i64.trunc_sat_f32_s" , ["0xFC", "0x04"], [] , "conversion"],
202202
["saturatingFloatToInt", "i64.trunc_sat_f32_u" , ["0xFC", "0x05"], [] , "conversion"],
203203
["saturatingFloatToInt", "i64.trunc_sat_f64_s" , ["0xFC", "0x06"], [] , "conversion"],
204-
["saturatingFloatToInt", "i64.trunc_sat_f64_u" , ["0xFC", "0x07"], [] , "conversion"]
204+
["saturatingFloatToInt", "i64.trunc_sat_f64_u" , ["0xFC", "0x07"], [] , "conversion"],
205+
["threads" , "atomic.fence" , ["0xFE", "0x03", "0x00"], [] , null ]
205206
]

0 commit comments

Comments
 (0)