Skip to content

Commit fd0e618

Browse files
leonbettv8-internal-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[wasm] Support br_on_cast_fail
This CL adds support for the br_on_cast_fail instruction. Bug: 474940922 Change-Id: Icacbd109fff843179f69806769437322f14326c8 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/9299601 Commit-Queue: Leon Bettscheider <bettscheider@google.com> Reviewed-by: Matthias Liedtke <mliedtke@google.com>
1 parent 4e85913 commit fd0e618

17 files changed

Lines changed: 333 additions & 33 deletions

Sources/Fuzzilli/Base/ProgramBuilder.swift

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5200,14 +5200,31 @@ public class ProgramBuilder {
52005200
types.append(.wasmTypeDef())
52015201
}
52025202

5203-
let wasmRefType = targetRefType.wasmReferenceType!
5204-
let cleanTargetRefType =
5205-
wasmRefType.isAbstract()
5206-
? targetRefType : ILType.wasmRef(.Index(), nullability: wasmRefType.nullability)
5207-
52085203
let instr = b.emit(
52095204
WasmBranchOnCast(
5210-
parameterCount: labelParams.count - 1, targetRefType: cleanTargetRefType),
5205+
parameterCount: labelParams.count - 1, targetRefType: targetRefType),
5206+
withInputs: inputs,
5207+
types: types)
5208+
return Array(instr.outputs)
5209+
}
5210+
5211+
@discardableResult
5212+
public func wasmBranchOnCastFail(
5213+
_ reference: Variable, targetRefType: ILType, to label: Variable, args: [Variable] = [],
5214+
typeDef: Variable? = nil
5215+
) -> [Variable] {
5216+
let labelType = b.type(of: label)
5217+
let labelParams = labelType.wasmLabelType!.parameters
5218+
var inputs = [label] + args + [reference]
5219+
var types = [.anyWasmLabel] + labelParams.dropLast() + [.wasmGenericRef]
5220+
if let typeDef {
5221+
inputs.append(typeDef)
5222+
types.append(.wasmTypeDef())
5223+
}
5224+
5225+
let instr = b.emit(
5226+
WasmBranchOnCastFail(
5227+
parameterCount: labelParams.count - 1, targetRefType: targetRefType),
52115228
withInputs: inputs,
52125229
types: types)
52135230
return Array(instr.outputs)
@@ -5620,7 +5637,9 @@ public class ProgramBuilder {
56205637
fatalError("Could not find or generate wasm variable of type \(type)")
56215638
}
56225639

5623-
public func randomWasmReferenceType(withAbstractSuperType type: ILType) -> ILType {
5640+
public func randomWasmReferenceType(withAbstractSuperType type: ILType) -> (
5641+
type: ILType, typeDef: Variable?
5642+
) {
56245643
assert(type.wasmReferenceType?.isAbstract() == true)
56255644

56265645
let nullability = type.wasmReferenceType!.nullability
@@ -5646,16 +5665,15 @@ public class ProgramBuilder {
56465665
}
56475666

56485667
if let typeDef {
5649-
let desc = b.type(of: typeDef).wasmTypeDefinition!.description!
5650-
return ILType.wasmIndexRef(desc, nullability: nullability)
5668+
return (.wasmRef(.Index(), nullability: nullability), typeDef)
56515669
}
56525670
}
56535671

56545672
let candidates = WasmAbstractHeapType.allCases
56555673
.map { ILType.wasmRef($0, shared: false, nullability: nullability) }
56565674
.filter { type.subsumes($0) }
56575675

5658-
return candidates.randomElement() ?? type
5676+
return (candidates.randomElement() ?? type, nil)
56595677
}
56605678

56615679
public func wasmUnreachable() {

Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,5 @@ public let codeGeneratorWeights = [
412412
"WasmRefCastGenerator": 5,
413413
"WasmRefCastAbstractGenerator": 5,
414414
"WasmBranchOnCastGenerator": 5,
415+
"WasmBranchOnCastFailGenerator": 5,
415416
]

Sources/Fuzzilli/CodeGen/WasmCodeGenerators.swift

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,30 +1906,80 @@ public let WasmCodeGenerators: [CodeGenerator] = [
19061906
let labelType = b.type(of: label).wasmLabelType!
19071907
let lastParamType = labelType.parameters.last!
19081908
assert(lastParamType.wasmReferenceType != nil, "This should never be a wasmGenericRef")
1909-
let isIndexType = !lastParamType.wasmReferenceType!.isAbstract()
1910-
let typeDef = isIndexType ? b.getWasmTypeDef(for: lastParamType) : nil
19111909
let sourceType = lastParamType.wasmReferenceType!.kind.topType()
19121910
let v = function.findOrGenerateWasmVar(ofType: sourceType)
19131911
let args = labelType.parameters.dropLast().map(function.findOrGenerateWasmVar)
1914-
function.wasmBranchOnCast(
1915-
v, targetRefType: lastParamType, to: label, args: args, typeDef: typeDef)
1912+
let isIndexType = !lastParamType.wasmReferenceType!.isAbstract()
1913+
if isIndexType {
1914+
let typeDef = b.getWasmTypeDef(for: lastParamType)
1915+
let unlinkedLastParamType = ILType.wasmRef(
1916+
.Index(), nullability: lastParamType.wasmReferenceType!.nullability)
1917+
function.wasmBranchOnCast(
1918+
v, targetRefType: unlinkedLastParamType, to: label, args: args, typeDef: typeDef
1919+
)
1920+
} else {
1921+
function.wasmBranchOnCast(v, targetRefType: lastParamType, to: label, args: args)
1922+
}
19161923
} else {
1917-
let hierarchies: [ILType] = [
1918-
.wasmAnyRef(), .wasmFuncRef(), .wasmExternRef(), .wasmExnRef(),
1919-
]
1920-
let topType = hierarchies.randomElement()!
1921-
let targetRefType = function.randomWasmReferenceType(withAbstractSuperType: topType)
1922-
let isIndexType = !targetRefType.wasmReferenceType!.isAbstract()
1923-
let typeDef = isIndexType ? b.getWasmTypeDef(for: targetRefType) : nil
1924+
let topType = ILType.wasmRefHierarchyTopTypes.randomElement()!
1925+
let (targetRefType, typeDef) = function.randomWasmReferenceType(
1926+
withAbstractSuperType: topType)
1927+
var blockOutputTypes = b.randomWasmBlockOutputTypes(upTo: 2) + [targetRefType]
1928+
let signatureDef = b.wasmDefineAdHocSignatureType(
1929+
signature: [] => blockOutputTypes,
1930+
indexTypes: typeDef != nil ? [typeDef!] : nil)
19241931

1925-
let blockParamTypes = b.randomWasmBlockOutputTypes(upTo: 2) + [targetRefType]
1932+
let signature = b.type(of: signatureDef).wasmFunctionSignatureDefSignature
1933+
1934+
function.wasmBuildBlockWithResults(with: signatureDef, args: []) {
1935+
blockLabel, _ in
1936+
let sourceVar = function.findOrGenerateWasmVar(ofType: topType)
1937+
let args = signature.outputTypes.map(function.findOrGenerateWasmVar)
1938+
1939+
function.wasmBranchOnCast(
1940+
sourceVar, targetRefType: targetRefType, to: blockLabel, args: args.dropLast(),
1941+
typeDef: typeDef)
1942+
1943+
return args
1944+
}
1945+
}
1946+
},
1947+
1948+
CodeGenerator(
1949+
"WasmBranchOnCastFailGenerator", inContext: .single(.wasmFunction)
1950+
) { b in
1951+
let function = b.currentWasmModule.currentWasmFunction
1952+
1953+
let label = b.findVariable { label in
1954+
if let params = b.type(of: label).wasmLabelType?.parameters, let last = params.last {
1955+
return ILType.wasmRefHierarchyTopTypes.contains(last)
1956+
}
1957+
return false
1958+
}
1959+
1960+
if let label {
1961+
let labelType = b.type(of: label).wasmLabelType!
1962+
let lastParamType = labelType.parameters.last!
1963+
1964+
let sourceVar = function.findOrGenerateWasmVar(ofType: lastParamType)
1965+
let (targetRefType, typeDef) = function.randomWasmReferenceType(
1966+
withAbstractSuperType: lastParamType)
1967+
1968+
let args = labelType.parameters.dropLast().map(function.findOrGenerateWasmVar)
1969+
function.wasmBranchOnCastFail(
1970+
sourceVar, targetRefType: targetRefType, to: label, args: args, typeDef: typeDef)
1971+
} else {
1972+
let topType = ILType.wasmRefHierarchyTopTypes.randomElement()!
1973+
let blockParamTypes = b.randomWasmBlockOutputTypes(upTo: 2) + [topType]
19261974

19271975
function.wasmBuildBlockWithResults(with: [] => blockParamTypes, args: []) {
19281976
blockLabel, _ in
19291977
let sourceVar = function.findOrGenerateWasmVar(ofType: topType)
1978+
let (targetRefType, typeDef) = function.randomWasmReferenceType(
1979+
withAbstractSuperType: topType)
19301980
let args = blockParamTypes.map(function.findOrGenerateWasmVar)
19311981

1932-
function.wasmBranchOnCast(
1982+
function.wasmBranchOnCastFail(
19331983
sourceVar, targetRefType: targetRefType, to: blockLabel, args: args.dropLast(),
19341984
typeDef: typeDef)
19351985

Sources/Fuzzilli/FuzzIL/Instruction.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,10 @@ extension Instruction: ProtobufConvertible {
16271627
$0.wasmBranchOnCast = Fuzzilli_Protobuf_WasmBranchOnCast.with {
16281628
$0.type = ILTypeToWasmTypeEnum(op.targetType)
16291629
}
1630+
case .wasmBranchOnCastFail(let op):
1631+
$0.wasmBranchOnCastFail = Fuzzilli_Protobuf_WasmBranchOnCastFail.with {
1632+
$0.type = ILTypeToWasmTypeEnum(op.targetType)
1633+
}
16301634
case .wasmBranchOnNonNull(_):
16311635
$0.wasmBranchOnNonNull = Fuzzilli_Protobuf_WasmBranchOnNonNull()
16321636
case .wasmBeginIf(let op):
@@ -2805,6 +2809,11 @@ extension Instruction: ProtobufConvertible {
28052809
op = WasmBranchOnCast(
28062810
parameterCount: (inouts.count - 3 - type.requiredInputCount()) / 2,
28072811
targetRefType: type)
2812+
case .wasmBranchOnCastFail(let p):
2813+
let type = WasmTypeEnumToILType(p.type)
2814+
op = WasmBranchOnCastFail(
2815+
parameterCount: (inouts.count - 3 - type.requiredInputCount()) / 2,
2816+
targetRefType: type)
28082817
case .wasmBranchOnNonNull(_):
28092818
op = WasmBranchOnNonNull(parameterCount: (inouts.count - 2) / 2)
28102819
case .wasmBeginIf(let p):

Sources/Fuzzilli/FuzzIL/JSTyper.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,26 @@ public struct JSTyper: Analyzer {
11531153
let sourceTopType = actualSourceType.kind.topType()
11541154
setType(of: instr.outputs.last!, to: sourceTopType)
11551155

1156+
case .wasmBranchOnCastFail(let op):
1157+
let labelType = type(of: instr.input(0))
1158+
let parameterTypes = labelType.wasmLabelType!.parameters
1159+
assert(instr.outputs.count == parameterTypes.count)
1160+
for (output, parameterType) in zip(
1161+
instr.outputs.dropLast(), parameterTypes.dropLast())
1162+
{
1163+
setType(of: output, to: parameterType)
1164+
}
1165+
1166+
let targetType = op.targetType.wasmReferenceType!
1167+
if targetType.isAbstract() {
1168+
setType(of: instr.outputs.last!, to: op.targetType)
1169+
} else {
1170+
let typeDefInputIndex = 1 + op.parameterCount + 1
1171+
setReferenceType(
1172+
of: instr.outputs.last!, typeDef: instr.input(typeDefInputIndex),
1173+
nullability: targetType.nullability)
1174+
}
1175+
11561176
case .wasmBranchOnNonNull(_):
11571177
let labelType = type(of: instr.input(0))
11581178
let parameterTypes = labelType.wasmLabelType!.parameters

Sources/Fuzzilli/FuzzIL/Opcodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,4 +386,5 @@ enum Opcode {
386386
case endWorkerFunction(EndWorkerFunction)
387387
case wasmBranchOnCast(WasmBranchOnCast)
388388
case importNamespace(ImportNamespace)
389+
case wasmBranchOnCastFail(WasmBranchOnCastFail)
389390
}

Sources/Fuzzilli/FuzzIL/TypeSystem.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,10 @@ public struct ILType: Hashable {
431431
.wasmi32, .wasmi64, .wasmf32, .wasmf64, .wasmSimd128,
432432
]
433433

434+
public static let wasmRefHierarchyTopTypes: [ILType] = [
435+
.wasmAnyRef(), .wasmFuncRef(), .wasmExternRef(), .wasmExnRef(),
436+
]
437+
434438
public static let anyNonNullableIndexRef = wasmRef(.Index(), nullability: false)
435439
public static let anyIndexRef = wasmRef(.Index(), nullability: true)
436440

Sources/Fuzzilli/FuzzIL/WasmOperations.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,23 @@ final class WasmBranchOnCast: WasmOperation {
16451645
var parameterCount: Int { numInputs - 2 - targetType.requiredInputCount() }
16461646
}
16471647

1648+
final class WasmBranchOnCastFail: WasmOperation {
1649+
override var opcode: Opcode { .wasmBranchOnCastFail(self) }
1650+
let targetType: ILType
1651+
1652+
init(parameterCount: Int, targetRefType: ILType) {
1653+
self.targetType = targetRefType
1654+
// Inputs: label, args, ref, type definition
1655+
// Outputs: args, original ref
1656+
super.init(
1657+
numInputs: 1 + parameterCount + 1 + targetType.requiredInputCount(),
1658+
numOutputs: parameterCount + 1,
1659+
requiredContext: [.wasmFunction])
1660+
}
1661+
1662+
var parameterCount: Int { numInputs - 2 - targetType.requiredInputCount() }
1663+
}
1664+
16481665
final class WasmBranchOnNonNull: WasmOperation {
16491666
override var opcode: Opcode { .wasmBranchOnNonNull(self) }
16501667

Sources/Fuzzilli/Lifting/FuzzILLifter.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,19 +1431,35 @@ public class FuzzILLifter: Lifter {
14311431
}
14321432

14331433
case .wasmBranchOnCast(let op):
1434-
let refInputIndex = 1 + op.parameterCount
1435-
let ref = instr.inputs[refInputIndex]
1434+
let typeDefCount = op.targetType.requiredInputCount() // 0 or 1
1435+
let ref = instr.inputs.dropLast(typeDefCount).last!
14361436
let label = instr.inputs.first!
1437-
let args = instr.inputs[1..<refInputIndex].map(lift).joined(separator: ", ")
1437+
let args = instr.inputs.dropFirst().dropLast(1 + typeDefCount).map(lift).joined(
1438+
separator: ", ")
14381439
let typeInput =
1439-
op.targetType.requiredInputCount() > 0
1440-
? " (IndexType: \(instr.inputs[refInputIndex + 1])" : ""
1440+
typeDefCount > 0
1441+
? " (IndexType: \(instr.inputs.last!))" : ""
14411442

14421443
let outputs = instr.outputs.map(lift).joined(separator: ", ")
14431444
w.emit(
14441445
"\(outputs) <- WasmBranchOnCast \(op.targetType) \(ref) to \(label) [\(args)]\(typeInput)"
14451446
)
14461447

1448+
case .wasmBranchOnCastFail(let op):
1449+
let typeDefCount = op.targetType.requiredInputCount() // 0 or 1
1450+
let ref = instr.inputs.dropLast(typeDefCount).last!
1451+
let label = instr.inputs.first!
1452+
let args = instr.inputs.dropFirst().dropLast(1 + typeDefCount).map(lift).joined(
1453+
separator: ", ")
1454+
let typeInput =
1455+
typeDefCount > 0
1456+
? " (IndexType: \(instr.inputs.last!))" : ""
1457+
1458+
let outputs = instr.outputs.map(lift).joined(separator: ", ")
1459+
w.emit(
1460+
"\(outputs) <- WasmBranchOnCastFail \(op.targetType) \(ref) to \(label) [\(args)]\(typeInput)"
1461+
)
1462+
14471463
case .wasmBranchTable(let op):
14481464
let table =
14491465
(0..<op.valueCount).enumerated().map { "\($0) => \(instr.input($1)), " }.joined()

Sources/Fuzzilli/Lifting/JavaScriptLifter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,7 @@ public class JavaScriptLifter: Lifter {
19991999
.wasmBranchOnNull(_),
20002000
.wasmBranchOnNonNull(_),
20012001
.wasmBranchOnCast(_),
2002+
.wasmBranchOnCastFail(_),
20022003
.wasmBranchTable(_),
20032004
.wasmBeginIf(_),
20042005
.wasmBeginElse(_),

0 commit comments

Comments
 (0)