Skip to content

Commit 2dccaf6

Browse files
WasmParser: Move OrderTracking to Parser module
1 parent 046852e commit 2dccaf6

File tree

2 files changed

+76
-64
lines changed

2 files changed

+76
-64
lines changed

Sources/WasmKit/ModuleParser.swift

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,9 @@ public func parseWasm(bytes: [UInt8], features: WasmFeatureSet = .default) throw
3131
return module
3232
}
3333

34-
private struct OrderTracking {
35-
enum Order: UInt8 {
36-
case initial = 0
37-
case type
38-
case _import
39-
case function
40-
case table
41-
case memory
42-
case tag
43-
case global
44-
case export
45-
case start
46-
case element
47-
case dataCount
48-
case code
49-
case data
50-
}
51-
52-
private var last: Order = .initial
53-
mutating func track(order: Order) throws {
54-
guard last.rawValue < order.rawValue else {
55-
throw WasmParserError.sectionOutOfOrder
56-
}
57-
last = order
58-
}
59-
}
60-
6134
/// > Note:
6235
/// <https://webassembly.github.io/spec/core/binary/modules.html#binary-module>
6336
func parseModule<Stream: ByteStream>(stream: Stream, features: WasmFeatureSet = .default) throws -> Module {
64-
var orderTracking = OrderTracking()
6537
var types: [FunctionType] = []
6638
var typeIndices: [TypeIndex] = []
6739
var codes: [Code] = []
@@ -86,40 +58,28 @@ func parseModule<Stream: ByteStream>(stream: Stream, features: WasmFeatureSet =
8658
case .customSection(let customSection):
8759
customSections.append(customSection)
8860
case .typeSection(let typeSection):
89-
try orderTracking.track(order: .type)
9061
types = typeSection
9162
case .importSection(let importSection):
92-
try orderTracking.track(order: ._import)
9363
imports = importSection
9464
case .functionSection(let types):
95-
try orderTracking.track(order: .function)
9665
typeIndices = types
9766
case .tableSection(let tableSection):
98-
try orderTracking.track(order: .table)
9967
tables = tableSection.map(\.type)
10068
case .memorySection(let memorySection):
101-
try orderTracking.track(order: .memory)
10269
memories = memorySection.map(\.type)
10370
case .globalSection(let globalSection):
104-
try orderTracking.track(order: .global)
10571
globals = globalSection
10672
case .exportSection(let exportSection):
107-
try orderTracking.track(order: .export)
10873
exports = exportSection
10974
case .startSection(let functionIndex):
110-
try orderTracking.track(order: .start)
11175
start = functionIndex
11276
case .elementSection(let elementSection):
113-
try orderTracking.track(order: .element)
11477
elements = elementSection
11578
case .codeSection(let codeSection):
116-
try orderTracking.track(order: .code)
11779
codes = codeSection
11880
case .dataSection(let dataSection):
119-
try orderTracking.track(order: .data)
12081
data = dataSection
12182
case .dataCount(let count):
122-
try orderTracking.track(order: .dataCount)
12383
dataCount = count
12484
}
12585
}

Sources/WasmParser/WasmParser.swift

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ public struct Parser<Stream: ByteStream> {
1515
public private(set) var hasDataCount: Bool = false
1616
public let features: WasmFeatureSet
1717
let limits: ParsingLimits
18+
var orderTracking = OrderTracking()
1819

1920
enum NextParseTarget {
2021
case header
2122
case section
2223
}
2324
private var nextParseTarget: NextParseTarget
2425

25-
@usableFromInline
26-
var currentIndex: Int {
26+
public var offset: Int {
2727
return stream.currentIndex
2828
}
2929

@@ -37,7 +37,7 @@ public struct Parser<Stream: ByteStream> {
3737

3838
@usableFromInline
3939
internal func makeError(_ message: WasmParserError.Message) -> WasmParserError {
40-
return WasmParserError(message, offset: currentIndex)
40+
return WasmParserError(message, offset: offset)
4141
}
4242
}
4343

@@ -147,7 +147,7 @@ public struct ExpressionParser {
147147
var lastCode: InstructionCode?
148148

149149
public var offset: Int {
150-
self.codeOffset + self.parser.currentIndex - self.initialStreamOffset
150+
self.codeOffset + self.parser.offset - self.initialStreamOffset
151151
}
152152

153153
public init(code: Code) {
@@ -157,7 +157,7 @@ public struct ExpressionParser {
157157
hasDataCount: code.hasDataCount
158158
)
159159
self.codeOffset = code.offset
160-
self.initialStreamOffset = self.parser.currentIndex
160+
self.initialStreamOffset = self.parser.offset
161161
}
162162

163163
@inlinable
@@ -322,10 +322,6 @@ extension WasmParserError.Message {
322322
}
323323

324324
extension WasmParserError {
325-
// TODO: Remove
326-
public static var sectionOutOfOrder: Self {
327-
Self(.sectionOutOfOrder, offset: 0)
328-
}
329325
public static func inconsistentFunctionAndCodeLength(functionCount: Int, codeCount: Int) -> Self {
330326
Self(.inconsistentFunctionAndCodeLength(functionCount: functionCount, codeCount: codeCount), offset: 0)
331327
}
@@ -449,7 +445,7 @@ extension Parser {
449445
case 0x70: return .ref(.funcRef)
450446
case 0x6F: return .ref(.externRef)
451447
default:
452-
throw StreamError<Stream.Element>.unexpected(b, index: currentIndex, expected: Set(0x7C...0x7F))
448+
throw StreamError<Stream.Element>.unexpected(b, index: offset, expected: Set(0x7C...0x7F))
453449
}
454450
}
455451

@@ -547,7 +543,7 @@ extension Parser {
547543
case 0x6F:
548544
elementType = .externRef
549545
default:
550-
throw StreamError.unexpected(b, index: currentIndex, expected: [0x6F, 0x70])
546+
throw StreamError.unexpected(b, index: offset, expected: [0x6F, 0x70])
551547
}
552548

553549
let limits = try parseLimits()
@@ -1220,6 +1216,33 @@ extension Parser {
12201216
return version
12211217
}
12221218

1219+
struct OrderTracking {
1220+
enum Order: UInt8 {
1221+
case initial = 0
1222+
case type
1223+
case _import
1224+
case function
1225+
case table
1226+
case memory
1227+
case tag
1228+
case global
1229+
case export
1230+
case start
1231+
case element
1232+
case dataCount
1233+
case code
1234+
case data
1235+
}
1236+
1237+
private var last: Order = .initial
1238+
mutating func track(order: Order, parser: Parser) throws {
1239+
guard last.rawValue < order.rawValue else {
1240+
throw parser.makeError(.sectionOutOfOrder)
1241+
}
1242+
last = order
1243+
}
1244+
}
1245+
12231246
/// Attempts to parse a chunk of the Wasm binary stream.
12241247
///
12251248
/// - Returns: A `ParsingPayload` if the parsing was successful, otherwise `nil`.
@@ -1264,28 +1287,57 @@ extension Parser {
12641287
let sectionStart = stream.currentIndex
12651288

12661289
let payload: ParsingPayload
1290+
let order: OrderTracking.Order?
12671291
switch sectionID {
1268-
case 0: payload = .customSection(try parseCustomSection(size: sectionSize))
1269-
case 1: payload = .typeSection(try parseTypeSection())
1270-
case 2: payload = .importSection(try parseImportSection())
1271-
case 3: payload = .functionSection(try parseFunctionSection())
1272-
case 4: payload = .tableSection(try parseTableSection())
1273-
case 5: payload = .memorySection(try parseMemorySection())
1274-
case 6: payload = .globalSection(try parseGlobalSection())
1275-
case 7: payload = .exportSection(try parseExportSection())
1276-
case 8: payload = .startSection(try parseStartSection())
1277-
case 9: payload = .elementSection(try parseElementSection())
1278-
case 10: payload = .codeSection(try parseCodeSection())
1279-
case 11: payload = .dataSection(try parseDataSection())
1292+
case 0:
1293+
order = nil
1294+
payload = .customSection(try parseCustomSection(size: sectionSize))
1295+
case 1:
1296+
order = .type
1297+
payload = .typeSection(try parseTypeSection())
1298+
case 2:
1299+
order = ._import
1300+
payload = .importSection(try parseImportSection())
1301+
case 3:
1302+
order = .function
1303+
payload = .functionSection(try parseFunctionSection())
1304+
case 4:
1305+
order = .table
1306+
payload = .tableSection(try parseTableSection())
1307+
case 5:
1308+
order = .memory
1309+
payload = .memorySection(try parseMemorySection())
1310+
case 6:
1311+
order = .global
1312+
payload = .globalSection(try parseGlobalSection())
1313+
case 7:
1314+
order = .export
1315+
payload = .exportSection(try parseExportSection())
1316+
case 8:
1317+
order = .start
1318+
payload = .startSection(try parseStartSection())
1319+
case 9:
1320+
order = .element
1321+
payload = .elementSection(try parseElementSection())
1322+
case 10:
1323+
order = .code
1324+
payload = .codeSection(try parseCodeSection())
1325+
case 11:
1326+
order = .data
1327+
payload = .dataSection(try parseDataSection())
12801328
case 12:
1329+
order = .dataCount
12811330
hasDataCount = true
12821331
payload = .dataCount(try parseDataCountSection())
12831332
default:
12841333
throw makeError(.malformedSectionID(sectionID))
12851334
}
1335+
if let order = order {
1336+
try orderTracking.track(order: order, parser: self)
1337+
}
12861338
let expectedSectionEnd = sectionStart + Int(sectionSize)
12871339
guard expectedSectionEnd == stream.currentIndex else {
1288-
throw makeError(.sectionSizeMismatch(expected: expectedSectionEnd, actual: currentIndex))
1340+
throw makeError(.sectionSizeMismatch(expected: expectedSectionEnd, actual: offset))
12891341
}
12901342
return payload
12911343
}

0 commit comments

Comments
 (0)