Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DestructArray and DestructArrayAndReassign operations #300

Merged
merged 9 commits into from
Nov 21, 2021

Conversation

amarekano
Copy link
Contributor

@amarekano amarekano commented Nov 14, 2021

This implementation currently does not support the following JS constructs:

  • Nested arrays (i.e. [[a,b],c] = arr) To be handled during compilation
  • holes (i.e [a,,b] = arr)
  • rest element (i.e. [a, ...b] = arr)

Copy link
Collaborator

@saelo saelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! The main thing I'm still wondering about is whether we really need the AndReassign variant of this. On the one hand, it most likely gets converted early on in the JS pipeline into a destruct and regular reassignments, so probably doesn't really cover any new code. On the other hand, compiling a destruct + reassign to a normal destruct and a bunch of reassignments is kind of inefficient, and so if that happens frequently enough, it's probably worth keeping the additional instruction for that. WDYT?

Sources/Fuzzilli/Core/CodeGenerators.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/FuzzIL/Operations.swift Show resolved Hide resolved
Sources/Fuzzilli/Lifting/JavaScriptLifter.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/Protobuf/program.pb.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/FuzzIL/Operations.swift Show resolved Hide resolved
Sources/Fuzzilli/Lifting/FuzzILLifter.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/Core/CodeGenerators.swift Show resolved Hide resolved
@amarekano
Copy link
Contributor Author

amarekano commented Nov 19, 2021

The main thing I'm still wondering about is whether we really need the AndReassign variant of this.

Let me compare the bytecode generate from destruct + reassign and destruct with multiple assignments. Perhaps we can take a decision using that data.

@amarekano
Copy link
Contributor Author

I think we should support the AndReassign variant for a couple of reasons: the first being that this op generates more interesting bytecode compared to just using simple reassignments. Here's two programs that I've used to test this:

const v4 = [15,30,"Hello"];
let v5 = 1000;
[v5] = v4;

//VS

const v4 = [15,30,"Hello"];
let v5 = 1000;
v5 = v4[0];

The bc from the two samples are linked below:
bc_with_destruct_array.log
bc_without_destruct_array.log

The second reason is that handling restElement assignments would become tricky. Thinking off the top of my head, I imagine you'd need to introduce a loop (or some slice operation) that would simulate the same reassignment, which would change the semantics of the program.

@amarekano
Copy link
Contributor Author

Wrt to nested arrays in destruct operations, I think we can handle this during compilation using temporary variables. For example, if we have the following program:

let [x,[a,b]] = [1,[2,3]]

we can re-write this during compilation to:

let [x, _temp0] = [1,[2,3]]
let [a,b] = _temp0

Diffing the bytecode dumps from the orginal and modified sample above doesn't reveal a significant difference so I think we should be fine on that front as well.

All other review comments have been addressed so we should be good to go here. Let me know if you'd like me to incorporate any other changes or improvements.

Copy link
Collaborator

@saelo saelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool thanks, that makes sense, so let's keep both variants!

Sources/Fuzzilli/Lifting/FuzzILLifter.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/Lifting/JavaScriptLifter.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/Protobuf/operations.pb.swift Show resolved Hide resolved
return Array(outputs)
}

public func destructAndReassign(_ candidates: [Variable], atIndices indices: [Int], from input: Variable, hasRestElement: Bool = false) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe change signature to something like destructAndReassign(_ input: Variable, selecting indices: [Int], into: outputs [Variable], hasRestElement: Bool) to better match destruct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thoughts on renaming this function to just destruct and updating the signature as you've suggested?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, that works as well!

Sources/Fuzzilli/Mutators/OperationMutator.swift Outdated Show resolved Hide resolved
Sources/Fuzzilli/Core/CodeGenerators.swift Outdated Show resolved Hide resolved
@saelo saelo merged commit c41b205 into googleprojectzero:main Nov 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants