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

Fuzzer: Add a pass to prune illegal imports and exports for JS #6312

Merged
merged 12 commits into from
Feb 21, 2024

Conversation

kripken
Copy link
Member

@kripken kripken commented Feb 15, 2024

We already have passes to legalize i64 imports and exports, which the fuzzer will
run so that we can run wasm files in JS VMs. SIMD and multivalue also pose a
problem as they trap on the boundary. In principle we could legalize them as well,
but that is substantial effort, so instead just prune them: given a wasm module,
remove any imports or exports that use SIMD or multivalue (or anything else that
is not legal for JS).

Running this in the fuzzer will allow us to not skip running v8 on any testcase we
enable SIMD and multivalue for.

Also remove the limitation on running v8 with multimemory (v8 now supports
that).

@kripken kripken requested review from tlively and aheejin February 15, 2024 01:21
Comment on lines +57 to +61
// JS cannot log v128 values (we trap on the boundary), but we must still
// provide an import so that we do not trap during linking. (Alternatively,
// we could avoid running JS on code with SIMD in it, but it is useful to
// fuzz such code as much as we can.)
'log-v128': logValue,
Copy link
Member

Choose a reason for hiding this comment

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

Then what does it print for v128?

Copy link
Member Author

Choose a reason for hiding this comment

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

It will trap atm if it is called. But this is forward-looking in that if the JS-wasm spec some day allows this without trapping - maybe it becomes a JS array of 4 elements? - then it would print that JS value.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

I'm not sure we need to be pruning multivalue, and if we don't, would it be worth just adding legalization logic for v128?

@@ -29,6 +29,11 @@
// across modules, we still want to legalize dynCalls so JS can call into the
// tables even to a signature that is not legal.
//
// Another variation also "prunes" imports and exports that we cannot yet
// legalize, like exports and imports with SIMD or multivalue. Until we write
Copy link
Member

Choose a reason for hiding this comment

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

Why would we need to legalize or prune out multivalue? We should only be testing on JS engines that fully support it, right?

Comment on lines +420 to +421
func->body =
builder.makeConstantExpression(Literal::makeZeros(sig.results));
Copy link
Member

Choose a reason for hiding this comment

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

What if the result type is not defaultable?

Copy link
Member Author

Choose a reason for hiding this comment

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

Then we'd be in trouble, but we already avoid this situation in the fuzzer because it is a problem in general: We can't send a non-null reference from JS. So the fuzzer fixes that up.

@kripken
Copy link
Member Author

kripken commented Feb 20, 2024

I'm not sure we need to be pruning multivalue

We need to prune it because JS will trap if you call an export returning a multivalue like i32 i32.

@kripken
Copy link
Member Author

kripken commented Feb 21, 2024

Looks like multivalue support for exports was added in node 16. I guess we could limit ourselves to only fuzzing that and onwards, but it seems simpler for now to just fix up things to run in all node. I added a comment.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

How far back before Node 16 do you get before you run into something else we don't support like threads or nontrapping-fp-to-int? Is there really much benefit to fuzzing older nodes?

LGTM, though, if you think there is a benefit.

@kripken
Copy link
Member Author

kripken commented Feb 21, 2024

Agreed the benefit isn't very large. Though without this PR I now realize we'd also need to add code to properly receive multivalues on the JS side, compare them between VMs, etc., so this PR allows deferring some work. Worth doing all that but my main goal atm is GC fuzzing.

@kripken kripken merged commit 1441bcb into WebAssembly:main Feb 21, 2024
14 checks passed
@kripken kripken deleted the fuzz.and.prune branch February 21, 2024 00:49
radekdoulik pushed a commit to dotnet/binaryen that referenced this pull request Jul 12, 2024
…sembly#6312)

We already have passes to legalize i64 imports and exports, which the fuzzer will
run so that we can run wasm files in JS VMs. SIMD and multivalue also pose a
problem as they trap on the boundary. In principle we could legalize them as well,
but that is substantial effort, so instead just prune them: given a wasm module,
remove any imports or exports that use SIMD or multivalue (or anything else that
is not legal for JS).

Running this in the fuzzer will allow us to not skip running v8 on any testcase we
enable SIMD and multivalue for.

(Multivalue is allowed in newer VMs, so that part of this PR could be removed
eventually.)

Also remove the limitation on running v8 with multimemory (v8 now supports
that).
@gkdn gkdn mentioned this pull request Aug 31, 2024
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.

3 participants