Skip to content

Commit

Permalink
[tests] adds tests for the new parameter types
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasWienand committed Feb 7, 2025
1 parent f3dbb31 commit 1d31162
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Sources/Fuzzilli/Base/ProgramBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,10 @@ public class ProgramBuilder {
let parameters = Parameters(count: parameterTypes.count, hasRestParameter: parameterTypes.hasRestParameter)
return SubroutineDescriptor(withParameters: parameters, ofTypes: parameterTypes)
}

public static func parameters(_ parameters: Parameters) -> SubroutineDescriptor {
return SubroutineDescriptor(withParameters: parameters)
}

private init(withParameters parameters: Parameters, ofTypes parameterTypes: ParameterList? = nil) {
if let types = parameterTypes {
Expand All @@ -2372,6 +2376,17 @@ public class ProgramBuilder {
return instr.output
}

@discardableResult
public func buildUnusualFunction(with parameters: Parameters, named functionName: String? = nil, _ body: ([Variable]) -> ()) -> Variable {
// Emit the BeginPlainFunction with the provided Parameters (which carry the detailed patterns).
let instr = emit(BeginPlainFunction(parameters: parameters, functionName: functionName))
if enableRecursionGuard { hide(instr.output) }
body(Array(instr.innerOutputs))
if enableRecursionGuard { unhide(instr.output) }
emit(EndPlainFunction())
return instr.output
}

@discardableResult
public func buildArrowFunction(with descriptor: SubroutineDescriptor, _ body: ([Variable]) -> ()) -> Variable {
setParameterTypesForNextSubroutine(descriptor.parameterTypes)
Expand Down
54 changes: 54 additions & 0 deletions Tests/FuzzilliTests/CompilerTests/parameters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
function functionSimple(paramA) {
console.log("paramA:", paramA);
}

function functionNoParam() {
console.log("No parameters here ...");
}

function functionWithObjectPattern(argPrimary, { keyA, keyB }) {
console.log("keyB:", keyB);
console.log("argPrimary:", argPrimary);
console.log("keyA:", keyA);
}

function functionWithArrayPattern(firstElem, [secondElem, thirdElem]) {
console.log("secondElem:", secondElem);
console.log("thirdElem:", thirdElem);
console.log("firstElem:", firstElem);
}

function functionWithNestedObjectPattern(mainArg, { nestedKey1, nestedKey2: { subKeyX, subKeyY } }) {
console.log("mainArg:", mainArg);
console.log("subKeyY:", subKeyY);
console.log("nestedKey1:", nestedKey1);
console.log("subKeyX:", subKeyX);
}

function functionWithNestedArrayPattern(primaryElem, [secondaryElem, [nestedElemX, nestedElemY]]) {
console.log("primaryElem:", primaryElem);
console.log("nestedElemY:", nestedElemY);
console.log("secondaryElem:", secondaryElem);
console.log("nestedElemX:", nestedElemX);
}

function functionWithMixedPattern(
[arrayElem1, { objKey1, objKey2 }],
{ arrKey1, arrKey2: [nestedArrElem1, nestedArrElem2] }
) {
console.log("objKey2:", objKey2);
console.log("arrKey1:", arrKey1);
console.log("nestedArrElem1:", nestedArrElem1);
console.log("objKey1:", objKey1);
console.log("arrayElem1:", arrayElem1);
console.log("nestedArrElem2:", nestedArrElem2);
}

functionWithObjectPattern("foo", { keyA: 23, keyB: 42 });
functionWithArrayPattern("bar", [9000, 9001]);
functionWithNestedObjectPattern("foo", { nestedKey1: 23, nestedKey2: { subKeyX: 100, subKeyY: 200 } });
functionWithNestedArrayPattern("bar", [9000, [9001, 9002]]);
functionWithMixedPattern(
["alpha", { objKey1: 300, objKey2: 400 }],
{ arrKey1: 500, arrKey2: [8000, 8001] }
);
39 changes: 39 additions & 0 deletions Tests/FuzzilliTests/LifterTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,45 @@ class LifterTests: XCTestCase {
XCTAssertEqual(actual, expected)
}

func testUnusualFunctionLifting() {
let fuzzer = makeMockFuzzer()
let b = fuzzer.makeBuilder()

// numVariables refers to the number of parameters after destructuring, i.e. the local variables in the function.
let numVariables = 5
let objPattern: ParameterPattern = .object(properties: [
("a", .identifier),
("b", .identifier)
])
let arrPattern: ParameterPattern = .array(elements: [.identifier, .identifier])
let restElem: ParameterPattern = .rest(.identifier)
let params = Parameters(count: numVariables, patterns: [objPattern, arrPattern, restElem], hasRestParameter: false)


let f = b.buildUnusualFunction(with: params) { args in
b.doReturn(b.createArray(with: [args[0], args[1], args[2], args[3], args[4]]))
}

let objArg: Variable = b.createObject(with: ["a" : b.loadInt(1337), "b" : b.loadInt(42)])
let arrArg: Variable = b.createArray(with: [b.loadInt(9000), b.loadInt(9001)])
let arrArg2: Variable = b.createArray(with: [b.loadInt(8000), b.loadInt(8001)])

b.callFunction(f, withArgs: [objArg, arrArg, arrArg2])


let program = b.finalize()
let actual = fuzzer.lifter.lift(program)

let expected = """
function f0({ a: a1, b: a2 }, [a3, a4], ...a5) {
return [a1,a2,a3,a4,a5];
}
f0({ a: 1337, b: 42 }, [9000,9001], [8000,8001]);
"""
XCTAssertEqual(actual, expected)
}

func testConditionalOperationLifting() {
let fuzzer = makeMockFuzzer()
let b = fuzzer.makeBuilder()
Expand Down

0 comments on commit 1d31162

Please sign in to comment.