Skip to content

Commit dbce3f1

Browse files
Add tail-call instructions and run WasmGen
1 parent 07293bf commit dbce3f1

File tree

6 files changed

+44
-0
lines changed

6 files changed

+44
-0
lines changed

Sources/WAT/BinaryInstructionEncoder.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ extension BinaryInstructionEncoder {
7474
try encodeInstruction([0x11])
7575
try encodeImmediates(typeIndex: typeIndex, tableIndex: tableIndex)
7676
}
77+
mutating func visitReturnCall(functionIndex: UInt32) throws {
78+
try encodeInstruction([0x12])
79+
try encodeImmediates(functionIndex: functionIndex)
80+
}
81+
mutating func visitReturnCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws {
82+
try encodeInstruction([0x13])
83+
try encodeImmediates(typeIndex: typeIndex, tableIndex: tableIndex)
84+
}
7785
mutating func visitDrop() throws { try encodeInstruction([0x1A]) }
7886
mutating func visitSelect() throws { try encodeInstruction([0x1B]) }
7987
mutating func visitTypedSelect(type: ValueType) throws {

Sources/WAT/ParseTextInstruction.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
4343
case "call_indirect":
4444
let (typeIndex, tableIndex) = try expressionParser.visitCallIndirect(wat: &wat)
4545
return { return try $0.visitCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex) }
46+
case "return_call":
47+
let (functionIndex) = try expressionParser.visitReturnCall(wat: &wat)
48+
return { return try $0.visitReturnCall(functionIndex: functionIndex) }
49+
case "return_call_indirect":
50+
let (typeIndex, tableIndex) = try expressionParser.visitReturnCallIndirect(wat: &wat)
51+
return { return try $0.visitReturnCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex) }
4652
case "drop": return { return try $0.visitDrop() }
4753
case "select": return { return try $0.visitSelect() }
4854
case "local.get":

Sources/WAT/Parser/ExpressionParser.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,12 @@ extension ExpressionParser {
450450
let (_, typeIndex) = try wat.types.resolve(use: typeUse)
451451
return (UInt32(typeIndex), tableIndex)
452452
}
453+
mutating func visitReturnCall(wat: inout Wat) throws -> UInt32 {
454+
return try visitCall(wat: &wat)
455+
}
456+
mutating func visitReturnCallIndirect(wat: inout Wat) throws -> (typeIndex: UInt32, tableIndex: UInt32) {
457+
return try visitCallIndirect(wat: &wat)
458+
}
453459
mutating func visitTypedSelect(wat: inout Wat) throws -> ValueType {
454460
fatalError("unreachable because Instruction.json does not define the name of typed select and it is handled in parseTextInstruction() manually")
455461
}

Sources/WasmParser/BinaryInstructionDecoder.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ protocol BinaryInstructionDecoder {
2626
@inlinable mutating func visitCall() throws -> UInt32
2727
/// Decode `call_indirect` immediates
2828
@inlinable mutating func visitCallIndirect() throws -> (typeIndex: UInt32, tableIndex: UInt32)
29+
/// Decode `return_call` immediates
30+
@inlinable mutating func visitReturnCall() throws -> UInt32
31+
/// Decode `return_call_indirect` immediates
32+
@inlinable mutating func visitReturnCallIndirect() throws -> (typeIndex: UInt32, tableIndex: UInt32)
2933
/// Decode `typedSelect` immediates
3034
@inlinable mutating func visitTypedSelect() throws -> ValueType
3135
/// Decode `local.get` immediates
@@ -122,6 +126,12 @@ func parseBinaryInstruction<V: InstructionVisitor, D: BinaryInstructionDecoder>(
122126
case 0x11:
123127
let (typeIndex, tableIndex) = try decoder.visitCallIndirect()
124128
try visitor.visitCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex)
129+
case 0x12:
130+
let (functionIndex) = try decoder.visitReturnCall()
131+
try visitor.visitReturnCall(functionIndex: functionIndex)
132+
case 0x13:
133+
let (typeIndex, tableIndex) = try decoder.visitReturnCallIndirect()
134+
try visitor.visitReturnCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex)
125135
case 0x1A:
126136
try visitor.visitDrop()
127137
case 0x1B:

Sources/WasmParser/InstructionVisitor.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ public enum Instruction: Equatable {
187187
case `return`
188188
case `call`(functionIndex: UInt32)
189189
case `callIndirect`(typeIndex: UInt32, tableIndex: UInt32)
190+
case `returnCall`(functionIndex: UInt32)
191+
case `returnCallIndirect`(typeIndex: UInt32, tableIndex: UInt32)
190192
case `drop`
191193
case `select`
192194
case `typedSelect`(type: ValueType)
@@ -246,6 +248,8 @@ extension AnyInstructionVisitor {
246248
public mutating func visitReturn() throws { return try self.visit(.return) }
247249
public mutating func visitCall(functionIndex: UInt32) throws { return try self.visit(.call(functionIndex: functionIndex)) }
248250
public mutating func visitCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws { return try self.visit(.callIndirect(typeIndex: typeIndex, tableIndex: tableIndex)) }
251+
public mutating func visitReturnCall(functionIndex: UInt32) throws { return try self.visit(.returnCall(functionIndex: functionIndex)) }
252+
public mutating func visitReturnCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws { return try self.visit(.returnCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex)) }
249253
public mutating func visitDrop() throws { return try self.visit(.drop) }
250254
public mutating func visitSelect() throws { return try self.visit(.select) }
251255
public mutating func visitTypedSelect(type: ValueType) throws { return try self.visit(.typedSelect(type: type)) }
@@ -316,6 +320,10 @@ public protocol InstructionVisitor {
316320
mutating func visitCall(functionIndex: UInt32) throws
317321
/// Visiting `call_indirect` instruction.
318322
mutating func visitCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws
323+
/// Visiting `return_call` instruction.
324+
mutating func visitReturnCall(functionIndex: UInt32) throws
325+
/// Visiting `return_call_indirect` instruction.
326+
mutating func visitReturnCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws
319327
/// Visiting `drop` instruction.
320328
mutating func visitDrop() throws
321329
/// Visiting `select` instruction.
@@ -409,6 +417,8 @@ extension InstructionVisitor {
409417
case .return: return try visitReturn()
410418
case let .call(functionIndex): return try visitCall(functionIndex: functionIndex)
411419
case let .callIndirect(typeIndex, tableIndex): return try visitCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex)
420+
case let .returnCall(functionIndex): return try visitReturnCall(functionIndex: functionIndex)
421+
case let .returnCallIndirect(typeIndex, tableIndex): return try visitReturnCallIndirect(typeIndex: typeIndex, tableIndex: tableIndex)
412422
case .drop: return try visitDrop()
413423
case .select: return try visitSelect()
414424
case let .typedSelect(type): return try visitTypedSelect(type: type)
@@ -465,6 +475,8 @@ extension InstructionVisitor {
465475
public mutating func visitReturn() throws {}
466476
public mutating func visitCall(functionIndex: UInt32) throws {}
467477
public mutating func visitCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws {}
478+
public mutating func visitReturnCall(functionIndex: UInt32) throws {}
479+
public mutating func visitReturnCallIndirect(typeIndex: UInt32, tableIndex: UInt32) throws {}
468480
public mutating func visitDrop() throws {}
469481
public mutating func visitSelect() throws {}
470482
public mutating func visitTypedSelect(type: ValueType) throws {}

Utilities/Instructions.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
["mvp" , "return" , ["0x0F"] , [] , null ],
1313
["mvp" , "call" , ["0x10"] , [["functionIndex", "UInt32"]] , null ],
1414
["mvp" , "call_indirect" , ["0x11"] , [["typeIndex", "UInt32"], ["tableIndex", "UInt32"]], null ],
15+
["tailCall" , "return_call" , ["0x12"] , [["functionIndex", "UInt32"]] , null ],
16+
["tailCall" , "return_call_indirect" , ["0x13"] , [["typeIndex", "UInt32"], ["tableIndex", "UInt32"]], null ],
1517
["mvp" , "drop" , ["0x1A"] , [] , null ],
1618
["mvp" , "select" , ["0x1B"] , [] , null ],
1719
["referenceTypes" , {"enumCase": "typedSelect"}, ["0x1C"] , [["type", "ValueType"]] , null ],

0 commit comments

Comments
 (0)