Skip to content

Feature/nestedBreak #513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Sources/Fuzzilli/Base/ProgramBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2822,6 +2822,34 @@ public class ProgramBuilder {
emit(Print(), withInputs: [value])
}

public func loopNestedContinue(_ depth: Int){
emit(LoopNestedContinue(depth), withInputs: [])
}

public func loopNestedBreak(_ depth: Int){
emit(LoopNestedBreak(depth), withInputs: [])
}

public func blockNestedBreak(_ depth: Int){
emit(BlockNestedBreak(depth), withInputs: [])
}

public func ifNestedBreak(_ depth: Int){
emit(IfNestedBreak(depth), withInputs: [])
}

public func switchNestedBreak(_ depth: Int){
emit(SwitchNestedBreak(depth), withInputs: [])
}

public func withNestedBreak(_ depth: Int){
emit(WithNestedBreak(depth), withInputs: [])
}

public func tryNestedBreak(_ depth: Int){
emit(TryNestedBreak(depth), withInputs: [])
}


@discardableResult
public func createWasmGlobal(value: WasmGlobal, isMutable: Bool) -> Variable {
Expand Down
7 changes: 7 additions & 0 deletions Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ public let codeGeneratorWeights = [
"TryCatchGenerator": 5,
"ThrowGenerator": 1,
"BlockStatementGenerator": 1,
"LoopNestedContinueGenerator": 1,
"LoopNestedBreakGenerator": 1,
"BlockNestedBreakGenerator": 1,
"IfNestedBreakGenerator": 1,
"TryNestedBreakGenerator": 1,
"SwitchNestedBreakGenerator": 1,
"WithNestedBreakGenerator": 1,

// Special generators
"WellKnownPropertyLoadGenerator": 5,
Expand Down
30 changes: 29 additions & 1 deletion Sources/Fuzzilli/CodeGen/CodeGenerators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public let CodeGenerators: [CodeGenerator] = [
ValueGenerator("StringGenerator") { b, n in
for _ in 0..<n {
b.loadString(b.randomString())
}
}
},

ValueGenerator("BooleanGenerator") { b, n in
Expand Down Expand Up @@ -1866,6 +1866,34 @@ public let CodeGenerators: [CodeGenerator] = [
b.callFunction(f, withArgs: args)
}, catchBody: { _ in })
},

CodeGenerator("LoopNestedContinueGenerator", inContext: .loop) { b in
b.loopNestedContinue(Int.random(in: 0...10))
},

CodeGenerator("LoopNestedBreakGenerator", inContext: .loop) { b in
b.loopNestedBreak(Int.random(in: 0...10))
},

CodeGenerator("BlockNestedBreakGenerator", inContext: .codeBlock) { b in
b.blockNestedBreak(Int.random(in: 0...10))
},

CodeGenerator("IfNestedBreakGenerator", inContext: .ifBlock) { b in
b.ifNestedBreak(Int.random(in: 0...10))
},

CodeGenerator("TryNestedBreakGenerator", inContext: .tryBlock) { b in
b.tryNestedBreak(Int.random(in: 0...10))
},

CodeGenerator("SwitchNestedBreakGenerator", inContext: .switchBlock) { b in
b.switchNestedBreak(Int.random(in: 0...10))
},

CodeGenerator("WithNestedBreakGenerator", inContext: .with) { b in
b.withNestedBreak(Int.random(in: 0...10))
},
]

extension Array where Element == CodeGenerator {
Expand Down
6 changes: 6 additions & 0 deletions Sources/Fuzzilli/FuzzIL/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public struct Context: OptionSet {
public static let wasmFunction = Context(rawValue: 1 << 13)
// Inside a block of a wasm function, allows branches
public static let wasmBlock = Context(rawValue: 1 << 14)
// Inside a block
public static let codeBlock = Context(rawValue: 1 << 15)
// Inside a if|else block
public static let ifBlock = Context(rawValue: 1 << 16)
// Inside a try|catch block
public static let tryBlock = Context(rawValue: 1 << 17)

public static let empty = Context([])

Expand Down
28 changes: 28 additions & 0 deletions Sources/Fuzzilli/FuzzIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,20 @@ extension Instruction: ProtobufConvertible {
$0.wrapSuspending = Fuzzilli_Protobuf_WrapSuspending()
case .bindMethod(let op):
$0.bindMethod = Fuzzilli_Protobuf_BindMethod.with { $0.methodName = op.methodName }
case .loopNestedContinue:
$0.loopNestedContinue = Fuzzilli_Protobuf_LoopNestedContinue()
case .loopNestedBreak:
$0.loopNestedBreak = Fuzzilli_Protobuf_LoopNestedBreak()
case .blockNestedBreak:
$0.blockNestedBreak = Fuzzilli_Protobuf_BlockNestedBreak()
case .ifNestedBreak:
$0.ifNestedBreak = Fuzzilli_Protobuf_IfNestedBreak()
case .tryNestedBreak:
$0.tryNestedBreak = Fuzzilli_Protobuf_TryNestedBreak()
case .switchNestedBreak:
$0.switchNestedBreak = Fuzzilli_Protobuf_SwitchNestedBreak()
case .withNestedBreak:
$0.withNestedBreak = Fuzzilli_Protobuf_WithNestedBreak()
case .print(_):
fatalError("Print operations should not be serialized")
// Wasm Operations
Expand Down Expand Up @@ -1892,6 +1906,20 @@ extension Instruction: ProtobufConvertible {
op = LoadNewTarget()
case .nop:
op = Nop()
case .loopNestedContinue(let d):
op = LoopNestedContinue(d.depth)
case .loopNestedBreak(let d):
op = LoopNestedBreak(d.depth)
case .blockNestedBreak(let d):
op = BlockNestedBreak(d.depth)
case .ifNestedBreak(let d):
op = IfNestedBreak(d.depth)
case .tryNestedBreak(let d):
op = TryNestedBreak(d.depth)
case .switchNestedBreak(let d):
op = SwitchNestedBreak(d.depth)
case .withNestedBreak(let d):
op = WithNestedBreak(d.depth)
case .createWasmGlobal(let p):
op = CreateWasmGlobal(value: convertWasmGlobal(p.wasmGlobal), isMutable: p.wasmGlobal.isMutable)
case .createWasmMemory(let p):
Expand Down
86 changes: 79 additions & 7 deletions Sources/Fuzzilli/FuzzIL/JsOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1945,15 +1945,15 @@ final class BeginIf: JsOperation {

init(inverted: Bool) {
self.inverted = inverted
super.init(numInputs: 1, attributes: [.isBlockStart, .isMutable, .propagatesSurroundingContext], contextOpened: .javascript)
super.init(numInputs: 1, attributes: [.isBlockStart, .isMutable, .propagatesSurroundingContext], contextOpened: [.javascript, .ifBlock])
}
}

final class BeginElse: JsOperation {
override var opcode: Opcode { .beginElse(self) }

init() {
super.init(attributes: [.isBlockEnd, .isBlockStart, .propagatesSurroundingContext], contextOpened: .javascript)
super.init(attributes: [.isBlockEnd, .isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .ifBlock])
}
}

Expand Down Expand Up @@ -2234,29 +2234,29 @@ final class BeginTry: JsOperation {
override var opcode: Opcode { .beginTry(self) }

init() {
super.init(attributes: [.isBlockStart, .propagatesSurroundingContext])
super.init(attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .tryBlock])
}
}

final class BeginCatch: JsOperation {
override var opcode: Opcode { .beginCatch(self) }

init() {
super.init(numInnerOutputs: 1, attributes: [.isBlockStart, .isBlockEnd, .propagatesSurroundingContext])
super.init(numInnerOutputs: 1, attributes: [.isBlockStart, .isBlockEnd, .propagatesSurroundingContext], contextOpened: [.javascript, .tryBlock])
}
}

final class BeginFinally: JsOperation {
override var opcode: Opcode { .beginFinally(self) }

init() {
super.init(attributes: [.isBlockStart, .isBlockEnd, .propagatesSurroundingContext])
super.init(attributes: [.isBlockStart, .isBlockEnd, .propagatesSurroundingContext], contextOpened: [.javascript, .tryBlock])
}
}

final class EndTryCatchFinally: JsOperation {
override var opcode: Opcode { .endTryCatchFinally(self) }

init() {
super.init(attributes: [.isBlockEnd])
}
Expand Down Expand Up @@ -2292,7 +2292,7 @@ final class BeginBlockStatement: JsOperation {
override var opcode: Opcode { .beginBlockStatement(self) }

init() {
super.init(attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: .javascript)
super.init(attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .codeBlock])
}
}

Expand Down Expand Up @@ -2464,6 +2464,78 @@ class BindMethod: JsOperation {
}
}

final class LoopNestedContinue: JsOperation {
override var opcode: Opcode { .loopNestedContinue(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .loop])
}
}

final class LoopNestedBreak: JsOperation {
override var opcode: Opcode { .loopNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .loop])
}
}
final class BlockNestedBreak: JsOperation {
override var opcode: Opcode { .blockNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .codeBlock])
}
}
final class IfNestedBreak: JsOperation {
override var opcode: Opcode { .ifNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .ifBlock])
}
}
final class TryNestedBreak: JsOperation {
override var opcode: Opcode { .tryNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .tryBlock])
}
}
final class SwitchNestedBreak: JsOperation {
override var opcode: Opcode { .switchNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .switchCase])
}
}
final class WithNestedBreak: JsOperation {
override var opcode: Opcode { .withNestedBreak(self) }

let depth: Int

init(_ depth: Int) {
self.depth = depth
super.init(attributes: [.isJump], requiredContext: [.javascript, .with])
}
}


// This instruction is used to create strongly typed WasmGlobals in the JS world that can be imported by a WasmModule.
class CreateWasmGlobal: JsOperation {
Expand Down
7 changes: 7 additions & 0 deletions Sources/Fuzzilli/FuzzIL/Opcodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ enum Opcode {
case endSwitch(EndSwitch)
case switchBreak(SwitchBreak)
case loadNewTarget(LoadNewTarget)
case loopNestedContinue(LoopNestedContinue)
case loopNestedBreak(LoopNestedBreak)
case blockNestedBreak(BlockNestedBreak)
case ifNestedBreak(IfNestedBreak)
case tryNestedBreak(TryNestedBreak)
case switchNestedBreak(SwitchNestedBreak)
case withNestedBreak(WithNestedBreak)
case print(Print)
case explore(Explore)
case probe(Probe)
Expand Down
21 changes: 21 additions & 0 deletions Sources/Fuzzilli/Lifting/FuzzILLifter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,27 @@ public class FuzzILLifter: Lifter {
case .loadNewTarget:
w.emit("\(output()) <- LoadNewTarget")

case .loopNestedContinue(let op):
w.emit("LoopNestedContinue \(op.depth)")

case .loopNestedBreak(let op):
w.emit("LoopNestedBreak \(op.depth)")

case .blockNestedBreak(let op):
w.emit("BlockNestedBreak \(op.depth)")

case .ifNestedBreak(let op):
w.emit("IfNestedBreak \(op.depth)")

case .tryNestedBreak(let op):
w.emit("TryNestedBreak \(op.depth)")

case .switchNestedBreak(let op):
w.emit("SwitchNestedBreak \(op.depth)")

case .withNestedBreak(let op):
w.emit("WithNestedBreak \(op.depth)")

case .beginWasmModule:
w.emit("BeginWasmModule")
w.increaseIndentionLevel()
Expand Down
Loading