Skip to content

Commit

Permalink
Merge pull request #108 from swiftwasm/katei/update-spectest
Browse files Browse the repository at this point in the history
Update spectest part1
  • Loading branch information
kateinoigakukun authored Jul 22, 2024
2 parents b7fc72b + defa571 commit 2191586
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 229 deletions.
42 changes: 26 additions & 16 deletions Sources/WAT/Encoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,15 @@ extension TableType: WasmEncodable {
}
}

struct ElementExprCollector: VoidInstructionVisitor {
struct ElementExprCollector: AnyInstructionVisitor {
typealias Output = Void

var isAllRefFunc: Bool = true
var useExpression: Bool {
// if all instructions are ref.func, use function indices representation
return !isAllRefFunc
}
let addFunctionIndex: (UInt32?) -> Void
var instructions: [Instruction] = []

mutating func parse(indices: WatParser.ElementDecl.Indices, wat: inout Wat) throws {
switch indices {
Expand All @@ -160,6 +162,10 @@ struct ElementExprCollector: VoidInstructionVisitor {
}
}

private mutating func addFunctionIndex(_ index: UInt32) {
instructions.append(.refFunc(functionIndex: index))
}

private mutating func parseFunctionList(lexer: Lexer, wat: Wat) throws {
var parser = Parser(lexer)
while let funcUse = try parser.takeIndexOrId() {
Expand All @@ -168,12 +174,12 @@ struct ElementExprCollector: VoidInstructionVisitor {
}
}

mutating func visitRefFunc(functionIndex: UInt32) throws {
addFunctionIndex(functionIndex)
}
mutating func visitRefNull(type: ReferenceType) throws {
isAllRefFunc = false
addFunctionIndex(nil)
mutating func visit(_ instruction: Instruction) throws {
if case .refFunc = instruction {
} else {
isAllRefFunc = false
}
instructions.append(instruction)
}
}

Expand Down Expand Up @@ -209,8 +215,7 @@ extension WAT.WatParser.ElementDecl {
fatalError("Inline element segment should be replaced with active mode")
}

var functionIndices: [UInt32?] = []
var collector = ElementExprCollector(addFunctionIndex: { functionIndices.append($0) })
var collector = ElementExprCollector()
try collector.parse(indices: indices, wat: &wat)

if collector.useExpression {
Expand Down Expand Up @@ -243,19 +248,24 @@ extension WAT.WatParser.ElementDecl {
}

if collector.useExpression {
try encoder.encodeVector(functionIndices) { funcIndex, encoder in
try encoder.encodeVector(collector.instructions) { instruction, encoder in
var exprEncoder = ExpressionEncoder()
if let funcIndex {
try exprEncoder.visitRefFunc(functionIndex: funcIndex)
} else {
switch instruction {
case .globalGet(let globalIndex):
try exprEncoder.visitGlobalGet(globalIndex: globalIndex)
case .refFunc(let functionIndex):
try exprEncoder.visitRefFunc(functionIndex: functionIndex)
case .refNull(let type):
try exprEncoder.visitRefNull(type: type)
default:
throw WatParserError("unexpected instruction in element expression (\(instruction)", location: nil)
}
try exprEncoder.visitEnd()
encoder.output.append(contentsOf: exprEncoder.encoder.output)
}
} else {
encoder.encodeVector(functionIndices) { funcIndex, encoder in
guard let funcIndex else { fatalError("null function reference in non-expression mode") }
encoder.encodeVector(collector.instructions) { instruction, encoder in
guard case let .refFunc(funcIndex) = instruction else { fatalError("non-ref.func instruction in non-expression mode") }
encoder.writeUnsignedLEB128(funcIndex)
}
}
Expand Down
8 changes: 8 additions & 0 deletions Sources/WAT/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,14 @@ struct ExpressionParser<Visitor: InstructionVisitor> {
return false
}

mutating func parseConstInstruction(visitor: inout Visitor) throws -> Bool {
var wat = Wat.empty()
if try foldedInstruction(visitor: &visitor, wat: &wat) {
return true
}
return false
}

mutating func parseWastExpectValue() throws -> WastExpectValue? {
let initialParser = parser
func takeNaNPattern(canonical: WastExpectValue, arithmetic: WastExpectValue) throws -> WastExpectValue? {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WasmKit/Execution/Runtime/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension Runtime {
// Process `elem.init` evaluation during allocation

// Step 11.
let instance = store.allocate(
let instance = try store.allocate(
module: module,
externalValues: externalValues,
initialGlobals: initialGlobals
Expand Down
14 changes: 11 additions & 3 deletions Sources/WasmKit/Execution/Runtime/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ extension Store {
module: Module,
externalValues: [ExternalValue],
initialGlobals: [Value]
) -> ModuleInstance {
) throws -> ModuleInstance {
// Step 1 of module allocation algorithm, according to Wasm 2.0 spec.
let moduleInstance = ModuleInstance(selfAddress: modules.count)

Expand Down Expand Up @@ -286,7 +286,7 @@ extension Store {

// Step 6.
for element in module.elements {
let references = element.initializer.map { expression -> Reference in
let references = try element.initializer.map { expression -> Reference in
switch expression[0] {
case let .refFunc(index):
let addr = moduleInstance.functionAddresses[Int(index)]
Expand All @@ -295,8 +295,16 @@ extension Store {
return .function(nil)
case .refNull(.externRef):
return .extern(nil)
case .globalGet(let index):
let globalAddr = moduleInstance.globalAddresses[Int(index)]
switch globals[globalAddr].value {
case .ref(.function(let addr)):
return .function(addr)
default:
throw Trap._raw("Unexpected global value type for element initializer expression")
}
default:
fatalError("Unexpected element initializer expression: \(expression)")
throw Trap._raw("Unexpected element initializer expression: \(expression)")
}
}
let address = allocate(elementType: element.type, references: references)
Expand Down
Loading

0 comments on commit 2191586

Please sign in to comment.