Skip to content

Commit 215f158

Browse files
authored
Added support for async arrow functions (googleprojectzero#96)
1 parent e8b7b34 commit 215f158

File tree

12 files changed

+169
-3
lines changed

12 files changed

+169
-3
lines changed

Sources/Fuzzilli/Core/CodeGenerators.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ public let CodeGenerators: [CodeGenerator] = [
140140
}
141141
},
142142

143+
CodeGenerator("AsyncArrowFunctionGenerator") { b in
144+
b.defineAsyncArrowFunction(withSignature: FunctionSignature(withParameterCount: Int.random(in: 2...5), hasRestParam: probability(0.1))) { _ in
145+
b.generateRecursive()
146+
b.await(value: b.randVar())
147+
b.doReturn(value: b.randVar())
148+
}
149+
},
150+
143151
CodeGenerator("PropertyRetrievalGenerator", input: .object()) { b, obj in
144152
let propertyName = b.type(of: obj).randomProperty() ?? b.genPropertyNameForRead()
145153
b.loadProperty(propertyName, of: obj)

Sources/Fuzzilli/Core/ProgramBuilder.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,14 @@ public class ProgramBuilder {
706706
perform(EndAsyncFunctionDefinition())
707707
return instruction.output
708708
}
709+
710+
@discardableResult
711+
public func defineAsyncArrowFunction(withSignature signature: FunctionSignature, _ body: ([Variable]) -> ()) -> Variable {
712+
let instruction = perform(BeginAsyncArrowFunctionDefinition(signature: signature))
713+
body(Array(instruction.innerOutputs))
714+
perform(EndAsyncArrowFunctionDefinition())
715+
return instruction.output
716+
}
709717

710718
public func doReturn(value: Variable) {
711719
perform(Return(), withInputs: [value])

Sources/Fuzzilli/FuzzIL/Instruction.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ extension Instruction: ProtobufConvertible {
329329
$0.beginAsyncFunctionDefinition = Fuzzilli_Protobuf_BeginAsyncFunctionDefinition.with { $0.signature = op.signature.asProtobuf() }
330330
case is EndAsyncFunctionDefinition:
331331
$0.endAsyncFunctionDefinition = Fuzzilli_Protobuf_EndAsyncFunctionDefinition()
332+
case let op as BeginAsyncArrowFunctionDefinition:
333+
$0.beginAsyncArrowFunctionDefinition = Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition.with { $0.signature = op.signature.asProtobuf() }
334+
case is EndAsyncArrowFunctionDefinition:
335+
$0.endAsyncArrowFunctionDefinition = Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition()
332336
case is Return:
333337
$0.return = Fuzzilli_Protobuf_Return()
334338
case is Yield:
@@ -516,6 +520,10 @@ extension Instruction: ProtobufConvertible {
516520
op = BeginAsyncFunctionDefinition(signature: try FunctionSignature(from: p.signature))
517521
case .endAsyncFunctionDefinition(_):
518522
op = EndAsyncFunctionDefinition()
523+
case .beginAsyncArrowFunctionDefinition(let p):
524+
op = BeginAsyncArrowFunctionDefinition(signature: try FunctionSignature(from: p.signature))
525+
case .endAsyncArrowFunctionDefinition(_):
526+
op = EndAsyncArrowFunctionDefinition()
519527
case .return(_):
520528
op = Return()
521529
case .yield(_):

Sources/Fuzzilli/FuzzIL/Operations.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ class EndGeneratorFunctionDefinition: EndAnyFunctionDefinition {}
371371
class BeginAsyncFunctionDefinition: BeginAnyFunctionDefinition {}
372372
class EndAsyncFunctionDefinition: EndAnyFunctionDefinition {}
373373

374+
// A ES6 async arrow function
375+
class BeginAsyncArrowFunctionDefinition: BeginAnyFunctionDefinition {}
376+
class EndAsyncArrowFunctionDefinition: EndAnyFunctionDefinition {}
377+
374378
class Return: Operation {
375379
init() {
376380
super.init(numInputs: 1, numOutputs: 0, attributes: [.isJump])

Sources/Fuzzilli/FuzzIL/Semantics.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ extension Operation {
7676
return endOp is EndGeneratorFunctionDefinition
7777
case is BeginAsyncFunctionDefinition:
7878
return endOp is EndAsyncFunctionDefinition
79+
case is BeginAsyncArrowFunctionDefinition:
80+
return endOp is EndAsyncArrowFunctionDefinition
7981
case is BeginWith:
8082
return endOp is EndWith
8183
case is BeginIf:

Sources/Fuzzilli/Lifting/JavaScriptLifter.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,13 @@ public class JavaScriptLifter: ComponentBase, Lifter {
253253

254254
case let op as BeginAsyncFunctionDefinition:
255255
liftFunctionDefinitionBegin(op, "async function")
256+
257+
case let op as BeginAsyncArrowFunctionDefinition:
258+
let params = liftFunctionDefinitionParameters(op)
259+
w.emit("\(constDecl) \(instr.output) = async (\(params)) => {")
260+
w.increaseIndentionLevel()
256261

257-
case is EndArrowFunctionDefinition:
262+
case is EndArrowFunctionDefinition, is EndAsyncArrowFunctionDefinition:
258263
w.decreaseIndentionLevel()
259264
w.emit("};")
260265

Sources/Fuzzilli/Protobuf/operations.pb.swift

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,37 @@ public struct Fuzzilli_Protobuf_EndAsyncFunctionDefinition {
673673
public init() {}
674674
}
675675

676+
public struct Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition {
677+
// SwiftProtobuf.Message conformance is added in an extension below. See the
678+
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
679+
// methods supported on all messages.
680+
681+
public var signature: Fuzzilli_Protobuf_FunctionSignature {
682+
get {return _signature ?? Fuzzilli_Protobuf_FunctionSignature()}
683+
set {_signature = newValue}
684+
}
685+
/// Returns true if `signature` has been explicitly set.
686+
public var hasSignature: Bool {return self._signature != nil}
687+
/// Clears the value of `signature`. Subsequent reads from it will return its default value.
688+
public mutating func clearSignature() {self._signature = nil}
689+
690+
public var unknownFields = SwiftProtobuf.UnknownStorage()
691+
692+
public init() {}
693+
694+
fileprivate var _signature: Fuzzilli_Protobuf_FunctionSignature? = nil
695+
}
696+
697+
public struct Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition {
698+
// SwiftProtobuf.Message conformance is added in an extension below. See the
699+
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
700+
// methods supported on all messages.
701+
702+
public var unknownFields = SwiftProtobuf.UnknownStorage()
703+
704+
public init() {}
705+
}
706+
676707
public struct Fuzzilli_Protobuf_Return {
677708
// SwiftProtobuf.Message conformance is added in an extension below. See the
678709
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
@@ -2015,6 +2046,54 @@ extension Fuzzilli_Protobuf_EndAsyncFunctionDefinition: SwiftProtobuf.Message, S
20152046
}
20162047
}
20172048

2049+
extension Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
2050+
public static let protoMessageName: String = _protobuf_package + ".BeginAsyncArrowFunctionDefinition"
2051+
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
2052+
1: .same(proto: "signature"),
2053+
]
2054+
2055+
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
2056+
while let fieldNumber = try decoder.nextFieldNumber() {
2057+
switch fieldNumber {
2058+
case 1: try decoder.decodeSingularMessageField(value: &self._signature)
2059+
default: break
2060+
}
2061+
}
2062+
}
2063+
2064+
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
2065+
if let v = self._signature {
2066+
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
2067+
}
2068+
try unknownFields.traverse(visitor: &visitor)
2069+
}
2070+
2071+
public static func ==(lhs: Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition, rhs: Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition) -> Bool {
2072+
if lhs._signature != rhs._signature {return false}
2073+
if lhs.unknownFields != rhs.unknownFields {return false}
2074+
return true
2075+
}
2076+
}
2077+
2078+
extension Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
2079+
public static let protoMessageName: String = _protobuf_package + ".EndAsyncArrowFunctionDefinition"
2080+
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()
2081+
2082+
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
2083+
while let _ = try decoder.nextFieldNumber() {
2084+
}
2085+
}
2086+
2087+
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
2088+
try unknownFields.traverse(visitor: &visitor)
2089+
}
2090+
2091+
public static func ==(lhs: Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition, rhs: Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition) -> Bool {
2092+
if lhs.unknownFields != rhs.unknownFields {return false}
2093+
return true
2094+
}
2095+
}
2096+
20182097
extension Fuzzilli_Protobuf_Return: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
20192098
public static let protoMessageName: String = _protobuf_package + ".Return"
20202099
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()

Sources/Fuzzilli/Protobuf/operations.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ message BeginAsyncFunctionDefinition {
144144
message EndAsyncFunctionDefinition {
145145
}
146146

147+
message BeginAsyncArrowFunctionDefinition {
148+
FunctionSignature signature = 1;
149+
}
150+
151+
message EndAsyncArrowFunctionDefinition {
152+
}
153+
147154
message Return {
148155
}
149156

Sources/Fuzzilli/Protobuf/program.pb.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,22 @@ public struct Fuzzilli_Protobuf_Instruction {
341341
set {_uniqueStorage()._operation = .endAsyncFunctionDefinition(newValue)}
342342
}
343343

344+
public var beginAsyncArrowFunctionDefinition: Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition {
345+
get {
346+
if case .beginAsyncArrowFunctionDefinition(let v)? = _storage._operation {return v}
347+
return Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition()
348+
}
349+
set {_uniqueStorage()._operation = .beginAsyncArrowFunctionDefinition(newValue)}
350+
}
351+
352+
public var endAsyncArrowFunctionDefinition: Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition {
353+
get {
354+
if case .endAsyncArrowFunctionDefinition(let v)? = _storage._operation {return v}
355+
return Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition()
356+
}
357+
set {_uniqueStorage()._operation = .endAsyncArrowFunctionDefinition(newValue)}
358+
}
359+
344360
public var `return`: Fuzzilli_Protobuf_Return {
345361
get {
346362
if case .return(let v)? = _storage._operation {return v}
@@ -693,6 +709,8 @@ public struct Fuzzilli_Protobuf_Instruction {
693709
case endGeneratorFunctionDefinition(Fuzzilli_Protobuf_EndGeneratorFunctionDefinition)
694710
case beginAsyncFunctionDefinition(Fuzzilli_Protobuf_BeginAsyncFunctionDefinition)
695711
case endAsyncFunctionDefinition(Fuzzilli_Protobuf_EndAsyncFunctionDefinition)
712+
case beginAsyncArrowFunctionDefinition(Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition)
713+
case endAsyncArrowFunctionDefinition(Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition)
696714
case `return`(Fuzzilli_Protobuf_Return)
697715
case yield(Fuzzilli_Protobuf_Yield)
698716
case yieldEach(Fuzzilli_Protobuf_YieldEach)
@@ -772,6 +790,8 @@ public struct Fuzzilli_Protobuf_Instruction {
772790
case (.endGeneratorFunctionDefinition(let l), .endGeneratorFunctionDefinition(let r)): return l == r
773791
case (.beginAsyncFunctionDefinition(let l), .beginAsyncFunctionDefinition(let r)): return l == r
774792
case (.endAsyncFunctionDefinition(let l), .endAsyncFunctionDefinition(let r)): return l == r
793+
case (.beginAsyncArrowFunctionDefinition(let l), .beginAsyncArrowFunctionDefinition(let r)): return l == r
794+
case (.endAsyncArrowFunctionDefinition(let l), .endAsyncArrowFunctionDefinition(let r)): return l == r
775795
case (.return(let l), .return(let r)): return l == r
776796
case (.yield(let l), .yield(let r)): return l == r
777797
case (.yieldEach(let l), .yieldEach(let r)): return l == r
@@ -878,6 +898,8 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
878898
70: .same(proto: "endGeneratorFunctionDefinition"),
879899
71: .same(proto: "beginAsyncFunctionDefinition"),
880900
72: .same(proto: "endAsyncFunctionDefinition"),
901+
79: .same(proto: "beginAsyncArrowFunctionDefinition"),
902+
80: .same(proto: "endAsyncArrowFunctionDefinition"),
881903
29: .same(proto: "return"),
882904
73: .same(proto: "yield"),
883905
74: .same(proto: "yieldEach"),
@@ -1543,6 +1565,22 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
15431565
}
15441566
try decoder.decodeSingularMessageField(value: &v)
15451567
if let v = v {_storage._operation = .comment(v)}
1568+
case 79:
1569+
var v: Fuzzilli_Protobuf_BeginAsyncArrowFunctionDefinition?
1570+
if let current = _storage._operation {
1571+
try decoder.handleConflictingOneOf()
1572+
if case .beginAsyncArrowFunctionDefinition(let m) = current {v = m}
1573+
}
1574+
try decoder.decodeSingularMessageField(value: &v)
1575+
if let v = v {_storage._operation = .beginAsyncArrowFunctionDefinition(v)}
1576+
case 80:
1577+
var v: Fuzzilli_Protobuf_EndAsyncArrowFunctionDefinition?
1578+
if let current = _storage._operation {
1579+
try decoder.handleConflictingOneOf()
1580+
if case .endAsyncArrowFunctionDefinition(let m) = current {v = m}
1581+
}
1582+
try decoder.decodeSingularMessageField(value: &v)
1583+
if let v = v {_storage._operation = .endAsyncArrowFunctionDefinition(v)}
15461584
default: break
15471585
}
15481586
}
@@ -1705,6 +1743,10 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M
17051743
try visitor.visitSingularMessageField(value: v, fieldNumber: 77)
17061744
case .comment(let v)?:
17071745
try visitor.visitSingularMessageField(value: v, fieldNumber: 78)
1746+
case .beginAsyncArrowFunctionDefinition(let v)?:
1747+
try visitor.visitSingularMessageField(value: v, fieldNumber: 79)
1748+
case .endAsyncArrowFunctionDefinition(let v)?:
1749+
try visitor.visitSingularMessageField(value: v, fieldNumber: 80)
17081750
case nil: break
17091751
}
17101752
}

Sources/Fuzzilli/Protobuf/program.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ message Instruction {
6060
EndGeneratorFunctionDefinition endGeneratorFunctionDefinition = 70;
6161
BeginAsyncFunctionDefinition beginAsyncFunctionDefinition = 71;
6262
EndAsyncFunctionDefinition endAsyncFunctionDefinition = 72;
63+
BeginAsyncArrowFunctionDefinition beginAsyncArrowFunctionDefinition= 79;
64+
EndAsyncArrowFunctionDefinition endAsyncArrowFunctionDefinition = 80;
6365
Return return = 29;
6466
Yield yield = 73;
6567
YieldEach yieldEach = 74;

0 commit comments

Comments
 (0)