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

Implement 0-len/drop spec changes in bulk memory #2529

Merged
merged 5 commits into from
Dec 17, 2019

Conversation

aheejin
Copy link
Member

@aheejin aheejin commented Dec 15, 2019

This implements recent bulk memory spec changes
(WebAssembly/bulk-memory-operations#126) in Binaryen. Now data.drop is
equivalent to shrinking a segment size to 0, and dropping already
dropped segments or active segments (which are thought to be dropped in
the beginning) is treated as a no-op. And all bounds checking is
performed in advance, so partial copying/filling/initializing does not
occur.

I tried to implement visitDataDrop in the interpreter as
segment.data.clear();, which is exactly what the revised spec says. I
didn't end up doing that because this also deletes all contents from
active segments, and there are cases we shouldn't do that:

  • wasm-ctor-eval shouldn't delete active segments, because it will
    store the changed contents back into segments
  • When --fuzz-exec is given to wasm-opt, it runs the module and
    compare the execution call results before and after transformations.
    But if running a module will nullify all active segments, applying
    any transformation to the module or re-running it does not make any
    sense.

Fixes #2528.

This implements recent bulk memory spec changes
(WebAssembly/bulk-memory-operations#126) in Binaryen. Now `data.drop` is
equivalent to shrinking a segment size to 0, and dropping already
dropped segments or active segments (which are thought to be dropped in
the beginning) is treated as a no-op. And all bounds checking is
performed in advance, so partial copying/filling/initializing does not
occur.

I tried to implement `visitDataDrop` in the interpreter as
`segment.data.clear();`, which is exactly what the revised spec says. I
didn't end up doing that because this also deletes all contents from
active segments, and there are cases we shouldn't do that:
- `wasm-ctor-eval` shouldn't delete active segments, because it will
  store the changed contents back into segments
- When `--fuzz-exec` is given to `wasm-opt`, it runs the module and
  compare the execution call results before and after transformations.
  But if running a module will nullify all active segments, applying
  any transformation to the module or re-running it does not make any
  sense.

Fixes WebAssembly#2528.
@aheejin aheejin requested a review from tlively December 15, 2019 14:36
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.

Nice! Thanks for doing this and sorry it was blocking you.

)
(func $bar
(drop
(loop (result i32)
(data.drop 0)
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this function tests anything useful without the data.drop. Should we just leave the data.drops in these tests?

Copy link
Member Author

Choose a reason for hiding this comment

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

After memory packing optimization, this module does not contain any segments left, so this becomes a validation error. The same for the one more removed (data.drop 0) above. Before, it was OK because we converted these data.drops to unreachables, because they tried to drop already dropped segments. But dropping the same segments repeatedly is not a trap anymore, so we shouldn't do that. (So segment 0 existed in the beginning and dropped because it was an active segment, but after transformation it does not exist anymore).

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, come to think of it, then it'd be better to just delete this function, now that it does not test anything meaningful... I already merged this :( But I'll post a follow-up patch.

Copy link
Member

Choose a reason for hiding this comment

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

Wait, are you saying that the memory packing removes the segment but keeps the data.drop around, leading to a validation error? That sounds like a bug in the memory packing pass. It should convert the data.drop to a nop or remove it instead.

Copy link
Member Author

@aheejin aheejin Dec 17, 2019

Choose a reason for hiding this comment

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

Hmm, yeah, that sounds like a new bug introduced... Is it worth fixing given that you are gonna completely overhaul the pass soon?

Copy link
Member Author

Choose a reason for hiding this comment

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

Filed a bug report anyway: #2535

@aheejin
Copy link
Member Author

aheejin commented Dec 17, 2019

Nice! Thanks for doing this and sorry it was blocking you.

Oh no it was not blocking me. I fixed this because I just thought it was a simple thing to do, and this isn't your bug either :)

@aheejin aheejin merged commit 48ccb2b into WebAssembly:master Dec 17, 2019
@aheejin aheejin deleted the bulk_mem_spec_change branch December 17, 2019 00:30
aheejin added a commit to aheejin/binaryen that referenced this pull request Dec 17, 2019
- Remove a function from memory-packing_all-features.wast, because it
  does not test anything meaningful after WebAssembly#2529.
- Rename a test file to use `--all-features`; it started failing I guess
  because `exnref` requires also reference type features, but not sure
  why it was OK so far.
aheejin added a commit that referenced this pull request Dec 17, 2019
- Remove a function from memory-packing_all-features.wast, because it
  does not test anything meaningful after #2529.
- Rename a test file to use `--all-features`; it started failing I guess
  because `exnref` requires also reference type features, but not sure
  why it was OK so far.
aheejin added a commit to aheejin/binaryen that referenced this pull request Dec 19, 2019
This does two things:
- Restore `visitDataDrop` handler deleted in WebAssembly#2529, but now we convert
  invalid `data.drop`s to not `unreachable` but `nop`. This conforms to
  the revised spec that `data.drop` on the active segment can be treated
  as a nop.
- Now `visitMemoryInit` does the same thing; its handling was missing in
  WebAssembly#2529. It drops all its arguments.

Fixes WebAssembly#2535.
aheejin added a commit to aheejin/binaryen that referenced this pull request Dec 19, 2019
This does two things:
- Restore `visitDataDrop` handler deleted in WebAssembly#2529, but now we convert
  invalid `data.drop`s to not `unreachable` but `nop`. This conforms to
  the revised spec that `data.drop` on the active segment can be treated
  as a nop.
- Now `visitMemoryInit` does the same thing; its handling was missing in
  WebAssembly#2529. It drops all its arguments.

Fixes WebAssembly#2535.
aheejin added a commit that referenced this pull request Dec 19, 2019
This does two things:
- Restore `visitDataDrop` handler deleted in #2529, but now we convert
  invalid `data.drop`s to not `unreachable` but `nop`. This conforms to
  the revised spec that `data.drop` on the active segment can be treated
  as a nop.
- Make `visitMemoryInit` trap if offset or size are not equal to 0 or if
  the dest address is out of bounds. Otherwise drop all its argument.

Fixes #2535.
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.

MemoryPacking changes d8 results
2 participants