Skip to content

Commit

Permalink
Feature/array spread (#447)
Browse files Browse the repository at this point in the history
* Implements compilation of arrays with spreading
* Implements test cases for arrays with spreading
  • Loading branch information
TobiasWienand authored Sep 30, 2024
1 parent d9b7550 commit 0e20cd5
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
16 changes: 14 additions & 2 deletions Sources/Fuzzilli/Compiler/Compiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -833,17 +833,29 @@ public class JavaScriptCompiler {
case .arrayExpression(let arrayExpression):
var elements = [Variable]()
var undefined: Variable? = nil
var spreads = [Bool]()
for elem in arrayExpression.elements {
if elem.expression == nil {
if undefined == nil {
undefined = emit(LoadUndefined()).output
}
elements.append(undefined!)
spreads.append(false)
} else {
elements.append(try compileExpression(elem))
if case .spreadElement(let spreadElement) = elem.expression {
elements.append(try compileExpression(spreadElement.argument))
spreads.append(true)
} else {
elements.append(try compileExpression(elem))
spreads.append(false)
}
}
}
return emit(CreateArray(numInitialValues: elements.count), withInputs: elements).output
if spreads.contains(true) {
return emit(CreateArrayWithSpread(spreads: spreads), withInputs: elements).output
} else {
return emit(CreateArray(numInitialValues: elements.count), withInputs: elements).output
}

case .functionExpression(let functionExpression):
let parameters = convertParameters(functionExpression.parameters)
Expand Down
27 changes: 25 additions & 2 deletions Tests/FuzzilliTests/CompilerTests/spreading.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function foo(a, b, c) {
output(c);
}

let a = [1,2,3,4];
let a = [1, 2, 3, 4];

foo(...a);
foo(100, ...a);
Expand All @@ -24,4 +24,27 @@ o.foo(100, ...a);
o.foo(100, 101, ...a);
o.foo(100, 101, 102, ...a);

// TODO also add tests for spreading in array literals
// Array spreading tests
let array1 = [10, 20, 30];
let array2 = [...array1];

output(array1);
output(array2);

array1[0] = 100;
output(array1);
output(array2);

let combinedArray = [5, ...array1, 50];
output(combinedArray);

// Spread with array-like objects
function testArguments() {
let argsArray = [...arguments];
output(argsArray);
}

testArguments(1, 2, 3);

let nestedArray = [...[...[1, 2, 3]], ...[4, 5]];
output(nestedArray);

0 comments on commit 0e20cd5

Please sign in to comment.