Skip to content

Commit 8674444

Browse files
LiedtkeV8-internal LUCI CQ
authored andcommitted
[wasm] Fix WasmTypeGroupReducer to expose all unremoved types
While the WasmTypeGroupReducer shall remove all inputs which are not used from the WasmEndTypeGroup (so that these types can be removed in a following iteration), it should still expose all types which are used inside the type group, so that the JSTyper still continues to handle them correctly. This will hopefully fix the current crashes we are observing for types missing the linkage from a wasm index reference type to the corresponding type definition variable in the JSTyper. Bug: 475996631 Change-Id: I571a44fabee3f302c8f53fad14d6f62263d0a8ca Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/8935617 Commit-Queue: Matthias Liedtke <mliedtke@google.com> Reviewed-by: Michael Achenbach <machenbach@google.com> Auto-Submit: Matthias Liedtke <mliedtke@google.com>
1 parent 1968a97 commit 8674444

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

Sources/Fuzzilli/Minimization/WasmTypeGroupReducer.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,24 @@ struct WasmTypeGroupReducer: Reducer {
2222
uses[input]? += 1
2323
}
2424

25+
26+
guard instr.op is WasmTypeOperation else { continue }
27+
// Define the usages for all WasmTypeOperation so that we also count usages of a type
28+
// inside a type group (i.e. by other type operations).
29+
for output in instr.outputs {
30+
uses[output] = 0
31+
}
32+
2533
// For now, we only consider EndTypeGroup instructions.
2634
guard case .wasmEndTypeGroup = instr.op.opcode else { continue }
2735

2836
candidates.append(instr.index)
29-
for output in instr.outputs {
30-
uses[output] = 0
37+
for (input, output) in zip(instr.inputs, instr.outputs) {
38+
// Subtract 1 as the input in the WasmEndTypeGroup itself is not a reason to keep
39+
// the type. However, if the type is used inside the type group, it also needs to be
40+
// exposed by the type group. Right now the JSTyper requires that all types defined
41+
// in a type group are exposed by their WasmEndTypeGroup instruction.
42+
uses[output]! += uses[input]! - 1
3143
}
3244
}
3345

Tests/FuzzilliTests/MinimizerTest.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,55 @@ class MinimizerTests: XCTestCase {
21262126

21272127
}
21282128

2129+
func testWasmTypeGroupTypeOnlyUsedInDependency() throws {
2130+
let evaluator = EvaluatorForMinimizationTests()
2131+
let fuzzer = makeMockFuzzer(evaluator: evaluator)
2132+
let b = fuzzer.makeBuilder()
2133+
2134+
// Build input program to be minimized.
2135+
do {
2136+
let typeGroup = b.wasmDefineTypeGroup {
2137+
// This signature is only used by the structType which is exposed from this type
2138+
// group and then used in the struct.new_default inside the wasm function. Still,
2139+
// due to this indirect usage it must still be kept alive.
2140+
let signature = b.wasmDefineSignatureType(signature: [.wasmi32] => [.wasmi32], indexTypes: [])
2141+
let structType = b.wasmDefineStructType(fields: [.init(type: .wasmRef(.Index(), nullability: true), mutability: true)], indexTypes: [signature])
2142+
return [signature, structType]
2143+
}
2144+
2145+
b.buildWasmModule { wasmModule in
2146+
wasmModule.addWasmFunction(with: [] => [.wasmAnyRef()]) { function, label, args in
2147+
evaluator.nextInstructionIsImportant(in: b)
2148+
return [function.wasmStructNewDefault(structType: typeGroup[1])]
2149+
}
2150+
}
2151+
}
2152+
let originalProgram = b.finalize()
2153+
2154+
// Build expected output program.
2155+
do {
2156+
let typeGroup = b.wasmDefineTypeGroup {
2157+
let signature = b.wasmDefineSignatureType(signature: [.wasmi32] => [.wasmi32], indexTypes: [])
2158+
let structType = b.wasmDefineStructType(fields: [.init(type: .wasmRef(.Index(), nullability: true), mutability: true)], indexTypes: [signature])
2159+
return [signature, structType]
2160+
}
2161+
2162+
b.buildWasmModule { wasmModule in
2163+
wasmModule.addWasmFunction(with: [] => [.wasmAnyRef()]) { function, label, args in
2164+
return [function.wasmStructNewDefault(structType: typeGroup[1])]
2165+
}
2166+
}
2167+
}
2168+
let expectedProgram = b.finalize()
2169+
2170+
// Perform minimization and check that the two programs are equal.
2171+
let actualProgram = minimize(originalProgram, with: fuzzer)
2172+
XCTAssertEqual(expectedProgram, actualProgram,
2173+
"Expected:\n\(FuzzILLifter().lift(expectedProgram.code))\n\n" +
2174+
"Actual:\n\(FuzzILLifter().lift(actualProgram.code))")
2175+
}
2176+
2177+
21292178
func testWasmTypeGroupNestedTypesAndTypeGroupDependencies() throws {
21302179
let evaluator = EvaluatorForMinimizationTests()
21312180
let fuzzer = makeMockFuzzer(evaluator: evaluator)

0 commit comments

Comments
 (0)