Skip to content

Commit

Permalink
Merge pull request #95 from swiftwasm/katei/add-atomics-feature
Browse files Browse the repository at this point in the history
Add parser support for the threads proposal
  • Loading branch information
kateinoigakukun committed May 26, 2024
2 parents 2606823 + 7300227 commit 17b9a64
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
44 changes: 33 additions & 11 deletions Sources/WasmParser/WasmParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ public struct WasmFeatureSet: OptionSet {
public static let memory64 = WasmFeatureSet(rawValue: 1 << 0)
/// The WebAssembly reference types proposal
public static let referenceTypes = WasmFeatureSet(rawValue: 1 << 1)
/// The WebAssembly threads proposal
public static let threads = WasmFeatureSet(rawValue: 1 << 2)

/// The default feature set
public static let `default`: WasmFeatureSet = [.referenceTypes]
/// The feature set with all features enabled
public static let all: WasmFeatureSet = [.memory64, .referenceTypes]
public static let all: WasmFeatureSet = [.memory64, .referenceTypes, .threads]
}

public enum WasmParserError: Swift.Error {
Expand Down Expand Up @@ -274,19 +276,39 @@ extension Parser {
/// <https://webassembly.github.io/spec/core/binary/types.html#limits>
func parseLimits() throws -> Limits {
let b = try stream.consumeAny()
let sharedMask : UInt8 = 0b0010
let isMemory64Mask: UInt8 = 0b0100

switch b {
case 0x00:
return try Limits(min: UInt64(parseUnsigned(UInt32.self)), max: nil)
case 0x01:
return try Limits(min: UInt64(parseUnsigned(UInt32.self)), max: UInt64(parseUnsigned(UInt32.self)))
case 0x04 where features.contains(.memory64):
return try Limits(min: parseUnsigned(UInt64.self), max: nil, isMemory64: true)
case 0x05 where features.contains(.memory64):
return try Limits(min: parseUnsigned(UInt64.self), max: parseUnsigned(UInt64.self), isMemory64: true)
default:
let hasMax = b & 0b0001 != 0
let shared = b & sharedMask != 0
let isMemory64 = b & isMemory64Mask != 0

var flagMask: UInt8 = 0b0001
if features.contains(.threads) {
flagMask |= sharedMask
}
if features.contains(.memory64) {
flagMask |= isMemory64Mask
}
guard (b & ~flagMask) == 0 else {
throw WasmParserError.malformedLimit(b)
}

let min: UInt64
if isMemory64 {
min = try parseUnsigned(UInt64.self)
} else {
min = try UInt64(parseUnsigned(UInt32.self))
}
var max: UInt64?
if hasMax {
if isMemory64 {
max = try parseUnsigned(UInt64.self)
} else {
max = try UInt64(parseUnsigned(UInt32.self))
}
}
return Limits(min: min, max: max, isMemory64: isMemory64, shared: shared)
}

/// > Note:
Expand Down
4 changes: 3 additions & 1 deletion Sources/WasmParser/WasmTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ public struct Limits: Equatable {
public let min: UInt64
public let max: UInt64?
public let isMemory64: Bool
public let shared: Bool

public init(min: UInt64, max: UInt64?, isMemory64: Bool = false) {
public init(min: UInt64, max: UInt64?, isMemory64: Bool = false, shared: Bool = false) {
self.min = min
self.max = max
self.isMemory64 = isMemory64
self.shared = shared
}
}

Expand Down

0 comments on commit 17b9a64

Please sign in to comment.