Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parser support for the threads proposal #95

Merged
merged 1 commit into from
May 26, 2024
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
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
Loading