Skip to content

Commit 4b1170c

Browse files
WAT: Ban named param and check inline type consistency in block type
1 parent f2e7033 commit 4b1170c

File tree

4 files changed

+34
-29
lines changed

4 files changed

+34
-29
lines changed

Sources/WAT/NameMapping.swift

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ struct TypesMap {
169169
/// Resolves a block type from a type use
170170
mutating func resolveBlockType(use: WatParser.TypeUse) throws -> BlockType {
171171
switch (use.index, use.inline) {
172-
case let (indexOrId?, _):
173-
let (type, index) = try resolve(use: indexOrId)
172+
case let (indexOrId?, inline):
173+
let (type, index) = try resolveAndCheck(use: indexOrId, inline: inline)
174174
return try resolveBlockType(signature: type.signature, resolveSignatureIndex: { _ in index })
175175
case (nil, let inline?):
176176
return try resolveBlockType(signature: inline.signature)
@@ -194,18 +194,22 @@ struct TypesMap {
194194
return (decl.type, index)
195195
}
196196

197+
private func resolveAndCheck(use indexOrId: Parser.IndexOrId, inline: WatParser.FunctionType?) throws -> (type: WatParser.FunctionType, index: Int) {
198+
let (found, index) = try resolve(use: indexOrId)
199+
if let inline {
200+
// If both index and inline type, then they must match
201+
guard found.signature == inline.signature else {
202+
throw WatParserError("Type mismatch \(found) != \(inline)", location: indexOrId.location)
203+
}
204+
}
205+
return (found, Int(index))
206+
}
207+
197208
/// Resolves a function type from a type use with an optional inline type
198209
mutating func resolve(use: WatParser.TypeUse) throws -> (type: WatParser.FunctionType, index: Int) {
199210
switch (use.index, use.inline) {
200211
case let (indexOrId?, inline):
201-
let (found, index) = try resolve(use: indexOrId)
202-
if let inline {
203-
// If both index and inline type, then they must match
204-
guard found.signature == inline.signature else {
205-
throw WatParserError("Type mismatch \(found) != \(inline)", location: indexOrId.location)
206-
}
207-
}
208-
return (found, Int(index))
212+
return try resolveAndCheck(use: indexOrId, inline: inline)
209213
case (nil, let inline):
210214
// If no index and no inline type, then it's a function type with no parameters or results
211215
let inline = inline ?? WatParser.FunctionType(signature: WasmTypes.FunctionType(parameters: [], results: []), parameterNames: [])

Sources/WAT/Parser/ExpressionParser.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ struct ExpressionParser<Visitor: InstructionVisitor> {
352352
if !results.isEmpty {
353353
return try wat.types.resolveBlockType(results: results)
354354
}
355-
let typeUse = try withWatParser { try $0.typeUse() }
355+
let typeUse = try withWatParser { try $0.typeUse(mayHaveName: false) }
356356
return try wat.types.resolveBlockType(use: typeUse)
357357
}
358358

@@ -455,7 +455,7 @@ extension ExpressionParser {
455455
} else {
456456
tableIndex = 0
457457
}
458-
let typeUse = try withWatParser { try $0.typeUse() }
458+
let typeUse = try withWatParser { try $0.typeUse(mayHaveName: true) }
459459
let (_, typeIndex) = try wat.types.resolve(use: typeUse)
460460
return (UInt32(typeIndex), tableIndex)
461461
}

Sources/WAT/Parser/WatParser.swift

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ struct WatParser {
196196
let importNames = try importNames()
197197
if try parser.takeParenBlockStart("func") {
198198
let id = try parser.takeId()
199-
kind = .function(FunctionDecl(id: id, exports: [], typeUse: try typeUse(), kind: .imported(importNames)))
199+
kind = .function(FunctionDecl(id: id, exports: [], typeUse: try typeUse(mayHaveName: true), kind: .imported(importNames)))
200200
} else if try parser.takeParenBlockStart("table") {
201201
let id = try parser.takeId()
202202
kind = .table(TableDecl(id: id, exports: [], type: try tableType(), importNames: importNames))
@@ -215,7 +215,7 @@ struct WatParser {
215215
let id = try parser.takeId()
216216
let exports = try inlineExports()
217217
let importNames = try inlineImport()
218-
let typeUse = try typeUse()
218+
let typeUse = try typeUse(mayHaveName: true)
219219
let functionKind: FunctionKind
220220
if let importNames = importNames {
221221
functionKind = .imported(importNames)
@@ -441,14 +441,14 @@ struct WatParser {
441441
return ImportNames(module: module, name: name)
442442
}
443443

444-
mutating func typeUse() throws -> TypeUse {
444+
mutating func typeUse(mayHaveName: Bool) throws -> TypeUse {
445445
let location = parser.lexer.location()
446446
var index: Parser.IndexOrId?
447447
if try parser.takeParenBlockStart("type") {
448448
index = try parser.expectIndexOrId()
449449
try parser.expect(.rightParen)
450450
}
451-
let inline = try optionalFunctionType()
451+
let inline = try optionalFunctionType(mayHaveName: mayHaveName)
452452
return TypeUse(index: index, inline: inline, location: location)
453453
}
454454

@@ -552,37 +552,39 @@ struct WatParser {
552552
mutating func funcType() throws -> FunctionType {
553553
try parser.expect(.leftParen)
554554
try parser.expectKeyword("func")
555-
let (params, names) = try params()
555+
let (params, names) = try params(mayHaveName: true)
556556
let results = try results()
557557
try parser.expect(.rightParen)
558558
return FunctionType(signature: WasmTypes.FunctionType(parameters: params, results: results), parameterNames: names)
559559
}
560560

561-
mutating func optionalFunctionType() throws -> FunctionType? {
562-
let (params, names) = try params()
561+
mutating func optionalFunctionType(mayHaveName: Bool) throws -> FunctionType? {
562+
let (params, names) = try params(mayHaveName: mayHaveName)
563563
let results = try results()
564564
if results.isEmpty, params.isEmpty {
565565
return nil
566566
}
567567
return FunctionType(signature: WasmTypes.FunctionType(parameters: params, results: results), parameterNames: names)
568568
}
569569

570-
mutating func params() throws -> ([ValueType], [Name?]) {
570+
mutating func params(mayHaveName: Bool) throws -> ([ValueType], [Name?]) {
571571
var types: [ValueType] = []
572572
var names: [Name?] = []
573573
while try parser.takeParenBlockStart("param") {
574-
if let id = try parser.takeId() {
575-
let valueType = try valueType()
576-
types.append(valueType)
577-
names.append(id)
578-
try parser.expect(.rightParen)
579-
} else {
580-
while try !parser.take(.rightParen) {
574+
if mayHaveName {
575+
if let id = try parser.takeId() {
581576
let valueType = try valueType()
582577
types.append(valueType)
583-
names.append(nil)
578+
names.append(id)
579+
try parser.expect(.rightParen)
580+
continue
584581
}
585582
}
583+
while try !parser.take(.rightParen) {
584+
let valueType = try valueType()
585+
types.append(valueType)
586+
names.append(nil)
587+
}
586588
}
587589
return (types, names)
588590
}

Tests/WATTests/EncoderTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ class EncoderTests: XCTestCase {
107107

108108
var stats = CompatibilityTestStats()
109109
let excluded: [String] = [
110-
"block.wast",
111110
"call_indirect.wast",
112111
"const.wast",
113112
"float_literals.wast",

0 commit comments

Comments
 (0)