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

WebAssembly support for crucible #594

Merged
merged 4 commits into from
Jan 12, 2021
Merged

WebAssembly support for crucible #594

merged 4 commits into from
Jan 12, 2021

Conversation

robdockins
Copy link
Contributor

This PR implements a rough first cut at providing WebAssembly translation support for Crucible. Support is currently incomplete in a variety of ways. For reference, I have been following the WebAssembly 1.0 specification, which may be found here:
https://www.w3.org/TR/2019/REC-wasm-core-1-20191205 (there is a newer 1.1 spec, but it doesn't seem to have much uptake yet, and the changes seem relatively small).

What works:

  • Parsing and loading modules via "Script" format from the haskell-wasm package
  • Much of the module instantiation/linking phase
  • Instruction translations for integer value arithmetic, control flow, direct function calls and memory access
  • Running assert_return clauses of the haskell-wasm test suite

What doesn't work yet:

  • Most floating-point instructions
  • Numeric conversions
  • data segment initialization
  • table segment initialization
  • the indirect function call instruction

Other rough edges:

  • This code doesn't compile as-is without exposing more of the abstract syntax data structures from haskell-wasm. I have not yet tried to get these changes incorporated upstream
  • Error handling is a bit of a mess. Many error calls should be converted to panic, as they should be ruled out by module verification, and others should be reported in more appropriate ways.
  • Comments are currently sparse on the ground
  • No test suite yet
  • I'm not confident we are doing the correct thing WRT partial numeric instructions. We should ensure that we are making appropriate assertions regarding divide-by-zero, etc.

@robdockins
Copy link
Contributor Author

Since the initial comment, I've added support for:

  • table segments
  • data segments
  • start function execution
  • indirect function-call support with concrete index argument

Finishing indirect function call support for symbolic arguments will probably require the same work as a fix for #10, which is support for truly symbolic function handles.

@robdockins
Copy link
Contributor Author

I'd like to get some resolution to SPY/haskell-wasm#10 before we merge this, but I think this is otherwise ready to merge. I don't want this to get too out of date before merging, even though it is incomplete.

@robdockins robdockins marked this pull request as ready for review January 8, 2021 23:18
@robdockins robdockins requested a review from kquick January 9, 2021 01:26
Copy link
Member

@kquick kquick left a comment

Choose a reason for hiding this comment

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

This looks really clear and clean!

I realize it was a "pencils down" situation that stopped your work, so apologies for the comments on the todo-ish portions, but it would be good to get those into an actionable form.

Most of the rest of the comments are stylistic or suggestions, so feel free to ignore if you don't like them.

I'm looking forward to seeing this merged into crucible master!

return ss

execCommand c ss =
do liftIO $ putStrLn $ unwords ["Command not implemented", show c]
Copy link
Member

Choose a reason for hiding this comment

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

Should this be a panic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good question. I'm coming around to the idea that we should perhaps make a distinction between panic and unimplemented. In my mind, panic means the programmer has thought about this and believes that various explicit or implicit invariants mean that the situation cannot occur, and it is a programming mistake bug if the situation occurs. Whereas, unimplemented or unsupported is explicitly an acknowledgement that valid inputs can drive the program into this situation, but we just haven't written the necessary code to deal with it.

Operationally, I think unimplemented should probably raise an appropriate (potentially non-fatal) exception instead of printing the panic message and immediately exiting.

Copy link
Member

Choose a reason for hiding this comment

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

I agree that there's definitely a semantic differentiation, but is there a runtime distinction (i.e. can it be a non-fatal/recoverable exception if it's truly unimplemented)? If so, then yes, let's make an unimplemented, otherwise we can just make sure the panic message clarifies the distinction (or I guess we can make an unimplemented that does the latter).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well... for something like SAW, I guess I'd rather see some useful "unimplemented" message and end up back at the SAW prompt rather than baling out of the executable altogether like panic does.

Copy link
Member

Choose a reason for hiding this comment

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

My overall thinking relative to all the panic notes below is leaving the right breadcrumbs for both the user and the developer to know who to tell and where to fix it when these unimplemented/todo/whatever things get encountered.

As context: Comments in the code, print statements that might get lost or don't suggest there needs to be a report, or error calls that might simply result in alternatives or quietly unsatisfiable branches are mostly passive and could result in invalid analyses or a lot of debugging to figure out why something isn't working right, which is why I tend to default to a fairly agressive reaction like panic.

crucible-wasm/crucible-wasm.cabal Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm/Translate.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm/Translate.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm/Instantiate.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm/Instantiate.hs Outdated Show resolved Hide resolved
crucible-wasm/src/Lang/Crucible/Wasm/Instantiate.hs Outdated Show resolved Hide resolved
This package currently is capable of loading WebAssembly modules
and simulating a subset of concrte programs that use integer values,
control flow and memory. There is a very basic `crux` driver layer
that loads scripts from the `haskell-wasm` test suite and executes
them (only a subset of the assertions in those scripts are supported,
however).

There is plenty of work still to be done, but the existing subset
will allow some nontrivial programs to be simulated, and a bit more
crux infrastructure support would allow serious symbolic simulation
testing to begin.
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