diff --git a/Sources/Fuzzilli/Base/ProgramBuilder.swift b/Sources/Fuzzilli/Base/ProgramBuilder.swift index 3eb4cb968..7a755685a 100644 --- a/Sources/Fuzzilli/Base/ProgramBuilder.swift +++ b/Sources/Fuzzilli/Base/ProgramBuilder.swift @@ -147,11 +147,36 @@ public class ProgramBuilder { } } + + public var loopSta: [Variable] + + public func pushLabel(_ variable: Variable) { + loopSta.append(variable) + } + + public func popLabel() { + loopSta.removeLast() + } + + public func randomLabel() -> Variable { + if let randomElement = loopSta.randomElement() { + return randomElement + } + return loadString("ErrorLabel") + } + + public func isLoopStaNotEmpty() -> Bool { loopSta.count > 0 } + + public func clearLoopSta() { + if loopSta.count > 0 { loopSta.removeAll() } + } + /// Constructs a new program builder for the given fuzzer. init(for fuzzer: Fuzzer, parent: Program?) { self.fuzzer = fuzzer self.jsTyper = JSTyper(for: fuzzer.environment) self.parent = parent + self.loopSta = [] } /// Resets this builder. @@ -168,6 +193,7 @@ public class ProgramBuilder { jsTyper.reset() activeObjectLiterals.removeAll() activeClassDefinitions.removeAll() + loopSta.removeAll() } /// Finalizes and returns the constructed program, then resets this builder so it can be reused for building another program. @@ -2518,6 +2544,18 @@ public class ProgramBuilder { emit(EndRepeatLoop()) } + public func loadLabel(_ value: Variable) { + emit(LoadLabel(), withInputs: [value]) + } + + public func loopLabelBreak(_ value: Variable) { + emit(LoopLabelBreak(), withInputs: [value]) + } + + public func loopLabelContinue(_ value: Variable) { + emit(LoopLabelContinue(), withInputs: [value]) + } + public func loopBreak() { emit(LoopBreak()) } diff --git a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift index 9ce5be34a..690f94784 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift @@ -164,6 +164,8 @@ public let codeGeneratorWeights = [ "SwitchCaseBreakGenerator": 5, "LoopBreakGenerator": 5, "ContinueGenerator": 5, + "LoopLabelBreakGenerator": 5, + "LoopLabelContinueGenerator": 5, "TryCatchGenerator": 5, "ThrowGenerator": 1, "BlockStatementGenerator": 1, diff --git a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift index f8a9cd5f7..13ffbd3ab 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift @@ -1326,22 +1326,28 @@ public let CodeGenerators: [CodeGenerator] = [ RecursiveCodeGenerator("WhileLoopGenerator") { b in let loopVar = b.loadInt(0) + let make = randomloadLabel(b) b.buildWhileLoop({ b.compare(loopVar, with: b.loadInt(Int64.random(in: 0...10)), using: .lessThan) }) { b.buildRecursive() + popLabelIfMake(b, make) b.unary(.PostInc, loopVar) } }, RecursiveCodeGenerator("DoWhileLoopGenerator") { b in let loopVar = b.loadInt(0) + let make = randomloadLabel(b) b.buildDoWhileLoop(do: { b.buildRecursive() + popLabelIfMake(b, make) b.unary(.PostInc, loopVar) }, while: { b.compare(loopVar, with: b.loadInt(Int64.random(in: 0...10)), using: .lessThan) }) }, RecursiveCodeGenerator("SimpleForLoopGenerator") { b in + let make = randomloadLabel(b) b.buildForLoop(i: { b.loadInt(0) }, { i in b.compare(i, with: b.loadInt(Int64.random(in: 0...10)), using: .lessThan) }, { i in b.unary(.PostInc, i) }) { _ in + popLabelIfMake(b, make) b.buildRecursive() } }, @@ -1350,27 +1356,35 @@ public let CodeGenerators: [CodeGenerator] = [ if probability(0.5) { // Generate a for-loop without any loop variables. let counter = b.loadInt(10) + let make = randomloadLabel(b) b.buildForLoop({}, { b.unary(.PostDec, counter) }) { b.buildRecursive() + popLabelIfMake(b, make) } } else { // Generate a for-loop with two loop variables. // TODO could also generate loops with even more loop variables? + let make = randomloadLabel(b) b.buildForLoop({ return [b.loadInt(0), b.loadInt(10)] }, { vs in b.compare(vs[0], with: vs[1], using: .lessThan) }, { vs in b.unary(.PostInc, vs[0]); b.unary(.PostDec, vs[1]) }) { _ in b.buildRecursive() + popLabelIfMake(b, make) } } }, RecursiveCodeGenerator("ForInLoopGenerator", inputs: .preferred(.object())) { b, obj in + let make = randomloadLabel(b) b.buildForInLoop(obj) { _ in b.buildRecursive() + popLabelIfMake(b, make) } }, RecursiveCodeGenerator("ForOfLoopGenerator", inputs: .preferred(.iterable)) { b, obj in + let make = randomloadLabel(b) b.buildForOfLoop(obj) { _ in b.buildRecursive() + popLabelIfMake(b, make) } }, @@ -1385,16 +1399,19 @@ public let CodeGenerators: [CodeGenerator] = [ if indices.isEmpty { indices = [0] } - + let make = randomloadLabel(b) b.buildForOfLoop(obj, selecting: indices, hasRestElement: probability(0.2)) { _ in b.buildRecursive() + popLabelIfMake(b, make) } }, RecursiveCodeGenerator("RepeatLoopGenerator") { b in let numIterations = Int.random(in: 2...100) + let make = randomloadLabel(b) b.buildRepeatLoop(n: numIterations) { _ in b.buildRecursive() + popLabelIfMake(b, make) } }, @@ -1407,6 +1424,20 @@ public let CodeGenerators: [CodeGenerator] = [ b.loopContinue() }, + CodeGenerator("LoopLabelBreakGenerator", inContext: .loop) { b in + assert(b.context.contains(.loop)) + if b.isLoopStaNotEmpty() { + b.loopLabelBreak(b.randomLabel()) + } + }, + + CodeGenerator("LoopLabelContinueGenerator", inContext: .loop) { b in + assert(b.context.contains(.loop)) + if b.isLoopStaNotEmpty() { + b.loopLabelContinue(b.randomLabel()) + } + }, + RecursiveCodeGenerator("TryCatchGenerator") { b in // Build either try-catch-finally, try-catch, or try-finally withEqualProbability({ diff --git a/Sources/Fuzzilli/CodeGen/CodeGenertorsUtil.swift b/Sources/Fuzzilli/CodeGen/CodeGenertorsUtil.swift new file mode 100644 index 000000000..fecd2c360 --- /dev/null +++ b/Sources/Fuzzilli/CodeGen/CodeGenertorsUtil.swift @@ -0,0 +1,29 @@ +import Foundation + +func randomLabelBreak(_ b: ProgramBuilder) { + if b.isLoopStaNotEmpty() { + if probability(0.2) { + if probability(0.5) { + b.loopLabelBreak(b.randomLabel()) + } else { + b.loopLabelContinue(b.randomLabel()) + } + } + } +} + +func randomloadLabel(_ b: ProgramBuilder) -> Bool { + let labelValue = b.loadString(String(UUID().uuidString.prefix(6))) + let makelabel = probability(0.2) + if makelabel { + b.loadLabel(labelValue) + b.pushLabel(labelValue) + } + return makelabel +} + +func popLabelIfMake(_ b: ProgramBuilder, _ makelabel: Bool) { + if makelabel { + b.popLabel() + } +} diff --git a/Sources/Fuzzilli/Compiler/Compiler.swift b/Sources/Fuzzilli/Compiler/Compiler.swift index e9f9bbd2f..3e24ec73f 100644 --- a/Sources/Fuzzilli/Compiler/Compiler.swift +++ b/Sources/Fuzzilli/Compiler/Compiler.swift @@ -443,19 +443,48 @@ public class JavaScriptCompiler { emit(EndForOfLoop()) - case .breakStatement: - // If we're in both .loop and .switch context, then the loop must be the most recent context - // (switch blocks don't propagate an outer .loop context) so we just need to check for .loop here - if contextAnalyzer.context.contains(.loop){ - emit(LoopBreak()) - } else if contextAnalyzer.context.contains(.switchBlock){ - emit(SwitchBreak()) + case .breakStatement(let breakStatement): + let label = breakStatement.label + if !label.isEmpty { + let labelVar = emit(LoadString(value: label)).output // Assuming LoopLabelBreak needs a label loaded as input + emit(LoopLabelBreak(), withInputs: [labelVar]) // Use the loaded label as input } else { - throw CompilerError.invalidNodeError("break statement outside of loop or switch") + // If we're in both .loop and .switch context, then the loop must be the most recent context + // (switch blocks don't propagate an outer .loop context) so we just need to check for .loop here + if contextAnalyzer.context.contains(.loop){ + emit(LoopBreak()) + } else if contextAnalyzer.context.contains(.switchBlock){ + emit(SwitchBreak()) + } else { + throw CompilerError.invalidNodeError("break statement outside of loop or switch") + } } - case .continueStatement: - emit(LoopContinue()) + case .continueStatement(let continueStatement): + let label = continueStatement.label + if !label.isEmpty { + let labelVar = emit(LoadString(value: label)).output + emit(LoopLabelContinue(), withInputs: [labelVar]) // Emit a labeled continue by loading the label and using it as input + } else { + emit(LoopContinue()) + } + + case .labeledStatement(let labeledStatement): + // Step 1: Load the label as a string first + let label: String = labeledStatement.label + // Emit the LoadString operation to convert the label to a variable + let loadStringInstr = emit(LoadString(value: label)) // This creates a FuzzIL instruction for the label string + // Extract the output variable from the LoadString instruction + let labelVar = loadStringInstr.output // Get the variable produced by LoadString + // Step 2: Emit LoadLabel, passing the label variable as input + emit(LoadLabel(), withInputs: [labelVar]) // Pass the output variable as input + // Step 3: Push the label to the context (track the label scope) + contextAnalyzer.enterLabeledBlock() + defer { + contextAnalyzer.exitLabeledBlock() + } + // Step 4: Compile the statement within the labeled block + try compileStatement(labeledStatement.statement) case .tryStatement(let tryStatement): emit(BeginTry()) diff --git a/Sources/Fuzzilli/Compiler/Parser/parser.js b/Sources/Fuzzilli/Compiler/Parser/parser.js index 07c886919..c46f46d2c 100644 --- a/Sources/Fuzzilli/Compiler/Parser/parser.js +++ b/Sources/Fuzzilli/Compiler/Parser/parser.js @@ -289,10 +289,19 @@ function parse(script, proto) { return makeStatement('ForOfLoop', forOfLoop); } case 'BreakStatement': { - return makeStatement('BreakStatement', {}); + let breakStatementProto = {}; + + if (node.label) { + breakStatementProto.label = node.label.name; // Extract the label if present + } + return makeStatement('BreakStatement', breakStatementProto); } case 'ContinueStatement': { - return makeStatement('ContinueStatement', {}); + let continueStatementProto = {}; + if (node.label) { + continueStatementProto.label = node.label.name; // Extract the label if present + } + return makeStatement('ContinueStatement', continueStatementProto); } case 'TryStatement': { assert(node.block.type === 'BlockStatement', "Expected block statement as body of a try block"); @@ -332,6 +341,13 @@ function parse(script, proto) { switchStatement.cases = node.cases.map(visitStatement); return makeStatement('SwitchStatement', switchStatement); } + case "LabeledStatement": { + let labeledStatementProto = { + label: node.label.name, // Store the label + statement: visitStatement(node.body) + }; + return { labeledStatement: labeledStatementProto }; + } case 'SwitchCase': { let switchCase = {}; if (node.test) {switchCase.test = visitExpression(node.test)} diff --git a/Sources/Fuzzilli/FuzzIL/Analyzer.swift b/Sources/Fuzzilli/FuzzIL/Analyzer.swift index 4b7e348b2..88b4c3004 100644 --- a/Sources/Fuzzilli/FuzzIL/Analyzer.swift +++ b/Sources/Fuzzilli/FuzzIL/Analyzer.swift @@ -147,9 +147,30 @@ struct ContextAnalyzer: Analyzer { return contextStack.top } + // To track labeled block contexts + private var labelContextStack = Stack([false]) + var isInLabeledContext: Bool { + return labelContextStack.top + } + + // Enter a new labeled block (for example, a loop with a label) + mutating func enterLabeledBlock() { + labelContextStack.push(true) + } + + // Exit the current labeled block + mutating func exitLabeledBlock() { + if !labelContextStack.isEmpty { + labelContextStack.pop() + } else { + print("Warning: Attempting to exit a labeled block, but stack is empty.") + } + } + mutating func analyze(_ instr: Instruction) { if instr.isBlockEnd { contextStack.pop() + labelContextStack.pop() } if instr.isBlockStart { var newContext = instr.op.contextOpened @@ -178,6 +199,8 @@ struct ContextAnalyzer: Analyzer { newContext.remove(.switchCase) } contextStack.push(newContext) + // Push a new false label context for the block + labelContextStack.push(false) } } } diff --git a/Sources/Fuzzilli/FuzzIL/Instruction.swift b/Sources/Fuzzilli/FuzzIL/Instruction.swift index d770196b2..2cfd92890 100644 --- a/Sources/Fuzzilli/FuzzIL/Instruction.swift +++ b/Sources/Fuzzilli/FuzzIL/Instruction.swift @@ -814,6 +814,12 @@ extension Instruction: ProtobufConvertible { $0.loopBreak = Fuzzilli_Protobuf_LoopBreak() case .loopContinue: $0.loopContinue = Fuzzilli_Protobuf_LoopContinue() + case .loopLabelBreak: + $0.loopLabelBreak = Fuzzilli_Protobuf_LoopLabelBreak() + case .loadLabel: + $0.loadLabel = Fuzzilli_Protobuf_LoadLabel() + case .loopLabelContinue: + $0.loopLabelContinue = Fuzzilli_Protobuf_LoopLabelContinue() case .beginTry: $0.beginTry = Fuzzilli_Protobuf_BeginTry() case .beginCatch: @@ -1226,6 +1232,12 @@ extension Instruction: ProtobufConvertible { op = BeginRepeatLoop(iterations: Int(p.iterations), exposesLoopCounter: p.exposesLoopCounter) case .endRepeatLoop: op = EndRepeatLoop() + case .loopLabelBreak: + op = LoopLabelBreak() + case .loopLabelContinue: + op = LoopLabelContinue() + case .loadLabel: + op = LoadLabel() case .loopBreak: op = LoopBreak() case .loopContinue: diff --git a/Sources/Fuzzilli/FuzzIL/JsOperations.swift b/Sources/Fuzzilli/FuzzIL/JsOperations.swift index bab2bd749..8fcfbc164 100644 --- a/Sources/Fuzzilli/FuzzIL/JsOperations.swift +++ b/Sources/Fuzzilli/FuzzIL/JsOperations.swift @@ -2038,6 +2038,30 @@ final class EndRepeatLoop: JsOperation { } } +final class LoopLabelBreak: JsOperation { + override var opcode: Opcode { .loopLabelBreak(self) } + + init() { + super.init(numInputs: 1, attributes: [.isJump, .isSingular], requiredContext: [.javascript, .loop]) + } +} + +final class LoopLabelContinue: JsOperation { + override var opcode: Opcode { .loopLabelContinue(self) } + + init() { + super.init(numInputs: 1, attributes: [.isJump, .isSingular], requiredContext: [.javascript, .loop]) + } +} + +final class LoadLabel: JsOperation { + override var opcode: Opcode { .loadLabel(self) } + + init() { + super.init(numInputs: 1, attributes: [.isPure], requiredContext: [.javascript]) + } +} + final class LoopBreak: JsOperation { override var opcode: Opcode { .loopBreak(self) } diff --git a/Sources/Fuzzilli/FuzzIL/Opcodes.swift b/Sources/Fuzzilli/FuzzIL/Opcodes.swift index e0b9f37fa..d582c3c50 100644 --- a/Sources/Fuzzilli/FuzzIL/Opcodes.swift +++ b/Sources/Fuzzilli/FuzzIL/Opcodes.swift @@ -183,6 +183,9 @@ enum Opcode { case endForOfLoop(EndForOfLoop) case beginRepeatLoop(BeginRepeatLoop) case endRepeatLoop(EndRepeatLoop) + case loopLabelBreak(LoopLabelBreak) + case loopLabelContinue(LoopLabelContinue) + case loadLabel(LoadLabel) case loopBreak(LoopBreak) case loopContinue(LoopContinue) case beginTry(BeginTry) diff --git a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift index aa489854b..ede0fc9d9 100644 --- a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift +++ b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift @@ -699,6 +699,26 @@ public class FuzzILLifter: Lifter { w.decreaseIndentionLevel() w.emit("EndRepeatLoop") + + case .loopLabelBreak: + let labelVar = input(0) // Directly assign the input(0) value + if !labelVar.isEmpty { // Check if it's a non-empty string + w.emit("Break \(labelVar)") + } else { + w.emit("Break") + } + + case .loopLabelContinue: + let labelVar = input(0) // Directly assign the input(0) value + if !labelVar.isEmpty { // Check if it's a non-empty string + w.emit("Continue \(labelVar)") + } else { + w.emit("Continue") + } + + case .loadLabel: + w.emit("LoadLabel \(input(0))") + case .loopBreak, .switchBreak: w.emit("Break") diff --git a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift index 240f3ea99..b51131088 100644 --- a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift +++ b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift @@ -1214,6 +1214,21 @@ public class JavaScriptLifter: Lifter { w.leaveCurrentBlock() w.emit("}") + case .loopLabelBreak: + let VALUE = input(0) + let s = "loop_" + VALUE.text.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) + w.emit("break \(s);") + + case .loopLabelContinue: + let VALUE = input(0) + let s = "loop_" + VALUE.text.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) + w.emit("continue \(s);") + + case .loadLabel: + let VALUE = input(0) + let s = "loop_" + VALUE.text.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) + w.emit("\(s):") + case .loopBreak(_), .switchBreak: w.emit("break;") diff --git a/Sources/Fuzzilli/Protobuf/ast.pb.swift b/Sources/Fuzzilli/Protobuf/ast.pb.swift index 60d2eb9c5..f53ca5121 100644 --- a/Sources/Fuzzilli/Protobuf/ast.pb.swift +++ b/Sources/Fuzzilli/Protobuf/ast.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: ast.proto @@ -21,7 +22,6 @@ // 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 @@ -768,6 +768,8 @@ public struct Compiler_Protobuf_BreakStatement: Sendable { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + public var label: String = String() + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -778,6 +780,8 @@ public struct Compiler_Protobuf_ContinueStatement: Sendable { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + public var label: String = String() + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -954,6 +958,34 @@ public struct Compiler_Protobuf_SwitchCase: Sendable { fileprivate var _test: Compiler_Protobuf_Expression? = nil } +public struct Compiler_Protobuf_LabeledStatement: @unchecked 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. + + /// The label for the loop or block. + public var label: String { + get {return _storage._label} + set {_uniqueStorage()._label = newValue} + } + + /// The statement or block associated with the label. + public var statement: Compiler_Protobuf_Statement { + get {return _storage._statement ?? Compiler_Protobuf_Statement()} + set {_uniqueStorage()._statement = newValue} + } + /// Returns true if `statement` has been explicitly set. + public var hasStatement: Bool {return _storage._statement != nil} + /// Clears the value of `statement`. Subsequent reads from it will return its default value. + public mutating func clearStatement() {_uniqueStorage()._statement = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + public struct Compiler_Protobuf_Statement: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -1116,6 +1148,14 @@ public struct Compiler_Protobuf_Statement: @unchecked Sendable { set {_uniqueStorage()._statement = .switchStatement(newValue)} } + public var labeledStatement: Compiler_Protobuf_LabeledStatement { + get { + if case .labeledStatement(let v)? = _storage._statement {return v} + return Compiler_Protobuf_LabeledStatement() + } + set {_uniqueStorage()._statement = .labeledStatement(newValue)} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public enum OneOf_Statement: Equatable, Sendable { @@ -1138,6 +1178,7 @@ public struct Compiler_Protobuf_Statement: @unchecked Sendable { case throwStatement(Compiler_Protobuf_ThrowStatement) case withStatement(Compiler_Protobuf_WithStatement) case switchStatement(Compiler_Protobuf_SwitchStatement) + case labeledStatement(Compiler_Protobuf_LabeledStatement) } @@ -3759,18 +3800,31 @@ extension Compiler_Protobuf_ForOfLoop: SwiftProtobuf.Message, SwiftProtobuf._Mes extension Compiler_Protobuf_BreakStatement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".BreakStatement" - public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "label"), + ] public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // 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.decodeSingularStringField(value: &self.label) }() + default: break + } + } } public func traverse(visitor: inout V) throws { + if !self.label.isEmpty { + try visitor.visitSingularStringField(value: self.label, fieldNumber: 1) + } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Compiler_Protobuf_BreakStatement, rhs: Compiler_Protobuf_BreakStatement) -> Bool { + if lhs.label != rhs.label {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -3778,18 +3832,31 @@ extension Compiler_Protobuf_BreakStatement: SwiftProtobuf.Message, SwiftProtobuf extension Compiler_Protobuf_ContinueStatement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ContinueStatement" - public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "label"), + ] public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // 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.decodeSingularStringField(value: &self.label) }() + default: break + } + } } public func traverse(visitor: inout V) throws { + if !self.label.isEmpty { + try visitor.visitSingularStringField(value: self.label, fieldNumber: 1) + } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: Compiler_Protobuf_ContinueStatement, rhs: Compiler_Protobuf_ContinueStatement) -> Bool { + if lhs.label != rhs.label {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -4203,6 +4270,90 @@ extension Compiler_Protobuf_SwitchCase: SwiftProtobuf.Message, SwiftProtobuf._Me } } +extension Compiler_Protobuf_LabeledStatement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".LabeledStatement" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "label"), + 2: .same(proto: "statement"), + ] + + fileprivate class _StorageClass { + var _label: String = String() + var _statement: Compiler_Protobuf_Statement? = nil + + #if swift(>=5.10) + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + #else + static let defaultInstance = _StorageClass() + #endif + + private init() {} + + init(copying source: _StorageClass) { + _label = source._label + _statement = source._statement + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // 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.decodeSingularStringField(value: &_storage._label) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._statement) }() + default: break + } + } + } + } + + public func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // 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 + if !_storage._label.isEmpty { + try visitor.visitSingularStringField(value: _storage._label, fieldNumber: 1) + } + try { if let v = _storage._statement { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Compiler_Protobuf_LabeledStatement, rhs: Compiler_Protobuf_LabeledStatement) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._label != rhs_storage._label {return false} + if _storage._statement != rhs_storage._statement {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Compiler_Protobuf_Statement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Statement" public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -4225,6 +4376,7 @@ extension Compiler_Protobuf_Statement: SwiftProtobuf.Message, SwiftProtobuf._Mes 17: .same(proto: "throwStatement"), 18: .same(proto: "withStatement"), 19: .same(proto: "switchStatement"), + 20: .same(proto: "labeledStatement"), ] fileprivate class _StorageClass { @@ -4509,6 +4661,19 @@ extension Compiler_Protobuf_Statement: SwiftProtobuf.Message, SwiftProtobuf._Mes _storage._statement = .switchStatement(v) } }() + case 20: try { + var v: Compiler_Protobuf_LabeledStatement? + var hadOneofValue = false + if let current = _storage._statement { + hadOneofValue = true + if case .labeledStatement(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._statement = .labeledStatement(v) + } + }() default: break } } @@ -4598,6 +4763,10 @@ extension Compiler_Protobuf_Statement: SwiftProtobuf.Message, SwiftProtobuf._Mes guard case .switchStatement(let v)? = _storage._statement else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 19) }() + case .labeledStatement?: try { + guard case .labeledStatement(let v)? = _storage._statement else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 20) + }() case nil: break } } diff --git a/Sources/Fuzzilli/Protobuf/ast.proto b/Sources/Fuzzilli/Protobuf/ast.proto index 3db9a50c4..ceb32cad7 100644 --- a/Sources/Fuzzilli/Protobuf/ast.proto +++ b/Sources/Fuzzilli/Protobuf/ast.proto @@ -175,9 +175,11 @@ message ForOfLoop { } message BreakStatement { + string label = 1; } message ContinueStatement { + string label = 1; } message CatchClause { @@ -217,6 +219,11 @@ message SwitchCase { repeated Statement consequent = 2; } +message LabeledStatement { + string label = 1; // The label for the loop or block. + Statement statement = 2; // The statement or block associated with the label. +} + message Statement { oneof statement { EmptyStatement emptyStatement = 1; @@ -238,6 +245,7 @@ message Statement { ThrowStatement throwStatement = 17; WithStatement withStatement = 18; SwitchStatement switchStatement = 19; + LabeledStatement labeledStatement = 20; } } diff --git a/Sources/Fuzzilli/Protobuf/operations.pb.swift b/Sources/Fuzzilli/Protobuf/operations.pb.swift index 5bb356cdc..7e1715c62 100644 --- a/Sources/Fuzzilli/Protobuf/operations.pb.swift +++ b/Sources/Fuzzilli/Protobuf/operations.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: operations.proto @@ -21,7 +22,6 @@ // 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 @@ -2347,6 +2347,36 @@ public struct Fuzzilli_Protobuf_EndRepeatLoop: Sendable { public init() {} } +public struct Fuzzilli_Protobuf_LoopLabelBreak: 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_LoopLabelContinue: 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_LoadLabel: 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_LoopBreak: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -7275,6 +7305,63 @@ extension Fuzzilli_Protobuf_EndRepeatLoop: SwiftProtobuf.Message, SwiftProtobuf. } } +extension Fuzzilli_Protobuf_LoopLabelBreak: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".LoopLabelBreak" + 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_LoopLabelBreak, rhs: Fuzzilli_Protobuf_LoopLabelBreak) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Fuzzilli_Protobuf_LoopLabelContinue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".LoopLabelContinue" + 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_LoopLabelContinue, rhs: Fuzzilli_Protobuf_LoopLabelContinue) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Fuzzilli_Protobuf_LoadLabel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".LoadLabel" + 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_LoadLabel, rhs: Fuzzilli_Protobuf_LoadLabel) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Fuzzilli_Protobuf_LoopBreak: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LoopBreak" public static let _protobuf_nameMap = SwiftProtobuf._NameMap() diff --git a/Sources/Fuzzilli/Protobuf/operations.proto b/Sources/Fuzzilli/Protobuf/operations.proto index 524e45a83..ec1bdb5c2 100644 --- a/Sources/Fuzzilli/Protobuf/operations.proto +++ b/Sources/Fuzzilli/Protobuf/operations.proto @@ -705,6 +705,15 @@ message BeginRepeatLoop { message EndRepeatLoop { } +message LoopLabelBreak { +} + +message LoopLabelContinue { +} + +message LoadLabel { +} + message LoopBreak { } diff --git a/Sources/Fuzzilli/Protobuf/program.pb.swift b/Sources/Fuzzilli/Protobuf/program.pb.swift index b04230473..165e23dc0 100644 --- a/Sources/Fuzzilli/Protobuf/program.pb.swift +++ b/Sources/Fuzzilli/Protobuf/program.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: program.proto @@ -1296,6 +1297,30 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { set {operation = .endRepeatLoop(newValue)} } + public var loopLabelBreak: Fuzzilli_Protobuf_LoopLabelBreak { + get { + if case .loopLabelBreak(let v)? = operation {return v} + return Fuzzilli_Protobuf_LoopLabelBreak() + } + set {operation = .loopLabelBreak(newValue)} + } + + public var loopLabelContinue: Fuzzilli_Protobuf_LoopLabelContinue { + get { + if case .loopLabelContinue(let v)? = operation {return v} + return Fuzzilli_Protobuf_LoopLabelContinue() + } + set {operation = .loopLabelContinue(newValue)} + } + + public var loadLabel: Fuzzilli_Protobuf_LoadLabel { + get { + if case .loadLabel(let v)? = operation {return v} + return Fuzzilli_Protobuf_LoadLabel() + } + set {operation = .loadLabel(newValue)} + } + public var loopBreak: Fuzzilli_Protobuf_LoopBreak { get { if case .loopBreak(let v)? = operation {return v} @@ -1631,6 +1656,9 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { case endForOfLoop(Fuzzilli_Protobuf_EndForOfLoop) case beginRepeatLoop(Fuzzilli_Protobuf_BeginRepeatLoop) case endRepeatLoop(Fuzzilli_Protobuf_EndRepeatLoop) + case loopLabelBreak(Fuzzilli_Protobuf_LoopLabelBreak) + case loopLabelContinue(Fuzzilli_Protobuf_LoopLabelContinue) + case loadLabel(Fuzzilli_Protobuf_LoadLabel) case loopBreak(Fuzzilli_Protobuf_LoopBreak) case loopContinue(Fuzzilli_Protobuf_LoopContinue) case beginTry(Fuzzilli_Protobuf_BeginTry) @@ -1859,28 +1887,31 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M 155: .same(proto: "endForOfLoop"), 156: .same(proto: "beginRepeatLoop"), 157: .same(proto: "endRepeatLoop"), - 158: .same(proto: "loopBreak"), - 159: .same(proto: "loopContinue"), - 160: .same(proto: "beginTry"), - 161: .same(proto: "beginCatch"), - 162: .same(proto: "beginFinally"), - 163: .same(proto: "endTryCatchFinally"), - 164: .same(proto: "throwException"), - 165: .same(proto: "beginCodeString"), - 166: .same(proto: "endCodeString"), - 167: .same(proto: "beginBlockStatement"), - 168: .same(proto: "endBlockStatement"), - 169: .same(proto: "beginSwitch"), - 170: .same(proto: "beginSwitchCase"), - 171: .same(proto: "beginSwitchDefaultCase"), - 172: .same(proto: "endSwitchCase"), - 173: .same(proto: "endSwitch"), - 174: .same(proto: "switchBreak"), - 175: .same(proto: "loadNewTarget"), - 176: .same(proto: "print"), - 177: .same(proto: "explore"), - 178: .same(proto: "probe"), - 179: .same(proto: "fixup"), + 158: .same(proto: "loopLabelBreak"), + 159: .same(proto: "loopLabelContinue"), + 160: .same(proto: "loadLabel"), + 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 { @@ -3914,6 +3945,45 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M } }() case 158: try { + var v: Fuzzilli_Protobuf_LoopLabelBreak? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .loopLabelBreak(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .loopLabelBreak(v) + } + }() + case 159: try { + var v: Fuzzilli_Protobuf_LoopLabelContinue? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .loopLabelContinue(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .loopLabelContinue(v) + } + }() + case 160: try { + var v: Fuzzilli_Protobuf_LoadLabel? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .loadLabel(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .loadLabel(v) + } + }() + case 161: try { var v: Fuzzilli_Protobuf_LoopBreak? var hadOneofValue = false if let current = self.operation { @@ -3926,7 +3996,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loopBreak(v) } }() - case 159: try { + case 162: try { var v: Fuzzilli_Protobuf_LoopContinue? var hadOneofValue = false if let current = self.operation { @@ -3939,7 +4009,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loopContinue(v) } }() - case 160: try { + case 163: try { var v: Fuzzilli_Protobuf_BeginTry? var hadOneofValue = false if let current = self.operation { @@ -3952,7 +4022,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginTry(v) } }() - case 161: try { + case 164: try { var v: Fuzzilli_Protobuf_BeginCatch? var hadOneofValue = false if let current = self.operation { @@ -3965,7 +4035,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginCatch(v) } }() - case 162: try { + case 165: try { var v: Fuzzilli_Protobuf_BeginFinally? var hadOneofValue = false if let current = self.operation { @@ -3978,7 +4048,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginFinally(v) } }() - case 163: try { + case 166: try { var v: Fuzzilli_Protobuf_EndTryCatchFinally? var hadOneofValue = false if let current = self.operation { @@ -3991,7 +4061,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endTryCatchFinally(v) } }() - case 164: try { + case 167: try { var v: Fuzzilli_Protobuf_ThrowException? var hadOneofValue = false if let current = self.operation { @@ -4004,7 +4074,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .throwException(v) } }() - case 165: try { + case 168: try { var v: Fuzzilli_Protobuf_BeginCodeString? var hadOneofValue = false if let current = self.operation { @@ -4017,7 +4087,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginCodeString(v) } }() - case 166: try { + case 169: try { var v: Fuzzilli_Protobuf_EndCodeString? var hadOneofValue = false if let current = self.operation { @@ -4030,7 +4100,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endCodeString(v) } }() - case 167: try { + case 170: try { var v: Fuzzilli_Protobuf_BeginBlockStatement? var hadOneofValue = false if let current = self.operation { @@ -4043,7 +4113,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginBlockStatement(v) } }() - case 168: try { + case 171: try { var v: Fuzzilli_Protobuf_EndBlockStatement? var hadOneofValue = false if let current = self.operation { @@ -4056,7 +4126,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endBlockStatement(v) } }() - case 169: try { + case 172: try { var v: Fuzzilli_Protobuf_BeginSwitch? var hadOneofValue = false if let current = self.operation { @@ -4069,7 +4139,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitch(v) } }() - case 170: try { + case 173: try { var v: Fuzzilli_Protobuf_BeginSwitchCase? var hadOneofValue = false if let current = self.operation { @@ -4082,7 +4152,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitchCase(v) } }() - case 171: try { + case 174: try { var v: Fuzzilli_Protobuf_BeginSwitchDefaultCase? var hadOneofValue = false if let current = self.operation { @@ -4095,7 +4165,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .beginSwitchDefaultCase(v) } }() - case 172: try { + case 175: try { var v: Fuzzilli_Protobuf_EndSwitchCase? var hadOneofValue = false if let current = self.operation { @@ -4108,7 +4178,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endSwitchCase(v) } }() - case 173: try { + case 176: try { var v: Fuzzilli_Protobuf_EndSwitch? var hadOneofValue = false if let current = self.operation { @@ -4121,7 +4191,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .endSwitch(v) } }() - case 174: try { + case 177: try { var v: Fuzzilli_Protobuf_SwitchBreak? var hadOneofValue = false if let current = self.operation { @@ -4134,7 +4204,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .switchBreak(v) } }() - case 175: try { + case 178: try { var v: Fuzzilli_Protobuf_LoadNewTarget? var hadOneofValue = false if let current = self.operation { @@ -4147,7 +4217,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .loadNewTarget(v) } }() - case 176: try { + case 179: try { var v: Fuzzilli_Protobuf_Print? var hadOneofValue = false if let current = self.operation { @@ -4160,7 +4230,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .print(v) } }() - case 177: try { + case 180: try { var v: Fuzzilli_Protobuf_Explore? var hadOneofValue = false if let current = self.operation { @@ -4173,7 +4243,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .explore(v) } }() - case 178: try { + case 181: try { var v: Fuzzilli_Protobuf_Probe? var hadOneofValue = false if let current = self.operation { @@ -4186,7 +4256,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .probe(v) } }() - case 179: try { + case 182: try { var v: Fuzzilli_Protobuf_Fixup? var hadOneofValue = false if let current = self.operation { @@ -4837,93 +4907,105 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M guard case .endRepeatLoop(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 157) }() + case .loopLabelBreak?: try { + guard case .loopLabelBreak(let v)? = self.operation else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 158) + }() + case .loopLabelContinue?: try { + guard case .loopLabelContinue(let v)? = self.operation else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 159) + }() + case .loadLabel?: try { + guard case .loadLabel(let v)? = self.operation else { preconditionFailure() } + 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: 158) + 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: 159) + 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: 160) + 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: 161) + 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: 162) + 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: 163) + 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: 164) + 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: 165) + 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: 166) + 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: 167) + 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: 168) + 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: 169) + 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: 170) + 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: 171) + 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: 172) + 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: 173) + 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: 174) + 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: 175) + 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: 176) + 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: 177) + 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: 178) + 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: 179) + 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 c8da3a390..8913bc92b 100644 --- a/Sources/Fuzzilli/Protobuf/program.proto +++ b/Sources/Fuzzilli/Protobuf/program.proto @@ -181,28 +181,31 @@ message Instruction { EndForOfLoop endForOfLoop = 155; BeginRepeatLoop beginRepeatLoop = 156; EndRepeatLoop endRepeatLoop = 157; - LoopBreak loopBreak = 158; - LoopContinue loopContinue = 159; - BeginTry beginTry = 160; - BeginCatch beginCatch = 161; - BeginFinally beginFinally = 162; - EndTryCatchFinally endTryCatchFinally = 163; - ThrowException throwException = 164; - BeginCodeString beginCodeString = 165; - EndCodeString endCodeString = 166; - BeginBlockStatement beginBlockStatement = 167; - EndBlockStatement endBlockStatement = 168; - BeginSwitch beginSwitch = 169; - BeginSwitchCase beginSwitchCase = 170; - BeginSwitchDefaultCase beginSwitchDefaultCase = 171; - EndSwitchCase endSwitchCase = 172; - EndSwitch endSwitch = 173; - SwitchBreak switchBreak = 174; - LoadNewTarget loadNewTarget = 175; - Print print = 176; - Explore explore = 177; - Probe probe = 178; - Fixup fixup = 179; + LoopLabelBreak loopLabelBreak = 158; + LoopLabelContinue loopLabelContinue = 159; + LoadLabel loadLabel = 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 156ed6920..ec48a9ca9 100644 --- a/Sources/Fuzzilli/Protobuf/sync.pb.swift +++ b/Sources/Fuzzilli/Protobuf/sync.pb.swift @@ -1,5 +1,6 @@ // 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/CompilerTests/label.js b/Tests/FuzzilliTests/CompilerTests/label.js new file mode 100644 index 000000000..ad2381f63 --- /dev/null +++ b/Tests/FuzzilliTests/CompilerTests/label.js @@ -0,0 +1,27 @@ +labelBlock: for (let i = 0; i < 1; i++) { + console.log("Inside block"); + continue labelBlock; // Skips the rest of the code in this labeled block + console.log("This will not run"); +} +console.log("Outside block"); + +outerLoop1: +for (let i = 0; i < 3; i++) { + for (let j = 0; j < 3; j++) { + if (j === 1) { + continue outerLoop1; // Skips to the next iteration of the outer loop + } + console.log(`i = ${i}, j = ${j}`); + } +} + +repeatLoop2: do { + console.log("Running once"); + break repeatLoop2; +} while (false); + +outerLoop3: while (true) { + console.log("Looping..."); + break outerLoop3; + console.log("Cannot be printed..."); +} \ No newline at end of file