Skip to content

Commit cbade79

Browse files
Leon BettscheiderV8-internal LUCI CQ
authored andcommitted
Add default parameters to generated functions
This CL adds support for default parameters in generated functions. Methods with default parameters, and JS to FuzzIL compilation code will be added later. Change-Id: I5b3583a8656c72a4068c497677bd6f18c98badb8 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/9176497 Reviewed-by: Matthias Liedtke <mliedtke@google.com> Commit-Queue: Leon Bettscheider <bettscheider@google.com>
1 parent 1d3e779 commit cbade79

File tree

9 files changed

+264
-51
lines changed

9 files changed

+264
-51
lines changed

Sources/Fuzzilli/Base/ProgramBuilder.swift

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,11 +3324,46 @@ public class ProgramBuilder {
33243324
return parameters.count
33253325
}
33263326

3327-
public static func parameters(n: Int, hasRestParameter: Bool = false)
3328-
-> SubroutineDescriptor
3329-
{
3327+
public static func parameters(
3328+
n: Int, hasRestParameter: Bool = false, defaultParameterIndices: [Int] = []
3329+
) -> SubroutineDescriptor {
33303330
return SubroutineDescriptor(
3331-
withParameters: Parameters(count: n, hasRestParameter: hasRestParameter))
3331+
withParameters: Parameters(
3332+
count: n, hasRestParameter: hasRestParameter,
3333+
defaultParameterIndices: defaultParameterIndices))
3334+
}
3335+
3336+
/// Returns a copy of this SubroutineDescriptor but with some parameters turned into default parameters.
3337+
public func withRandomDefaultParameters(
3338+
probability chance: Double, randomVariable: () -> Variable
3339+
)
3340+
-> (SubroutineDescriptor, [Variable])
3341+
{
3342+
var defaultParameterIndices = [Int]()
3343+
var defaultValues = [Variable]()
3344+
if self.parameters.count > 0 {
3345+
for i in 0..<self.parameters.count {
3346+
if self.parameters.hasRestParameter && i == self.parameters.count - 1 {
3347+
continue
3348+
}
3349+
if probability(chance) {
3350+
defaultParameterIndices.append(i)
3351+
defaultValues.append(randomVariable())
3352+
}
3353+
}
3354+
}
3355+
3356+
if defaultParameterIndices.isEmpty {
3357+
return (self, [])
3358+
}
3359+
let newParameters = Parameters(
3360+
count: self.parameters.count,
3361+
hasRestParameter: self.parameters.hasRestParameter,
3362+
defaultParameterIndices: defaultParameterIndices)
3363+
return (
3364+
SubroutineDescriptor(
3365+
withParameters: newParameters, ofTypes: self.parameterTypes), defaultValues
3366+
)
33323367
}
33333368

33343369
public static func parameters(_ params: Parameter...) -> SubroutineDescriptor {
@@ -3364,22 +3399,27 @@ public class ProgramBuilder {
33643399
@discardableResult
33653400
public func buildPlainFunction(
33663401
with descriptor: SubroutineDescriptor, named functionName: String? = nil,
3367-
_ body: ([Variable]) -> Void
3402+
defaultValues: [Variable] = [], _ body: ([Variable]) -> Void
33683403
) -> Variable {
3404+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
33693405
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
33703406
let instr = emit(
3371-
BeginPlainFunction(parameters: descriptor.parameters, functionName: functionName))
3407+
BeginPlainFunction(parameters: descriptor.parameters, functionName: functionName),
3408+
withInputs: defaultValues)
33723409
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
33733410
emit(EndPlainFunction())
33743411
return instr.output
33753412
}
33763413

33773414
@discardableResult
33783415
public func buildArrowFunction(
3379-
with descriptor: SubroutineDescriptor, _ body: ([Variable]) -> Void
3416+
with descriptor: SubroutineDescriptor, defaultValues: [Variable] = [],
3417+
_ body: ([Variable]) -> Void
33803418
) -> Variable {
3419+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
33813420
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
3382-
let instr = emit(BeginArrowFunction(parameters: descriptor.parameters))
3421+
let instr = emit(
3422+
BeginArrowFunction(parameters: descriptor.parameters), withInputs: defaultValues)
33833423
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
33843424
emit(EndArrowFunction())
33853425
return instr.output
@@ -3388,11 +3428,13 @@ public class ProgramBuilder {
33883428
@discardableResult
33893429
public func buildGeneratorFunction(
33903430
with descriptor: SubroutineDescriptor, named functionName: String? = nil,
3391-
_ body: ([Variable]) -> Void
3431+
defaultValues: [Variable] = [], _ body: ([Variable]) -> Void
33923432
) -> Variable {
3433+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
33933434
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
33943435
let instr = emit(
3395-
BeginGeneratorFunction(parameters: descriptor.parameters, functionName: functionName))
3436+
BeginGeneratorFunction(parameters: descriptor.parameters, functionName: functionName),
3437+
withInputs: defaultValues)
33963438
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
33973439
emit(EndGeneratorFunction())
33983440
return instr.output
@@ -3401,22 +3443,27 @@ public class ProgramBuilder {
34013443
@discardableResult
34023444
public func buildAsyncFunction(
34033445
with descriptor: SubroutineDescriptor, named functionName: String? = nil,
3404-
_ body: ([Variable]) -> Void
3446+
defaultValues: [Variable] = [], _ body: ([Variable]) -> Void
34053447
) -> Variable {
3448+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
34063449
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
34073450
let instr = emit(
3408-
BeginAsyncFunction(parameters: descriptor.parameters, functionName: functionName))
3451+
BeginAsyncFunction(parameters: descriptor.parameters, functionName: functionName),
3452+
withInputs: defaultValues)
34093453
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
34103454
emit(EndAsyncFunction())
34113455
return instr.output
34123456
}
34133457

34143458
@discardableResult
34153459
public func buildAsyncArrowFunction(
3416-
with descriptor: SubroutineDescriptor, _ body: ([Variable]) -> Void
3460+
with descriptor: SubroutineDescriptor, defaultValues: [Variable] = [],
3461+
_ body: ([Variable]) -> Void
34173462
) -> Variable {
3463+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
34183464
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
3419-
let instr = emit(BeginAsyncArrowFunction(parameters: descriptor.parameters))
3465+
let instr = emit(
3466+
BeginAsyncArrowFunction(parameters: descriptor.parameters), withInputs: defaultValues)
34203467
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
34213468
emit(EndAsyncArrowFunction())
34223469
return instr.output
@@ -3425,12 +3472,14 @@ public class ProgramBuilder {
34253472
@discardableResult
34263473
public func buildAsyncGeneratorFunction(
34273474
with descriptor: SubroutineDescriptor, named functionName: String? = nil,
3428-
_ body: ([Variable]) -> Void
3475+
defaultValues: [Variable] = [], _ body: ([Variable]) -> Void
34293476
) -> Variable {
3477+
assert(descriptor.parameters.numDefaultParameters == defaultValues.count)
34303478
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
34313479
let instr = emit(
34323480
BeginAsyncGeneratorFunction(
3433-
parameters: descriptor.parameters, functionName: functionName))
3481+
parameters: descriptor.parameters, functionName: functionName),
3482+
withInputs: defaultValues)
34343483
bodyWithRecursionGuard(instr.output) { body(Array(instr.innerOutputs)) }
34353484
emit(EndAsyncGeneratorFunction())
34363485
return instr.output

Sources/Fuzzilli/CodeGen/CodeGenerators.swift

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,11 +1504,15 @@ public let CodeGenerators: [CodeGenerator] = [
15041504
[
15051505
GeneratorStub("PlainFunctionBeginGenerator", provides: [.javascript, .subroutine]) {
15061506
b in
1507-
let randomParameters = b.randomParameters()
1507+
let (randomParameters, defaultValues) = b.randomParameters()
1508+
.withRandomDefaultParameters(
1509+
probability: 0.1,
1510+
randomVariable: { b.randomJsVariable() })
15081511
b.setParameterTypesForNextSubroutine(
15091512
randomParameters.parameterTypes)
15101513
let instr = b.emit(
1511-
BeginPlainFunction(parameters: randomParameters.parameters, functionName: nil))
1514+
BeginPlainFunction(parameters: randomParameters.parameters, functionName: nil),
1515+
withInputs: defaultValues)
15121516
if randomParameters.parameters.hasRestParameter && probability(0.2) {
15131517
b.getProperty("length", of: instr.innerOutputs.last!)
15141518
}
@@ -1532,11 +1536,15 @@ public let CodeGenerators: [CodeGenerator] = [
15321536
{ b in
15331537
// We could consider having a standalone DirectiveGenerator, but probably most of the time it won't do anything meaningful.
15341538
// We could also consider keeping a list of known directives in the JavaScriptEnvironment, but currently we only use 'use strict'.
1535-
let randomParameters = b.randomParameters()
1539+
let (randomParameters, defaultValues) = b.randomParameters()
1540+
.withRandomDefaultParameters(
1541+
probability: 0.1,
1542+
randomVariable: { b.randomJsVariable() })
15361543
b.setParameterTypesForNextSubroutine(
15371544
randomParameters.parameterTypes)
15381545
let instr = b.emit(
1539-
BeginPlainFunction(parameters: randomParameters.parameters, functionName: nil))
1546+
BeginPlainFunction(parameters: randomParameters.parameters, functionName: nil),
1547+
withInputs: defaultValues)
15401548
if randomParameters.parameters.hasRestParameter && probability(0.2) {
15411549
b.getProperty("length", of: instr.innerOutputs.last!)
15421550
}
@@ -1561,11 +1569,15 @@ public let CodeGenerators: [CodeGenerator] = [
15611569
"ArrowFunctionBeginGenerator",
15621570
provides: [.subroutine, .javascript]
15631571
) { b in
1564-
let randomParameters = b.randomParameters()
1572+
let (randomParameters, defaultValues) = b.randomParameters()
1573+
.withRandomDefaultParameters(
1574+
probability: 0.1,
1575+
randomVariable: { b.randomJsVariable() })
15651576
b.setParameterTypesForNextSubroutine(
15661577
randomParameters.parameterTypes)
15671578
let instr = b.emit(
1568-
BeginArrowFunction(parameters: randomParameters.parameters))
1579+
BeginArrowFunction(parameters: randomParameters.parameters),
1580+
withInputs: defaultValues)
15691581
if randomParameters.parameters.hasRestParameter && probability(0.2) {
15701582
b.getProperty("length", of: instr.innerOutputs.last!)
15711583
}
@@ -1586,12 +1598,16 @@ public let CodeGenerators: [CodeGenerator] = [
15861598
"GeneratorFunctionBeginGenerator",
15871599
provides: [.generatorFunction, .subroutine, .javascript]
15881600
) { b in
1589-
let randomParameters = b.randomParameters()
1601+
let (randomParameters, defaultValues) = b.randomParameters()
1602+
.withRandomDefaultParameters(
1603+
probability: 0.1,
1604+
randomVariable: { b.randomJsVariable() })
15901605
b.setParameterTypesForNextSubroutine(
15911606
randomParameters.parameterTypes)
15921607
let instr = b.emit(
15931608
BeginGeneratorFunction(
1594-
parameters: randomParameters.parameters, functionName: nil))
1609+
parameters: randomParameters.parameters, functionName: nil),
1610+
withInputs: defaultValues)
15951611
if randomParameters.parameters.hasRestParameter && probability(0.2) {
15961612
b.getProperty("length", of: instr.innerOutputs.last!)
15971613
}
@@ -1623,11 +1639,15 @@ public let CodeGenerators: [CodeGenerator] = [
16231639
GeneratorStub(
16241640
"AsyncFunctionBeginGenerator", provides: [.javascript, .subroutine, .asyncFunction]
16251641
) { b in
1626-
let randomParameters = b.randomParameters()
1642+
let (randomParameters, defaultValues) = b.randomParameters()
1643+
.withRandomDefaultParameters(
1644+
probability: 0.1,
1645+
randomVariable: { b.randomJsVariable() })
16271646
b.setParameterTypesForNextSubroutine(
16281647
randomParameters.parameterTypes)
16291648
let instr = b.emit(
1630-
BeginAsyncFunction(parameters: randomParameters.parameters, functionName: nil))
1649+
BeginAsyncFunction(parameters: randomParameters.parameters, functionName: nil),
1650+
withInputs: defaultValues)
16311651
if randomParameters.parameters.hasRestParameter && probability(0.2) {
16321652
b.getProperty("length", of: instr.innerOutputs.last!)
16331653
}
@@ -1653,12 +1673,15 @@ public let CodeGenerators: [CodeGenerator] = [
16531673
"AsyncArrowFunctionBeginGenerator",
16541674
provides: [.javascript, .asyncFunction]
16551675
) { b in
1656-
let randomParameters = b.randomParameters()
1676+
let (randomParameters, defaultValues) = b.randomParameters()
1677+
.withRandomDefaultParameters(
1678+
probability: 0.1,
1679+
randomVariable: { b.randomJsVariable() })
16571680
b.setParameterTypesForNextSubroutine(
16581681
randomParameters.parameterTypes)
16591682
let instr = b.emit(
16601683
BeginAsyncArrowFunction(
1661-
parameters: randomParameters.parameters))
1684+
parameters: randomParameters.parameters), withInputs: defaultValues)
16621685
if randomParameters.parameters.hasRestParameter && probability(0.2) {
16631686
b.getProperty("length", of: instr.innerOutputs.last!)
16641687
}
@@ -1689,12 +1712,16 @@ public let CodeGenerators: [CodeGenerator] = [
16891712
"AsyncGeneratorFunctionBeginGenerator",
16901713
provides: [.javascript, .subroutine, .asyncFunction, .generatorFunction]
16911714
) { b in
1692-
let randomParameters = b.randomParameters()
1715+
let (randomParameters, defaultValues) = b.randomParameters()
1716+
.withRandomDefaultParameters(
1717+
probability: 0.1,
1718+
randomVariable: { b.randomJsVariable() })
16931719
b.setParameterTypesForNextSubroutine(
16941720
randomParameters.parameterTypes)
16951721
let instr = b.emit(
16961722
BeginAsyncGeneratorFunction(
1697-
parameters: randomParameters.parameters, functionName: nil))
1723+
parameters: randomParameters.parameters, functionName: nil),
1724+
withInputs: defaultValues)
16981725
if randomParameters.parameters.hasRestParameter && probability(0.2) {
16991726
b.getProperty("length", of: instr.innerOutputs.last!)
17001727
}

Sources/Fuzzilli/FuzzIL/Instruction.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ extension Instruction: ProtobufConvertible {
329329
return Fuzzilli_Protobuf_Parameters.with {
330330
$0.count = UInt32(parameters.count)
331331
$0.hasRest_p = parameters.hasRestParameter
332+
$0.defaultParameterIndices = parameters.defaultParameterIndices.map(UInt32.init)
332333
}
333334
}
334335

@@ -1754,7 +1755,9 @@ extension Instruction: ProtobufConvertible {
17541755
}
17551756

17561757
func convertParameters(_ parameters: Fuzzilli_Protobuf_Parameters) -> Parameters {
1757-
return Parameters(count: Int(parameters.count), hasRestParameter: parameters.hasRest_p)
1758+
return Parameters(
1759+
count: Int(parameters.count), hasRestParameter: parameters.hasRest_p,
1760+
defaultParameterIndices: parameters.defaultParameterIndices.map(Int.init))
17581761
}
17591762

17601763
// Converts to the Wasm world global type

Sources/Fuzzilli/FuzzIL/JsOperations.swift

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,15 +1320,32 @@ public struct Parameters {
13201320
private let numParameters: UInt32
13211321
/// Whether the last parameter is a rest parameter.
13221322
let hasRestParameter: Bool
1323+
/// Indices of parameters that have a default value.
1324+
/// The n-th default parameter will be the n-th input to the BeginAnySubroutine instruction.
1325+
let defaultParameterIndices: [Int]
13231326

13241327
/// The total number of parameters. This is equivalent to the number of inner outputs produced from the parameters.
13251328
var count: Int {
13261329
return Int(numParameters)
13271330
}
13281331

1329-
init(count: Int, hasRestParameter: Bool = false) {
1332+
var numDefaultParameters: Int {
1333+
return defaultParameterIndices.count
1334+
}
1335+
1336+
init(count: Int, hasRestParameter: Bool = false, defaultParameterIndices: [Int] = []) {
1337+
assert(
1338+
!hasRestParameter || !defaultParameterIndices.contains(count - 1),
1339+
"Rest parameter cannot have a default value")
1340+
assert(
1341+
defaultParameterIndices.allSatisfy({ $0 >= 0 && $0 < count }),
1342+
"Invalid default parameter index")
1343+
assert(
1344+
defaultParameterIndices == defaultParameterIndices.sorted(),
1345+
"Default parameter indices must be sorted")
13301346
self.numParameters = UInt32(count)
13311347
self.hasRestParameter = hasRestParameter
1348+
self.defaultParameterIndices = defaultParameterIndices
13321349
}
13331350
}
13341351

@@ -1339,16 +1356,17 @@ class BeginAnySubroutine: JsOperation {
13391356
let parameters: Parameters
13401357

13411358
init(
1342-
parameters: Parameters, numInputs: Int = 0, numOutputs: Int = 0, numInnerOutputs: Int = 0,
1343-
attributes: Operation.Attributes = .isBlockStart, requiredContext: Context = .javascript,
1344-
contextOpened: Context
1359+
parameters: Parameters, numInputs: Int? = nil, numOutputs: Int = 0,
1360+
numInnerOutputs: Int = 0, attributes: Operation.Attributes = .isBlockStart,
1361+
requiredContext: Context = .javascript, contextOpened: Context
13451362
) {
13461363
assert(contextOpened.contains(.subroutine))
13471364
assert(attributes.contains(.isBlockStart))
13481365
self.parameters = parameters
13491366
super.init(
1350-
numInputs: numInputs, numOutputs: numOutputs, numInnerOutputs: numInnerOutputs,
1351-
attributes: attributes, requiredContext: requiredContext, contextOpened: contextOpened)
1367+
numInputs: numInputs ?? parameters.numDefaultParameters, numOutputs: numOutputs,
1368+
numInnerOutputs: numInnerOutputs, attributes: attributes,
1369+
requiredContext: requiredContext, contextOpened: contextOpened)
13521370
}
13531371
}
13541372

@@ -1365,7 +1383,7 @@ class BeginAnyFunction: BeginAnySubroutine {
13651383
init(parameters: Parameters, contextOpened: Context = [.javascript, .subroutine]) {
13661384
super.init(
13671385
parameters: parameters,
1368-
numInputs: 0,
1386+
numInputs: parameters.numDefaultParameters,
13691387
numOutputs: 1,
13701388
numInnerOutputs: parameters.count,
13711389
contextOpened: contextOpened)

Sources/Fuzzilli/Lifting/FuzzILLifter.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,14 @@ public class FuzzILLifter: Lifter {
408408
.beginAsyncArrowFunction(let op as BeginAnyFunction),
409409
.beginAsyncGeneratorFunction(let op as BeginAnyFunction):
410410
let params = instr.innerOutputs.map(lift).joined(separator: ", ")
411-
w.emit("\(output()) <- \(op.name) -> \(params)")
411+
let inputs =
412+
instr.inputs.isEmpty
413+
? ""
414+
: " ["
415+
+ zip(op.parameters.defaultParameterIndices, instr.inputs).map {
416+
"\($0): \(lift($1))"
417+
}.joined(separator: ", ") + "]"
418+
w.emit("\(output()) <- \(op.name)\(inputs) -> \(params)")
412419
w.increaseIndentionLevel()
413420

414421
case .endPlainFunction(let op as EndAnyFunction),

0 commit comments

Comments
 (0)