diff --git a/Sources/Fuzzilli/Base/ProgramBuilder.swift b/Sources/Fuzzilli/Base/ProgramBuilder.swift index 9b8b380e..9c9745f3 100644 --- a/Sources/Fuzzilli/Base/ProgramBuilder.swift +++ b/Sources/Fuzzilli/Base/ProgramBuilder.swift @@ -2493,19 +2493,31 @@ public class ProgramBuilder { emit(EndForLoop()) } - public func buildForInLoop(_ obj: Variable, _ body: (Variable) -> ()) { - let i = emit(BeginForInLoop(), withInputs: [obj]).innerOutput + public func buildPlainForInLoop(_ obj: Variable, _ body: (Variable) -> ()) { + let i = emit(BeginPlainForInLoop(), withInputs: [obj]).innerOutput body(i) emit(EndForInLoop()) } - public func buildForOfLoop(_ obj: Variable, _ body: (Variable) -> ()) { - let i = emit(BeginForOfLoop(), withInputs: [obj]).innerOutput + public func buildForInLoopWithReassignment(_ obj: Variable, _ existingVar: Variable, _ body: () -> ()) { + emit(BeginForInLoopWithReassignment(), withInputs: [obj, existingVar]) + body() + emit(EndForInLoop()) + } + + public func buildPlainForOfLoop(_ obj: Variable, _ body: (Variable) -> ()) { + let i = emit(BeginPlainForOfLoop(), withInputs: [obj]).innerOutput body(i) emit(EndForOfLoop()) } - public func buildForOfLoop(_ obj: Variable, selecting indices: [Int64], hasRestElement: Bool = false, _ body: ([Variable]) -> ()) { + public func buildForOfLoopWithReassignment(_ obj: Variable, _ existingVar: Variable, _ body: () -> ()) { + emit(BeginForOfLoopWithReassignment(), withInputs: [obj, existingVar]) + body() + emit(EndForOfLoop()) + } + + public func buildForOfLoopWithDestruct(_ obj: Variable, selecting indices: [Int64], hasRestElement: Bool = false, _ body: ([Variable]) -> ()) { let instr = emit(BeginForOfLoopWithDestruct(indices: indices, hasRestElement: hasRestElement), withInputs: [obj]) body(Array(instr.innerOutputs)) emit(EndForOfLoop()) diff --git a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift index 4c8d809c..75b2953a 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift @@ -158,8 +158,10 @@ public let codeGeneratorWeights = [ "DoWhileLoopGenerator": 15, "SimpleForLoopGenerator": 10, "ComplexForLoopGenerator": 10, - "ForInLoopGenerator": 10, - "ForOfLoopGenerator": 10, + "PlainForInLoopGenerator": 8, + "ForInLoopWithReassignmentGenerator": 2, + "PlainForOfLoopGenerator": 8, + "ForOfLoopWithReassignmentGenerator": 2, "ForOfWithDestructLoopGenerator": 3, "RepeatLoopGenerator": 10, "SwitchCaseBreakGenerator": 5, diff --git a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift index 1d016749..4353fe32 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift @@ -1370,14 +1370,29 @@ public let CodeGenerators: [CodeGenerator] = [ } }, - RecursiveCodeGenerator("ForInLoopGenerator", inputs: .preferred(.object())) { b, obj in - b.buildForInLoop(obj) { _ in + RecursiveCodeGenerator("PlainForInLoopGenerator", inputs: .preferred(.object())) { b, obj in + b.buildPlainForInLoop(obj) { _ in b.buildRecursive() } }, - RecursiveCodeGenerator("ForOfLoopGenerator", inputs: .preferred(.iterable)) { b, obj in - b.buildForOfLoop(obj) { _ in + RecursiveCodeGenerator("ForInLoopWithReassignmentGenerator", inputs: .preferred(.object())) { b, obj in + // use a pre-declared variable as the iterator variable (i.e., reassign it) + let existing = b.randomVariable() + b.buildForInLoopWithReassignment(obj, existing) { + b.buildRecursive() + } + }, + + RecursiveCodeGenerator("PlainForOfLoopGenerator", inputs: .preferred(.iterable)) { b, obj in + b.buildPlainForOfLoop(obj) { _ in + b.buildRecursive() + } + }, + + RecursiveCodeGenerator("ForOfLoopWithReassignmentGenerator", inputs: .preferred(.iterable)) { b, obj in + let existing = b.randomVariable() + b.buildForOfLoopWithReassignment(obj, existing) { b.buildRecursive() } }, @@ -1394,7 +1409,7 @@ public let CodeGenerators: [CodeGenerator] = [ indices = [0] } - b.buildForOfLoop(obj, selecting: indices, hasRestElement: probability(0.2)) { _ in + b.buildForOfLoopWithDestruct(obj, selecting: indices, hasRestElement: probability(0.2)) { _ in b.buildRecursive() } }, diff --git a/Sources/Fuzzilli/Compiler/Compiler.swift b/Sources/Fuzzilli/Compiler/Compiler.swift index b67142a1..0224dea0 100644 --- a/Sources/Fuzzilli/Compiler/Compiler.swift +++ b/Sources/Fuzzilli/Compiler/Compiler.swift @@ -412,36 +412,69 @@ public class JavaScriptCompiler { } case .forInLoop(let forInLoop): - let initializer = forInLoop.left; - guard !initializer.hasValue else { - throw CompilerError.invalidNodeError("Expected no initial value for the variable declared in a for-in loop") - } - + let initializer = forInLoop.left! let obj = try compileExpression(forInLoop.right) + // Processing a for-in or for-of loop requires an iterator, which is typically declared in the function header. + // Alternatively, an existing variable can be used, resulting in an identifier instead of a variable declarator. + // If the identifier is not previously declared, it is implicitly created as a global variable. + + switch initializer { + case .variableDeclarator(let variableDeclarator): + guard !variableDeclarator.hasValue else { + throw CompilerError.invalidNodeError("Expected no initial value for the variable declared in a for-in loop") + } + let loopVar = emit(BeginPlainForInLoop(), withInputs: [obj]).innerOutput + try enterNewScope { + map(variableDeclarator.name, to: loopVar) + try compileBody(forInLoop.body) + } + emit(EndForInLoop()) - let loopVar = emit(BeginForInLoop(), withInputs: [obj]).innerOutput - try enterNewScope { - map(initializer.name, to: loopVar) - try compileBody(forInLoop.body) + case .identifier(let identifier): + let loopVar: Variable + if let existingVar = lookupIdentifier(identifier.name) { + loopVar = existingVar + } else { + loopVar = emit(LoadNamedVariable(identifier.name)).output + map(identifier.name, to: loopVar) + } + emit(BeginForInLoopWithReassignment(), withInputs: [obj, loopVar]) + try enterNewScope { + try compileBody(forInLoop.body) + } + emit(EndForInLoop()) } - emit(EndForInLoop()) - case .forOfLoop(let forOfLoop): - let initializer = forOfLoop.left; - guard !initializer.hasValue else { - throw CompilerError.invalidNodeError("Expected no initial value for the variable declared in a for-of loop") - } - + let initializer = forOfLoop.left! let obj = try compileExpression(forOfLoop.right) - let loopVar = emit(BeginForOfLoop(), withInputs: [obj]).innerOutput - try enterNewScope { - map(initializer.name, to: loopVar) - try compileBody(forOfLoop.body) - } + switch initializer { + case .variableDeclarator(let variableDeclarator): + guard !variableDeclarator.hasValue else { + throw CompilerError.invalidNodeError("Expected no initial value for the variable declared in a for-of loop") + } + let loopVar = emit(BeginPlainForOfLoop(), withInputs: [obj]).innerOutput + try enterNewScope { + map(variableDeclarator.name, to: loopVar) + try compileBody(forOfLoop.body) + } + emit(EndForOfLoop()) - emit(EndForOfLoop()) + case .identifier(let identifier): + let loopVar: Variable + if let existingVar = lookupIdentifier(identifier.name) { + loopVar = existingVar + } else { + loopVar = emit(LoadNamedVariable(identifier.name)).output + map(identifier.name, to: loopVar) + } + emit(BeginForOfLoopWithReassignment(), withInputs: [obj, loopVar]) + try enterNewScope { + try compileBody(forOfLoop.body) + } + emit(EndForOfLoop()) + } case .breakStatement: // If we're in both .loop and .switch context, then the loop must be the most recent context diff --git a/Sources/Fuzzilli/Compiler/Parser/parser.js b/Sources/Fuzzilli/Compiler/Parser/parser.js index 237ed9b1..fd7f9b76 100644 --- a/Sources/Fuzzilli/Compiler/Parser/parser.js +++ b/Sources/Fuzzilli/Compiler/Parser/parser.js @@ -267,25 +267,35 @@ function parse(script, proto) { return makeStatement('ForLoop', forLoop); } case 'ForInStatement': { - assert(node.left.type === 'VariableDeclaration', "Expected variable declaration as init part of a for-in loop, found " + node.left.type); - assert(node.left.declarations.length === 1, "Expected exactly one variable declaration in the init part of a for-in loop"); - let decl = node.left.declarations[0]; let forInLoop = {}; - let initDecl = { name: decl.id.name }; - assert(decl.init == null, "Expected no initial value for the variable declared as part of a for-in loop") - forInLoop.left = make('VariableDeclarator', initDecl); + if (node.left.type === 'VariableDeclaration') { + assert(node.left.declarations.length === 1, "Expected exactly one variable declaration in the init part of a for-in loop"); + let decl = node.left.declarations[0]; + let initDecl = { name: decl.id.name }; + assert(decl.init == null, "Expected no initial value for the variable declared as part of a for-in loop") + forInLoop.variableDeclarator = make('VariableDeclarator', initDecl); + } else if (node.left.type === 'Identifier') { + forOfLoop.identifier = make('Identifier', { name: node.left.name }); + } else { + throw "Unsupported left side of for-in loop: " + node.left.type; + } forInLoop.right = visitExpression(node.right); forInLoop.body = visitStatement(node.body); return makeStatement('ForInLoop', forInLoop); } case 'ForOfStatement': { - assert(node.left.type === 'VariableDeclaration', "Expected variable declaration as init part of a for-in loop, found " + node.left.type); - assert(node.left.declarations.length === 1, "Expected exactly one variable declaration in the init part of a for-in loop"); - let decl = node.left.declarations[0]; let forOfLoop = {}; - let initDecl = { name: decl.id.name }; - assert(decl.init == null, "Expected no initial value for the variable declared as part of a for-in loop") - forOfLoop.left = make('VariableDeclarator', initDecl); + if (node.left.type === 'VariableDeclaration') { + assert(node.left.declarations.length === 1, "Expected exactly one variable declaration in the init part of a for-of loop"); + let decl = node.left.declarations[0]; + let initDecl = { name: decl.id.name }; + assert(decl.init == null, "Expected no initial value for the variable declared as part of a for-of loop") + forOfLoop.variableDeclarator = make('VariableDeclarator', initDecl); + } else if (node.left.type === 'Identifier') { + forOfLoop.identifier = make('Identifier', { name: node.left.name }); + } else { + throw "Unsupported left side of for-of loop: " + node.left.type; + } forOfLoop.right = visitExpression(node.right); forOfLoop.body = visitStatement(node.body); return makeStatement('ForOfLoop', forOfLoop); diff --git a/Sources/Fuzzilli/FuzzIL/Instruction.swift b/Sources/Fuzzilli/FuzzIL/Instruction.swift index 4ba5c279..cd55e3d8 100644 --- a/Sources/Fuzzilli/FuzzIL/Instruction.swift +++ b/Sources/Fuzzilli/FuzzIL/Instruction.swift @@ -792,12 +792,16 @@ extension Instruction: ProtobufConvertible { $0.beginForLoopBody = Fuzzilli_Protobuf_BeginForLoopBody() case .endForLoop: $0.endForLoop = Fuzzilli_Protobuf_EndForLoop() - case .beginForInLoop: - $0.beginForInLoop = Fuzzilli_Protobuf_BeginForInLoop() + case .beginPlainForInLoop: + $0.beginPlainForInLoop = Fuzzilli_Protobuf_BeginPlainForInLoop() + case .beginForInLoopWithReassignment: + $0.beginForInLoopWithReassignment = Fuzzilli_Protobuf_BeginForInLoopWithReassignment() case .endForInLoop: $0.endForInLoop = Fuzzilli_Protobuf_EndForInLoop() - case .beginForOfLoop: - $0.beginForOfLoop = Fuzzilli_Protobuf_BeginForOfLoop() + case .beginPlainForOfLoop: + $0.beginPlainForOfLoop = Fuzzilli_Protobuf_BeginPlainForOfLoop() + case .beginForOfLoopWithReassignment: + $0.beginForOfLoopWithReassignment = Fuzzilli_Protobuf_BeginForOfLoopWithReassignment() case .beginForOfLoopWithDestruct(let op): $0.beginForOfLoopWithDestruct = Fuzzilli_Protobuf_BeginForOfLoopWithDestruct.with { $0.indices = op.indices.map({ Int32($0) }) @@ -1216,14 +1220,21 @@ extension Instruction: ProtobufConvertible { op = BeginForLoopBody(numLoopVariables: inouts.count) case .endForLoop: op = EndForLoop() - case .beginForInLoop: - op = BeginForInLoop() + case .beginPlainForInLoop: + op = BeginPlainForInLoop() + case .beginForInLoopWithReassignment: + op = BeginForInLoopWithReassignment() case .endForInLoop: op = EndForInLoop() - case .beginForOfLoop: - op = BeginForOfLoop() + case .beginPlainForOfLoop: + op = BeginPlainForOfLoop() + case .beginForOfLoopWithReassignment: + op = BeginForOfLoopWithReassignment() case .beginForOfLoopWithDestruct(let p): - op = BeginForOfLoopWithDestruct(indices: p.indices.map({ Int64($0) }), hasRestElement: p.hasRestElement_p) + op = BeginForOfLoopWithDestruct( + indices: p.indices.map({ Int64($0) }), + hasRestElement: p.hasRestElement_p + ) case .endForOfLoop: op = EndForOfLoop() case .beginRepeatLoop(let p): diff --git a/Sources/Fuzzilli/FuzzIL/JSTyper.swift b/Sources/Fuzzilli/FuzzIL/JSTyper.swift index a21d9b4f..466d0862 100644 --- a/Sources/Fuzzilli/FuzzIL/JSTyper.swift +++ b/Sources/Fuzzilli/FuzzIL/JSTyper.swift @@ -283,8 +283,10 @@ public struct JSTyper: Analyzer { case .endForLoop: state.endGroupOfConditionallyExecutingBlocks(typeChanges: &typeChanges) case .beginWhileLoopBody, - .beginForInLoop, - .beginForOfLoop, + .beginPlainForInLoop, + .beginForInLoopWithReassignment, + .beginPlainForOfLoop, + .beginForOfLoopWithReassignment, .beginForOfLoopWithDestruct, .beginRepeatLoop, .beginCodeString: @@ -797,12 +799,18 @@ public struct JSTyper: Analyzer { assert(inputTypes.count == instr.numInnerOutputs) zip(instr.innerOutputs, inputTypes).forEach({ set($0, $1) }) - case .beginForInLoop: + case .beginPlainForInLoop: set(instr.innerOutput, .string) - case .beginForOfLoop: + case .beginForInLoopWithReassignment: + set(instr.input(1), .string) + + case .beginPlainForOfLoop: set(instr.innerOutput, .anything) + case .beginForOfLoopWithReassignment: + set(instr.input(1), .anything) + case .beginForOfLoopWithDestruct: for v in instr.innerOutputs { set(v, .anything) diff --git a/Sources/Fuzzilli/FuzzIL/JsOperations.swift b/Sources/Fuzzilli/FuzzIL/JsOperations.swift index 5905a9e1..90d842da 100644 --- a/Sources/Fuzzilli/FuzzIL/JsOperations.swift +++ b/Sources/Fuzzilli/FuzzIL/JsOperations.swift @@ -1974,14 +1974,20 @@ final class EndForLoop: JsOperation { } } -final class BeginForInLoop: JsOperation { - override var opcode: Opcode { .beginForInLoop(self) } - +final class BeginPlainForInLoop: JsOperation { + override var opcode: Opcode { .beginPlainForInLoop(self) } init() { super.init(numInputs: 1, numInnerOutputs: 1, attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .loop]) } } +final class BeginForInLoopWithReassignment: JsOperation { + override var opcode: Opcode { .beginForInLoopWithReassignment(self) } + init() { + super.init(numInputs: 2, numInnerOutputs: 0, attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .loop]) + } +} + final class EndForInLoop: JsOperation { override var opcode: Opcode { .endForInLoop(self) } @@ -1989,15 +1995,21 @@ final class EndForInLoop: JsOperation { super.init(attributes: .isBlockEnd) } } - -final class BeginForOfLoop: JsOperation { - override var opcode: Opcode { .beginForOfLoop(self) } - +// TODO: Support even more types of for loops, e.g.: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of#examples +final class BeginPlainForOfLoop: JsOperation { + override var opcode: Opcode { .beginPlainForOfLoop(self) } init() { super.init(numInputs: 1, numInnerOutputs: 1, attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .loop]) } } +final class BeginForOfLoopWithReassignment: JsOperation { + override var opcode: Opcode { .beginForOfLoopWithReassignment(self) } + init() { + super.init(numInputs: 2, numInnerOutputs: 0, attributes: [.isBlockStart, .propagatesSurroundingContext], contextOpened: [.javascript, .loop]) + } +} + final class BeginForOfLoopWithDestruct: JsOperation { override var opcode: Opcode { .beginForOfLoopWithDestruct(self) } diff --git a/Sources/Fuzzilli/FuzzIL/Opcodes.swift b/Sources/Fuzzilli/FuzzIL/Opcodes.swift index 8f376ea0..cb417578 100644 --- a/Sources/Fuzzilli/FuzzIL/Opcodes.swift +++ b/Sources/Fuzzilli/FuzzIL/Opcodes.swift @@ -177,9 +177,11 @@ enum Opcode { case beginForLoopAfterthought(BeginForLoopAfterthought) case beginForLoopBody(BeginForLoopBody) case endForLoop(EndForLoop) - case beginForInLoop(BeginForInLoop) + case beginPlainForInLoop(BeginPlainForInLoop) + case beginForInLoopWithReassignment(BeginForInLoopWithReassignment) case endForInLoop(EndForInLoop) - case beginForOfLoop(BeginForOfLoop) + case beginPlainForOfLoop(BeginPlainForOfLoop) + case beginForOfLoopWithReassignment(BeginForOfLoopWithReassignment) case beginForOfLoopWithDestruct(BeginForOfLoopWithDestruct) case endForOfLoop(EndForOfLoop) case beginRepeatLoop(BeginRepeatLoop) diff --git a/Sources/Fuzzilli/FuzzIL/Semantics.swift b/Sources/Fuzzilli/FuzzIL/Semantics.swift index e8110e02..e869ee00 100644 --- a/Sources/Fuzzilli/FuzzIL/Semantics.swift +++ b/Sources/Fuzzilli/FuzzIL/Semantics.swift @@ -54,6 +54,10 @@ extension Operation { case .destructArrayAndReassign, .destructObjectAndReassign: return inputIdx != 0 + case .beginForInLoopWithReassignment: + return inputIdx == 1 + case .beginForOfLoopWithReassignment: + return inputIdx == 1 default: return false } @@ -206,9 +210,11 @@ extension Operation { return endOp is BeginForLoopBody case .beginForLoopBody: return endOp is EndForLoop - case .beginForInLoop: + case .beginPlainForInLoop, + .beginForInLoopWithReassignment: return endOp is EndForInLoop - case .beginForOfLoop, + case .beginPlainForOfLoop, + .beginForOfLoopWithReassignment, .beginForOfLoopWithDestruct: return endOp is EndForOfLoop case .beginRepeatLoop: diff --git a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift index 8bfe3507..8edf396e 100644 --- a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift +++ b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift @@ -669,16 +669,24 @@ public class FuzzILLifter: Lifter { w.decreaseIndentionLevel() w.emit("EndForLoop") - case .beginForInLoop: - w.emit("BeginForInLoop \(input(0)) -> \(innerOutput())") + case .beginPlainForInLoop: + w.emit("BeginPlainForInLoop \(input(0)) -> \(innerOutput())") + w.increaseIndentionLevel() + + case .beginForInLoopWithReassignment: + w.emit("BeginForInLoopWithReassignment \(input(0)) -> \(input(1))") w.increaseIndentionLevel() case .endForInLoop: w.decreaseIndentionLevel() w.emit("EndForInLoop") - case .beginForOfLoop: - w.emit("BeginForOfLoop \(input(0)) -> \(innerOutput())") + case .beginPlainForOfLoop: + w.emit("BeginPlainForOfLoop \(input(0)) -> \(innerOutput())") + w.increaseIndentionLevel() + + case .beginForOfLoopWithReassignment: + w.emit("BeginForOfLoopWithReassignment \(input(0)) -> \(input(1))") w.increaseIndentionLevel() case .beginForOfLoopWithDestruct(let op): diff --git a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift index b7de0815..e70c5386 100644 --- a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift +++ b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift @@ -886,7 +886,7 @@ public class JavaScriptLifter: Lifter { w.assign(expr, to: instr.output) case .loadNamedVariable(let op): - w.assign(Identifier.new(op.variableName), to: instr.output) + w.assign(Identifier.new(op.variableName), to: instr.output, forceInlining: true) case .storeNamedVariable(let op): let NAME = op.variableName @@ -1172,24 +1172,36 @@ public class JavaScriptLifter: Lifter { w.leaveCurrentBlock() w.emit("}") - case .beginForInLoop: - let LET = w.declarationKeyword(for: instr.innerOutput) - let V = w.declare(instr.innerOutput) + case .beginPlainForInLoop: let OBJ = input(0) + let V = w.declare(instr.innerOutput) + let LET = w.declarationKeyword(for: instr.innerOutput) w.emit("for (\(LET) \(V) in \(OBJ)) {") w.enterNewBlock() + case .beginForInLoopWithReassignment: + let OBJ = input(0) + let V = input(1) + w.emit("for (\(V) in \(OBJ)) {") + w.enterNewBlock() + case .endForInLoop: w.leaveCurrentBlock() w.emit("}") - case .beginForOfLoop: + case .beginPlainForOfLoop: + let OBJ = input(0) let V = w.declare(instr.innerOutput) let LET = w.declarationKeyword(for: instr.innerOutput) - let OBJ = input(0) w.emit("for (\(LET) \(V) of \(OBJ)) {") w.enterNewBlock() + case .beginForOfLoopWithReassignment: + let OBJ = input(0) + let V = input(1) + w.emit("for (\(V) of \(OBJ)) {") + w.enterNewBlock() + case .beginForOfLoopWithDestruct(let op): let outputs = w.declareAll(instr.innerOutputs) let PATTERN = liftArrayDestructPattern(indices: op.indices, outputs: outputs, hasRestElement: op.hasRestElement) @@ -1540,13 +1552,13 @@ public class JavaScriptLifter: Lifter { /// /// If the expression can be inlined, it will be associated with the variable and returned at its use. If the expression cannot be inlined, /// the expression will be emitted either as part of a variable definition or as an expression statement (if the value isn't subsequently used). - mutating func assign(_ expr: Expression, to v: Variable, allowInlining: Bool = true) { + mutating func assign(_ expr: Expression, to v: Variable, allowInlining: Bool = true, forceInlining: Bool = false) { if let V = expressions[v] { // In some situations, for example in the case of guarded operations that require a try-catch around them, // the output variable is declared up-front and so we lift to a variable assignment. assert(V.type === Identifier) emit("\(V) = \(expr);") - } else if allowInlining && shouldTryInlining(expr, producing: v) { + } else if allowInlining && shouldTryInlining(expr, producing: v) || forceInlining { expressions[v] = expr // If this is an effectful expression, it must be the next expression to be evaluated. To ensure that, we // keep a list of all "pending" effectful expressions, which must be executed in FIFO order. diff --git a/Sources/Fuzzilli/Minimization/BlockReducer.swift b/Sources/Fuzzilli/Minimization/BlockReducer.swift index 9d00f839..c4cac2ca 100644 --- a/Sources/Fuzzilli/Minimization/BlockReducer.swift +++ b/Sources/Fuzzilli/Minimization/BlockReducer.swift @@ -51,8 +51,10 @@ struct BlockReducer: Reducer { case .beginWhileLoopHeader, .beginDoWhileLoopBody, .beginForLoopInitializer, - .beginForInLoop, - .beginForOfLoop, + .beginPlainForInLoop, + .beginForInLoopWithReassignment, + .beginPlainForOfLoop, + .beginForOfLoopWithReassignment, .beginForOfLoopWithDestruct, .beginRepeatLoop: reduceLoop(group, with: helper) diff --git a/Sources/Fuzzilli/Minimization/LoopReducer.swift b/Sources/Fuzzilli/Minimization/LoopReducer.swift index 30cf2add..d48efa1e 100644 --- a/Sources/Fuzzilli/Minimization/LoopReducer.swift +++ b/Sources/Fuzzilli/Minimization/LoopReducer.swift @@ -40,9 +40,11 @@ struct LoopReducer: Reducer { tryReplaceDoWhileLoopWithRepeatLoop(group, with: helper) case .beginRepeatLoop: tryReduceRepeatLoopIterationCount(group, with: helper) - case .beginForInLoop, - .beginForOfLoop, - .beginForOfLoopWithDestruct: + case .beginPlainForInLoop, + .beginForInLoopWithReassignment, + .beginPlainForOfLoop, + .beginForOfLoopWithReassignment, + .beginForOfLoopWithDestruct: // These loops are (usually) guaranteed to terminate, and should probably anyway not be replaced by repeat-loops. break default: diff --git a/Sources/Fuzzilli/Protobuf/ast.pb.swift b/Sources/Fuzzilli/Protobuf/ast.pb.swift index a71e2b36..04027268 100644 --- a/Sources/Fuzzilli/Protobuf/ast.pb.swift +++ b/Sources/Fuzzilli/Protobuf/ast.pb.swift @@ -690,14 +690,26 @@ public struct Compiler_Protobuf_ForInLoop: @unchecked Sendable { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - public var left: Compiler_Protobuf_VariableDeclarator { - get {return _storage._left ?? Compiler_Protobuf_VariableDeclarator()} + public var left: OneOf_Left? { + get {return _storage._left} set {_uniqueStorage()._left = newValue} } - /// Returns true if `left` has been explicitly set. - public var hasLeft: Bool {return _storage._left != nil} - /// Clears the value of `left`. Subsequent reads from it will return its default value. - public mutating func clearLeft() {_uniqueStorage()._left = nil} + + public var variableDeclarator: Compiler_Protobuf_VariableDeclarator { + get { + if case .variableDeclarator(let v)? = _storage._left {return v} + return Compiler_Protobuf_VariableDeclarator() + } + set {_uniqueStorage()._left = .variableDeclarator(newValue)} + } + + public var identifier: Compiler_Protobuf_Identifier { + get { + if case .identifier(let v)? = _storage._left {return v} + return Compiler_Protobuf_Identifier() + } + set {_uniqueStorage()._left = .identifier(newValue)} + } public var right: Compiler_Protobuf_Expression { get {return _storage._right ?? Compiler_Protobuf_Expression()} @@ -719,6 +731,12 @@ public struct Compiler_Protobuf_ForInLoop: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() + public enum OneOf_Left: Equatable, Sendable { + case variableDeclarator(Compiler_Protobuf_VariableDeclarator) + case identifier(Compiler_Protobuf_Identifier) + + } + public init() {} fileprivate var _storage = _StorageClass.defaultInstance @@ -729,14 +747,26 @@ public struct Compiler_Protobuf_ForOfLoop: @unchecked Sendable { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - public var left: Compiler_Protobuf_VariableDeclarator { - get {return _storage._left ?? Compiler_Protobuf_VariableDeclarator()} + public var left: OneOf_Left? { + get {return _storage._left} set {_uniqueStorage()._left = newValue} } - /// Returns true if `left` has been explicitly set. - public var hasLeft: Bool {return _storage._left != nil} - /// Clears the value of `left`. Subsequent reads from it will return its default value. - public mutating func clearLeft() {_uniqueStorage()._left = nil} + + public var variableDeclarator: Compiler_Protobuf_VariableDeclarator { + get { + if case .variableDeclarator(let v)? = _storage._left {return v} + return Compiler_Protobuf_VariableDeclarator() + } + set {_uniqueStorage()._left = .variableDeclarator(newValue)} + } + + public var identifier: Compiler_Protobuf_Identifier { + get { + if case .identifier(let v)? = _storage._left {return v} + return Compiler_Protobuf_Identifier() + } + set {_uniqueStorage()._left = .identifier(newValue)} + } public var right: Compiler_Protobuf_Expression { get {return _storage._right ?? Compiler_Protobuf_Expression()} @@ -758,6 +788,12 @@ public struct Compiler_Protobuf_ForOfLoop: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() + public enum OneOf_Left: Equatable, Sendable { + case variableDeclarator(Compiler_Protobuf_VariableDeclarator) + case identifier(Compiler_Protobuf_Identifier) + + } + public init() {} fileprivate var _storage = _StorageClass.defaultInstance @@ -3684,13 +3720,14 @@ extension Compiler_Protobuf_ForLoop: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Compiler_Protobuf_ForInLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ForInLoop" public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "left"), - 2: .same(proto: "right"), - 3: .same(proto: "body"), + 1: .same(proto: "variableDeclarator"), + 2: .same(proto: "identifier"), + 3: .same(proto: "right"), + 4: .same(proto: "body"), ] fileprivate class _StorageClass { - var _left: Compiler_Protobuf_VariableDeclarator? = nil + var _left: Compiler_Protobuf_ForInLoop.OneOf_Left? var _right: Compiler_Protobuf_Expression? = nil var _body: Compiler_Protobuf_Statement? = nil @@ -3728,9 +3765,34 @@ extension Compiler_Protobuf_ForInLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes // allocates stack space for every case branch when no optimizations are // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &_storage._left) }() - case 2: try { try decoder.decodeSingularMessageField(value: &_storage._right) }() - case 3: try { try decoder.decodeSingularMessageField(value: &_storage._body) }() + case 1: try { + var v: Compiler_Protobuf_VariableDeclarator? + var hadOneofValue = false + if let current = _storage._left { + hadOneofValue = true + if case .variableDeclarator(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._left = .variableDeclarator(v) + } + }() + case 2: try { + var v: Compiler_Protobuf_Identifier? + var hadOneofValue = false + if let current = _storage._left { + hadOneofValue = true + if case .identifier(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._left = .identifier(v) + } + }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._right) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._body) }() default: break } } @@ -3743,14 +3805,22 @@ extension Compiler_Protobuf_ForInLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes // allocates stack space for every if/case branch local when no optimizations // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._left { + switch _storage._left { + case .variableDeclarator?: try { + guard case .variableDeclarator(let v)? = _storage._left else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._right { + }() + case .identifier?: try { + guard case .identifier(let v)? = _storage._left else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case nil: break + } + try { if let v = _storage._right { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() try { if let v = _storage._body { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) } }() } try unknownFields.traverse(visitor: &visitor) @@ -3776,13 +3846,14 @@ extension Compiler_Protobuf_ForInLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes extension Compiler_Protobuf_ForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ForOfLoop" public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "left"), - 2: .same(proto: "right"), - 3: .same(proto: "body"), + 1: .same(proto: "variableDeclarator"), + 2: .same(proto: "identifier"), + 3: .same(proto: "right"), + 4: .same(proto: "body"), ] fileprivate class _StorageClass { - var _left: Compiler_Protobuf_VariableDeclarator? = nil + var _left: Compiler_Protobuf_ForOfLoop.OneOf_Left? var _right: Compiler_Protobuf_Expression? = nil var _body: Compiler_Protobuf_Statement? = nil @@ -3820,9 +3891,34 @@ extension Compiler_Protobuf_ForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes // allocates stack space for every case branch when no optimizations are // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &_storage._left) }() - case 2: try { try decoder.decodeSingularMessageField(value: &_storage._right) }() - case 3: try { try decoder.decodeSingularMessageField(value: &_storage._body) }() + case 1: try { + var v: Compiler_Protobuf_VariableDeclarator? + var hadOneofValue = false + if let current = _storage._left { + hadOneofValue = true + if case .variableDeclarator(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._left = .variableDeclarator(v) + } + }() + case 2: try { + var v: Compiler_Protobuf_Identifier? + var hadOneofValue = false + if let current = _storage._left { + hadOneofValue = true + if case .identifier(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._left = .identifier(v) + } + }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._right) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._body) }() default: break } } @@ -3835,14 +3931,22 @@ extension Compiler_Protobuf_ForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes // allocates stack space for every if/case branch local when no optimizations // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._left { + switch _storage._left { + case .variableDeclarator?: try { + guard case .variableDeclarator(let v)? = _storage._left else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._right { + }() + case .identifier?: try { + guard case .identifier(let v)? = _storage._left else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case nil: break + } + try { if let v = _storage._right { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() try { if let v = _storage._body { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) } }() } try unknownFields.traverse(visitor: &visitor) diff --git a/Sources/Fuzzilli/Protobuf/ast.proto b/Sources/Fuzzilli/Protobuf/ast.proto index c34af1e0..068ef1d9 100644 --- a/Sources/Fuzzilli/Protobuf/ast.proto +++ b/Sources/Fuzzilli/Protobuf/ast.proto @@ -163,15 +163,21 @@ message ForLoop { } message ForInLoop { - VariableDeclarator left = 1; - Expression right = 2; - Statement body = 3; + oneof left { + VariableDeclarator variableDeclarator = 1; + Identifier identifier = 2; + } + Expression right = 3; + Statement body = 4; } message ForOfLoop { - VariableDeclarator left = 1; - Expression right = 2; - Statement body = 3; + oneof left { + VariableDeclarator variableDeclarator = 1; + Identifier identifier = 2; + } + Expression right = 3; + Statement body = 4; } message BreakStatement { diff --git a/Sources/Fuzzilli/Protobuf/operations.pb.swift b/Sources/Fuzzilli/Protobuf/operations.pb.swift index 8a0cc83b..4aefd2c6 100644 --- a/Sources/Fuzzilli/Protobuf/operations.pb.swift +++ b/Sources/Fuzzilli/Protobuf/operations.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: operations.proto @@ -22,6 +21,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -2279,7 +2279,17 @@ public struct Fuzzilli_Protobuf_EndForLoop: Sendable { public init() {} } -public struct Fuzzilli_Protobuf_BeginForInLoop: Sendable { +public struct Fuzzilli_Protobuf_BeginPlainForInLoop: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Fuzzilli_Protobuf_BeginForInLoopWithReassignment: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2299,7 +2309,17 @@ public struct Fuzzilli_Protobuf_EndForInLoop: Sendable { public init() {} } -public struct Fuzzilli_Protobuf_BeginForOfLoop: Sendable { +public struct Fuzzilli_Protobuf_BeginPlainForOfLoop: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Fuzzilli_Protobuf_BeginForOfLoopWithReassignment: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -7133,8 +7153,27 @@ extension Fuzzilli_Protobuf_EndForLoop: SwiftProtobuf.Message, SwiftProtobuf._Me } } -extension Fuzzilli_Protobuf_BeginForInLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".BeginForInLoop" +extension Fuzzilli_Protobuf_BeginPlainForInLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BeginPlainForInLoop" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Fuzzilli_Protobuf_BeginPlainForInLoop, rhs: Fuzzilli_Protobuf_BeginPlainForInLoop) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Fuzzilli_Protobuf_BeginForInLoopWithReassignment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BeginForInLoopWithReassignment" public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { @@ -7146,7 +7185,7 @@ extension Fuzzilli_Protobuf_BeginForInLoop: SwiftProtobuf.Message, SwiftProtobuf try unknownFields.traverse(visitor: &visitor) } - public static func ==(lhs: Fuzzilli_Protobuf_BeginForInLoop, rhs: Fuzzilli_Protobuf_BeginForInLoop) -> Bool { + public static func ==(lhs: Fuzzilli_Protobuf_BeginForInLoopWithReassignment, rhs: Fuzzilli_Protobuf_BeginForInLoopWithReassignment) -> Bool { if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -7171,8 +7210,27 @@ extension Fuzzilli_Protobuf_EndForInLoop: SwiftProtobuf.Message, SwiftProtobuf._ } } -extension Fuzzilli_Protobuf_BeginForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - public static let protoMessageName: String = _protobuf_package + ".BeginForOfLoop" +extension Fuzzilli_Protobuf_BeginPlainForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BeginPlainForOfLoop" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Fuzzilli_Protobuf_BeginPlainForOfLoop, rhs: Fuzzilli_Protobuf_BeginPlainForOfLoop) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Fuzzilli_Protobuf_BeginForOfLoopWithReassignment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BeginForOfLoopWithReassignment" public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { @@ -7184,7 +7242,7 @@ extension Fuzzilli_Protobuf_BeginForOfLoop: SwiftProtobuf.Message, SwiftProtobuf try unknownFields.traverse(visitor: &visitor) } - public static func ==(lhs: Fuzzilli_Protobuf_BeginForOfLoop, rhs: Fuzzilli_Protobuf_BeginForOfLoop) -> Bool { + public static func ==(lhs: Fuzzilli_Protobuf_BeginForOfLoopWithReassignment, rhs: Fuzzilli_Protobuf_BeginForOfLoopWithReassignment) -> Bool { if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Sources/Fuzzilli/Protobuf/operations.proto b/Sources/Fuzzilli/Protobuf/operations.proto index 292ae8ce..dc10c972 100644 --- a/Sources/Fuzzilli/Protobuf/operations.proto +++ b/Sources/Fuzzilli/Protobuf/operations.proto @@ -683,13 +683,19 @@ message BeginForLoopBody { message EndForLoop { } -message BeginForInLoop { +message BeginPlainForInLoop { +} + +message BeginForInLoopWithReassignment { } message EndForInLoop { } -message BeginForOfLoop { +message BeginPlainForOfLoop { +} + +message BeginForOfLoopWithReassignment { } message BeginForOfLoopWithDestruct { diff --git a/Sources/Fuzzilli/Protobuf/program.pb.swift b/Sources/Fuzzilli/Protobuf/program.pb.swift index e03b56af..a786240f 100644 --- a/Sources/Fuzzilli/Protobuf/program.pb.swift +++ b/Sources/Fuzzilli/Protobuf/program.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: program.proto @@ -1249,12 +1248,20 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { set {operation = .endForLoop(newValue)} } - public var beginForInLoop: Fuzzilli_Protobuf_BeginForInLoop { + public var beginPlainForInLoop: Fuzzilli_Protobuf_BeginPlainForInLoop { get { - if case .beginForInLoop(let v)? = operation {return v} - return Fuzzilli_Protobuf_BeginForInLoop() + if case .beginPlainForInLoop(let v)? = operation {return v} + return Fuzzilli_Protobuf_BeginPlainForInLoop() } - set {operation = .beginForInLoop(newValue)} + set {operation = .beginPlainForInLoop(newValue)} + } + + public var beginForInLoopWithReassignment: Fuzzilli_Protobuf_BeginForInLoopWithReassignment { + get { + if case .beginForInLoopWithReassignment(let v)? = operation {return v} + return Fuzzilli_Protobuf_BeginForInLoopWithReassignment() + } + set {operation = .beginForInLoopWithReassignment(newValue)} } public var endForInLoop: Fuzzilli_Protobuf_EndForInLoop { @@ -1265,12 +1272,20 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { set {operation = .endForInLoop(newValue)} } - public var beginForOfLoop: Fuzzilli_Protobuf_BeginForOfLoop { + public var beginPlainForOfLoop: Fuzzilli_Protobuf_BeginPlainForOfLoop { get { - if case .beginForOfLoop(let v)? = operation {return v} - return Fuzzilli_Protobuf_BeginForOfLoop() + if case .beginPlainForOfLoop(let v)? = operation {return v} + return Fuzzilli_Protobuf_BeginPlainForOfLoop() } - set {operation = .beginForOfLoop(newValue)} + set {operation = .beginPlainForOfLoop(newValue)} + } + + public var beginForOfLoopWithReassignment: Fuzzilli_Protobuf_BeginForOfLoopWithReassignment { + get { + if case .beginForOfLoopWithReassignment(let v)? = operation {return v} + return Fuzzilli_Protobuf_BeginForOfLoopWithReassignment() + } + set {operation = .beginForOfLoopWithReassignment(newValue)} } public var beginForOfLoopWithDestruct: Fuzzilli_Protobuf_BeginForOfLoopWithDestruct { @@ -1634,9 +1649,11 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { case beginForLoopAfterthought(Fuzzilli_Protobuf_BeginForLoopAfterthought) case beginForLoopBody(Fuzzilli_Protobuf_BeginForLoopBody) case endForLoop(Fuzzilli_Protobuf_EndForLoop) - case beginForInLoop(Fuzzilli_Protobuf_BeginForInLoop) + case beginPlainForInLoop(Fuzzilli_Protobuf_BeginPlainForInLoop) + case beginForInLoopWithReassignment(Fuzzilli_Protobuf_BeginForInLoopWithReassignment) case endForInLoop(Fuzzilli_Protobuf_EndForInLoop) - case beginForOfLoop(Fuzzilli_Protobuf_BeginForOfLoop) + case beginPlainForOfLoop(Fuzzilli_Protobuf_BeginPlainForOfLoop) + case beginForOfLoopWithReassignment(Fuzzilli_Protobuf_BeginForOfLoopWithReassignment) case beginForOfLoopWithDestruct(Fuzzilli_Protobuf_BeginForOfLoopWithDestruct) case endForOfLoop(Fuzzilli_Protobuf_EndForOfLoop) case beginRepeatLoop(Fuzzilli_Protobuf_BeginRepeatLoop) @@ -1863,35 +1880,37 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M 149: .same(proto: "beginForLoopAfterthought"), 150: .same(proto: "beginForLoopBody"), 151: .same(proto: "endForLoop"), - 152: .same(proto: "beginForInLoop"), - 153: .same(proto: "endForInLoop"), - 154: .same(proto: "beginForOfLoop"), - 155: .same(proto: "beginForOfLoopWithDestruct"), - 156: .same(proto: "endForOfLoop"), - 157: .same(proto: "beginRepeatLoop"), - 158: .same(proto: "endRepeatLoop"), - 159: .same(proto: "loopBreak"), - 160: .same(proto: "loopContinue"), - 161: .same(proto: "beginTry"), - 162: .same(proto: "beginCatch"), - 163: .same(proto: "beginFinally"), - 164: .same(proto: "endTryCatchFinally"), - 165: .same(proto: "throwException"), - 166: .same(proto: "beginCodeString"), - 167: .same(proto: "endCodeString"), - 168: .same(proto: "beginBlockStatement"), - 169: .same(proto: "endBlockStatement"), - 170: .same(proto: "beginSwitch"), - 171: .same(proto: "beginSwitchCase"), - 172: .same(proto: "beginSwitchDefaultCase"), - 173: .same(proto: "endSwitchCase"), - 174: .same(proto: "endSwitch"), - 175: .same(proto: "switchBreak"), - 176: .same(proto: "loadNewTarget"), - 177: .same(proto: "print"), - 178: .same(proto: "explore"), - 179: .same(proto: "probe"), - 180: .same(proto: "fixup"), + 152: .same(proto: "beginPlainForInLoop"), + 153: .same(proto: "beginForInLoopWithReassignment"), + 154: .same(proto: "endForInLoop"), + 155: .same(proto: "beginPlainForOfLoop"), + 156: .same(proto: "beginForOfLoopWithReassignment"), + 157: .same(proto: "beginForOfLoopWithDestruct"), + 158: .same(proto: "endForOfLoop"), + 159: .same(proto: "beginRepeatLoop"), + 160: .same(proto: "endRepeatLoop"), + 161: .same(proto: "loopBreak"), + 162: .same(proto: "loopContinue"), + 163: .same(proto: "beginTry"), + 164: .same(proto: "beginCatch"), + 165: .same(proto: "beginFinally"), + 166: .same(proto: "endTryCatchFinally"), + 167: .same(proto: "throwException"), + 168: .same(proto: "beginCodeString"), + 169: .same(proto: "endCodeString"), + 170: .same(proto: "beginBlockStatement"), + 171: .same(proto: "endBlockStatement"), + 172: .same(proto: "beginSwitch"), + 173: .same(proto: "beginSwitchCase"), + 174: .same(proto: "beginSwitchDefaultCase"), + 175: .same(proto: "endSwitchCase"), + 176: .same(proto: "endSwitch"), + 177: .same(proto: "switchBreak"), + 178: .same(proto: "loadNewTarget"), + 179: .same(proto: "print"), + 180: .same(proto: "explore"), + 181: .same(proto: "probe"), + 182: .same(proto: "fixup"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -3847,19 +3866,32 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M } }() case 152: try { - var v: Fuzzilli_Protobuf_BeginForInLoop? + var v: Fuzzilli_Protobuf_BeginPlainForInLoop? var hadOneofValue = false if let current = self.operation { hadOneofValue = true - if case .beginForInLoop(let m) = current {v = m} + if case .beginPlainForInLoop(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.operation = .beginForInLoop(v) + self.operation = .beginPlainForInLoop(v) } }() case 153: try { + var v: Fuzzilli_Protobuf_BeginForInLoopWithReassignment? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .beginForInLoopWithReassignment(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .beginForInLoopWithReassignment(v) + } + }() + case 154: try { var v: Fuzzilli_Protobuf_EndForInLoop? var hadOneofValue = false if let current = self.operation { @@ -3872,20 +3904,33 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endForInLoop(v) } }() - case 154: try { - var v: Fuzzilli_Protobuf_BeginForOfLoop? + case 155: try { + var v: Fuzzilli_Protobuf_BeginPlainForOfLoop? var hadOneofValue = false if let current = self.operation { hadOneofValue = true - if case .beginForOfLoop(let m) = current {v = m} + if case .beginPlainForOfLoop(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.operation = .beginForOfLoop(v) + self.operation = .beginPlainForOfLoop(v) } }() - case 155: try { + case 156: try { + var v: Fuzzilli_Protobuf_BeginForOfLoopWithReassignment? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .beginForOfLoopWithReassignment(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .beginForOfLoopWithReassignment(v) + } + }() + case 157: try { var v: Fuzzilli_Protobuf_BeginForOfLoopWithDestruct? var hadOneofValue = false if let current = self.operation { @@ -3898,7 +3943,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginForOfLoopWithDestruct(v) } }() - case 156: try { + case 158: try { var v: Fuzzilli_Protobuf_EndForOfLoop? var hadOneofValue = false if let current = self.operation { @@ -3911,7 +3956,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endForOfLoop(v) } }() - case 157: try { + case 159: try { var v: Fuzzilli_Protobuf_BeginRepeatLoop? var hadOneofValue = false if let current = self.operation { @@ -3924,7 +3969,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginRepeatLoop(v) } }() - case 158: try { + case 160: try { var v: Fuzzilli_Protobuf_EndRepeatLoop? var hadOneofValue = false if let current = self.operation { @@ -3937,7 +3982,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endRepeatLoop(v) } }() - case 159: try { + case 161: try { var v: Fuzzilli_Protobuf_LoopBreak? var hadOneofValue = false if let current = self.operation { @@ -3950,7 +3995,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loopBreak(v) } }() - case 160: try { + case 162: try { var v: Fuzzilli_Protobuf_LoopContinue? var hadOneofValue = false if let current = self.operation { @@ -3963,7 +4008,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loopContinue(v) } }() - case 161: try { + case 163: try { var v: Fuzzilli_Protobuf_BeginTry? var hadOneofValue = false if let current = self.operation { @@ -3976,7 +4021,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginTry(v) } }() - case 162: try { + case 164: try { var v: Fuzzilli_Protobuf_BeginCatch? var hadOneofValue = false if let current = self.operation { @@ -3989,7 +4034,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginCatch(v) } }() - case 163: try { + case 165: try { var v: Fuzzilli_Protobuf_BeginFinally? var hadOneofValue = false if let current = self.operation { @@ -4002,7 +4047,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginFinally(v) } }() - case 164: try { + case 166: try { var v: Fuzzilli_Protobuf_EndTryCatchFinally? var hadOneofValue = false if let current = self.operation { @@ -4015,7 +4060,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endTryCatchFinally(v) } }() - case 165: try { + case 167: try { var v: Fuzzilli_Protobuf_ThrowException? var hadOneofValue = false if let current = self.operation { @@ -4028,7 +4073,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .throwException(v) } }() - case 166: try { + case 168: try { var v: Fuzzilli_Protobuf_BeginCodeString? var hadOneofValue = false if let current = self.operation { @@ -4041,7 +4086,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginCodeString(v) } }() - case 167: try { + case 169: try { var v: Fuzzilli_Protobuf_EndCodeString? var hadOneofValue = false if let current = self.operation { @@ -4054,7 +4099,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endCodeString(v) } }() - case 168: try { + case 170: try { var v: Fuzzilli_Protobuf_BeginBlockStatement? var hadOneofValue = false if let current = self.operation { @@ -4067,7 +4112,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginBlockStatement(v) } }() - case 169: try { + case 171: try { var v: Fuzzilli_Protobuf_EndBlockStatement? var hadOneofValue = false if let current = self.operation { @@ -4080,7 +4125,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endBlockStatement(v) } }() - case 170: try { + case 172: try { var v: Fuzzilli_Protobuf_BeginSwitch? var hadOneofValue = false if let current = self.operation { @@ -4093,7 +4138,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitch(v) } }() - case 171: try { + case 173: try { var v: Fuzzilli_Protobuf_BeginSwitchCase? var hadOneofValue = false if let current = self.operation { @@ -4106,7 +4151,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitchCase(v) } }() - case 172: try { + case 174: try { var v: Fuzzilli_Protobuf_BeginSwitchDefaultCase? var hadOneofValue = false if let current = self.operation { @@ -4119,7 +4164,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitchDefaultCase(v) } }() - case 173: try { + case 175: try { var v: Fuzzilli_Protobuf_EndSwitchCase? var hadOneofValue = false if let current = self.operation { @@ -4132,7 +4177,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endSwitchCase(v) } }() - case 174: try { + case 176: try { var v: Fuzzilli_Protobuf_EndSwitch? var hadOneofValue = false if let current = self.operation { @@ -4145,7 +4190,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endSwitch(v) } }() - case 175: try { + case 177: try { var v: Fuzzilli_Protobuf_SwitchBreak? var hadOneofValue = false if let current = self.operation { @@ -4158,7 +4203,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .switchBreak(v) } }() - case 176: try { + case 178: try { var v: Fuzzilli_Protobuf_LoadNewTarget? var hadOneofValue = false if let current = self.operation { @@ -4171,7 +4216,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loadNewTarget(v) } }() - case 177: try { + case 179: try { var v: Fuzzilli_Protobuf_Print? var hadOneofValue = false if let current = self.operation { @@ -4184,7 +4229,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .print(v) } }() - case 178: try { + case 180: try { var v: Fuzzilli_Protobuf_Explore? var hadOneofValue = false if let current = self.operation { @@ -4197,7 +4242,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .explore(v) } }() - case 179: try { + case 181: try { var v: Fuzzilli_Protobuf_Probe? var hadOneofValue = false if let current = self.operation { @@ -4210,7 +4255,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .probe(v) } }() - case 180: try { + case 182: try { var v: Fuzzilli_Protobuf_Fixup? var hadOneofValue = false if let current = self.operation { @@ -4837,121 +4882,129 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M guard case .endForLoop(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 151) }() - case .beginForInLoop?: try { - guard case .beginForInLoop(let v)? = self.operation else { preconditionFailure() } + case .beginPlainForInLoop?: try { + guard case .beginPlainForInLoop(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 152) }() - case .endForInLoop?: try { - guard case .endForInLoop(let v)? = self.operation else { preconditionFailure() } + case .beginForInLoopWithReassignment?: try { + guard case .beginForInLoopWithReassignment(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 153) }() - case .beginForOfLoop?: try { - guard case .beginForOfLoop(let v)? = self.operation else { preconditionFailure() } + case .endForInLoop?: try { + guard case .endForInLoop(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 154) }() + case .beginPlainForOfLoop?: try { + guard case .beginPlainForOfLoop(let v)? = self.operation else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 155) + }() + case .beginForOfLoopWithReassignment?: try { + guard case .beginForOfLoopWithReassignment(let v)? = self.operation else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 156) + }() case .beginForOfLoopWithDestruct?: try { guard case .beginForOfLoopWithDestruct(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 155) + try visitor.visitSingularMessageField(value: v, fieldNumber: 157) }() case .endForOfLoop?: try { guard case .endForOfLoop(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 156) + try visitor.visitSingularMessageField(value: v, fieldNumber: 158) }() case .beginRepeatLoop?: try { guard case .beginRepeatLoop(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 157) + try visitor.visitSingularMessageField(value: v, fieldNumber: 159) }() case .endRepeatLoop?: try { guard case .endRepeatLoop(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 158) + try visitor.visitSingularMessageField(value: v, fieldNumber: 160) }() case .loopBreak?: try { guard case .loopBreak(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 159) + try visitor.visitSingularMessageField(value: v, fieldNumber: 161) }() case .loopContinue?: try { guard case .loopContinue(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 160) + try visitor.visitSingularMessageField(value: v, fieldNumber: 162) }() case .beginTry?: try { guard case .beginTry(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 161) + try visitor.visitSingularMessageField(value: v, fieldNumber: 163) }() case .beginCatch?: try { guard case .beginCatch(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 162) + try visitor.visitSingularMessageField(value: v, fieldNumber: 164) }() case .beginFinally?: try { guard case .beginFinally(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 163) + try visitor.visitSingularMessageField(value: v, fieldNumber: 165) }() case .endTryCatchFinally?: try { guard case .endTryCatchFinally(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 164) + try visitor.visitSingularMessageField(value: v, fieldNumber: 166) }() case .throwException?: try { guard case .throwException(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 165) + try visitor.visitSingularMessageField(value: v, fieldNumber: 167) }() case .beginCodeString?: try { guard case .beginCodeString(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 166) + try visitor.visitSingularMessageField(value: v, fieldNumber: 168) }() case .endCodeString?: try { guard case .endCodeString(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 167) + try visitor.visitSingularMessageField(value: v, fieldNumber: 169) }() case .beginBlockStatement?: try { guard case .beginBlockStatement(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 168) + try visitor.visitSingularMessageField(value: v, fieldNumber: 170) }() case .endBlockStatement?: try { guard case .endBlockStatement(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 169) + try visitor.visitSingularMessageField(value: v, fieldNumber: 171) }() case .beginSwitch?: try { guard case .beginSwitch(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 170) + try visitor.visitSingularMessageField(value: v, fieldNumber: 172) }() case .beginSwitchCase?: try { guard case .beginSwitchCase(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 171) + try visitor.visitSingularMessageField(value: v, fieldNumber: 173) }() case .beginSwitchDefaultCase?: try { guard case .beginSwitchDefaultCase(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 172) + try visitor.visitSingularMessageField(value: v, fieldNumber: 174) }() case .endSwitchCase?: try { guard case .endSwitchCase(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 173) + try visitor.visitSingularMessageField(value: v, fieldNumber: 175) }() case .endSwitch?: try { guard case .endSwitch(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 174) + try visitor.visitSingularMessageField(value: v, fieldNumber: 176) }() case .switchBreak?: try { guard case .switchBreak(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 175) + try visitor.visitSingularMessageField(value: v, fieldNumber: 177) }() case .loadNewTarget?: try { guard case .loadNewTarget(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 176) + try visitor.visitSingularMessageField(value: v, fieldNumber: 178) }() case .print?: try { guard case .print(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 177) + try visitor.visitSingularMessageField(value: v, fieldNumber: 179) }() case .explore?: try { guard case .explore(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 178) + try visitor.visitSingularMessageField(value: v, fieldNumber: 180) }() case .probe?: try { guard case .probe(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 179) + try visitor.visitSingularMessageField(value: v, fieldNumber: 181) }() case .fixup?: try { guard case .fixup(let v)? = self.operation else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 180) + try visitor.visitSingularMessageField(value: v, fieldNumber: 182) }() case nil: break } diff --git a/Sources/Fuzzilli/Protobuf/program.proto b/Sources/Fuzzilli/Protobuf/program.proto index 9a5af6fe..131974e8 100644 --- a/Sources/Fuzzilli/Protobuf/program.proto +++ b/Sources/Fuzzilli/Protobuf/program.proto @@ -175,35 +175,37 @@ message Instruction { BeginForLoopAfterthought beginForLoopAfterthought = 149; BeginForLoopBody beginForLoopBody = 150; EndForLoop endForLoop = 151; - BeginForInLoop beginForInLoop = 152; - EndForInLoop endForInLoop = 153; - BeginForOfLoop beginForOfLoop = 154; - BeginForOfLoopWithDestruct beginForOfLoopWithDestruct = 155; - EndForOfLoop endForOfLoop = 156; - BeginRepeatLoop beginRepeatLoop = 157; - EndRepeatLoop endRepeatLoop = 158; - LoopBreak loopBreak = 159; - LoopContinue loopContinue = 160; - BeginTry beginTry = 161; - BeginCatch beginCatch = 162; - BeginFinally beginFinally = 163; - EndTryCatchFinally endTryCatchFinally = 164; - ThrowException throwException = 165; - BeginCodeString beginCodeString = 166; - EndCodeString endCodeString = 167; - BeginBlockStatement beginBlockStatement = 168; - EndBlockStatement endBlockStatement = 169; - BeginSwitch beginSwitch = 170; - BeginSwitchCase beginSwitchCase = 171; - BeginSwitchDefaultCase beginSwitchDefaultCase = 172; - EndSwitchCase endSwitchCase = 173; - EndSwitch endSwitch = 174; - SwitchBreak switchBreak = 175; - LoadNewTarget loadNewTarget = 176; - Print print = 177; - Explore explore = 178; - Probe probe = 179; - Fixup fixup = 180; + BeginPlainForInLoop beginPlainForInLoop = 152; + BeginForInLoopWithReassignment beginForInLoopWithReassignment = 153; + EndForInLoop endForInLoop = 154; + BeginPlainForOfLoop beginPlainForOfLoop = 155; + BeginForOfLoopWithReassignment beginForOfLoopWithReassignment = 156; + BeginForOfLoopWithDestruct beginForOfLoopWithDestruct = 157; + EndForOfLoop endForOfLoop = 158; + BeginRepeatLoop beginRepeatLoop = 159; + EndRepeatLoop endRepeatLoop = 160; + LoopBreak loopBreak = 161; + LoopContinue loopContinue = 162; + BeginTry beginTry = 163; + BeginCatch beginCatch = 164; + BeginFinally beginFinally = 165; + EndTryCatchFinally endTryCatchFinally = 166; + ThrowException throwException = 167; + BeginCodeString beginCodeString = 168; + EndCodeString endCodeString = 169; + BeginBlockStatement beginBlockStatement = 170; + EndBlockStatement endBlockStatement = 171; + BeginSwitch beginSwitch = 172; + BeginSwitchCase beginSwitchCase = 173; + BeginSwitchDefaultCase beginSwitchDefaultCase = 174; + EndSwitchCase endSwitchCase = 175; + EndSwitch endSwitch = 176; + SwitchBreak switchBreak = 177; + LoadNewTarget loadNewTarget = 178; + Print print = 179; + Explore explore = 180; + Probe probe = 181; + Fixup fixup = 182; } } diff --git a/Sources/Fuzzilli/Protobuf/sync.pb.swift b/Sources/Fuzzilli/Protobuf/sync.pb.swift index ec48a9ca..156ed692 100644 --- a/Sources/Fuzzilli/Protobuf/sync.pb.swift +++ b/Sources/Fuzzilli/Protobuf/sync.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: sync.proto diff --git a/Tests/FuzzilliTests/AnalyzerTest.swift b/Tests/FuzzilliTests/AnalyzerTest.swift index 1dac8557..3ec469db 100644 --- a/Tests/FuzzilliTests/AnalyzerTest.swift +++ b/Tests/FuzzilliTests/AnalyzerTest.swift @@ -257,15 +257,24 @@ class AnalyzerTests: XCTestCase { XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) } - b.buildForInLoop(args[1]) { _ in + b.buildPlainForInLoop(args[1]) { _ in XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) } - b.buildForOfLoop(args[2]) { _ in + let existingVar = b.loadInt(42) + b.buildForInLoopWithReassignment(args[1], existingVar) { XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) } - b.buildForOfLoop(args[3], selecting: [0, 1, 3]) { _ in + b.buildPlainForOfLoop(args[2]) { _ in + XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) + } + + b.buildForOfLoopWithReassignment(args[2], existingVar) { + XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) + } + + b.buildForOfLoopWithDestruct(args[3], selecting: [0, 1, 3]) { _ in XCTAssertEqual(b.context, [.javascript, .subroutine, .loop]) } diff --git a/Tests/FuzzilliTests/CompilerTests/advanced_loops.js b/Tests/FuzzilliTests/CompilerTests/advanced_loops.js index 7f40a8bf..4e310fec 100644 --- a/Tests/FuzzilliTests/CompilerTests/advanced_loops.js +++ b/Tests/FuzzilliTests/CompilerTests/advanced_loops.js @@ -89,3 +89,14 @@ for (output("inside for loop initializer"); output("inside for loop condition"), if (!countdown()) break; } resetCounter(); + +for (a of ["new a"]) {} +output("value of a: " + a); + +b = "old b"; +for (b of ["new b"]) {} +output("value of b: " + b); + +var c = "old c"; +for (c of ["new c"]) {} +output("value of c: " + c); \ No newline at end of file diff --git a/Tests/FuzzilliTests/JSTyperTests.swift b/Tests/FuzzilliTests/JSTyperTests.swift index 5ffd550e..35360558 100644 --- a/Tests/FuzzilliTests/JSTyperTests.swift +++ b/Tests/FuzzilliTests/JSTyperTests.swift @@ -681,12 +681,12 @@ class JSTyperTests: XCTestCase { } break case 2: - b.buildForInLoop(obj) { loopVar in + b.buildPlainForInLoop(obj) { loopVar in XCTAssertEqual(b.type(of: loopVar), .string) body() } case 3: - b.buildForOfLoop(obj) { loopVar in + b.buildPlainForOfLoop(obj) { loopVar in XCTAssertEqual(b.type(of: loopVar), .anything) body() } diff --git a/Tests/FuzzilliTests/LifterTest.swift b/Tests/FuzzilliTests/LifterTest.swift index 8371f9f1..cb3830b2 100644 --- a/Tests/FuzzilliTests/LifterTest.swift +++ b/Tests/FuzzilliTests/LifterTest.swift @@ -2579,9 +2579,9 @@ class LifterTests: XCTestCase { let a3 = b.createArray(with: [b.loadInt(30), b.loadInt(31), b.loadInt(32)]) let a4 = b.createArray(with: [a1, a2, a3]) let print = b.loadBuiltin("print") - b.buildForOfLoop(a4, selecting: [0,2], hasRestElement: true) { args in + b.buildForOfLoopWithDestruct(a4, selecting: [0,2], hasRestElement: true) { args in b.callFunction(print, withArgs: [args[0]]) - b.buildForOfLoop(args[1]) { v in + b.buildPlainForOfLoop(args[1]) { v in b.callFunction(print, withArgs: [v]) } } @@ -2602,13 +2602,40 @@ class LifterTests: XCTestCase { XCTAssertEqual(actual, expected) } + func testForLoopWithReassignment() { + let fuzzer = makeMockFuzzer() + let b = fuzzer.makeBuilder() + + let obj = b.createObject(with: ["x": b.loadInt(42)]) + let existing = b.loadString("initial") + b.buildForInLoopWithReassignment(obj, existing) { + b.reassign(existing, to: b.loadString("updated")) + } + + let program = b.finalize() + let actual = fuzzer.lifter.lift(program) + + let expected = """ + const o1 = { + "x": 42, + }; + let v2 = "initial"; + for (v2 in o1) { + v2 = "updated"; + } + + """ + + XCTAssertEqual(actual, expected) + } + func testBlockStatements() { let fuzzer = makeMockFuzzer() let b = fuzzer.makeBuilder() let v0 = b.loadInt(1337) let v1 = b.createObject(with: ["a": v0]) - b.buildForInLoop(v1) { v2 in + b.buildPlainForInLoop(v1) { v2 in b.blockStatement { let v3 = b.loadInt(1337) b.reassign(v2, to: v3) diff --git a/Tests/FuzzilliTests/ProgramBuilderTest.swift b/Tests/FuzzilliTests/ProgramBuilderTest.swift index 918af427..326ce000 100644 --- a/Tests/FuzzilliTests/ProgramBuilderTest.swift +++ b/Tests/FuzzilliTests/ProgramBuilderTest.swift @@ -2213,7 +2213,7 @@ class ProgramBuilderTests: XCTestCase { var o1 = b.createObject(with: ["foo": i, "bar": s, "baz": f]) b.loadString("unused") var o2 = b.createObject(with: [:]) - b.buildForInLoop(o1) { p in + b.buildPlainForInLoop(o1) { p in let i = b.loadInt(1337) b.loadString("unusedButPartOfBody") splicePoint = b.indexOfNextInstruction() @@ -2236,7 +2236,7 @@ class ProgramBuilderTests: XCTestCase { f = b.loadFloat(13.37) o1 = b.createObject(with: ["foo": i, "bar": s, "baz": f]) o2 = b.createObject(with: [:]) - b.buildForInLoop(o1) { p in + b.buildPlainForInLoop(o1) { p in let i = b.loadInt(1337) b.loadString("unusedButPartOfBody") b.setComputedProperty(p, of: o2, to: i)