-
Notifications
You must be signed in to change notification settings - Fork 27
[exec] Bounds check bulk-memory before execution #123
Conversation
I would also be interested in updating the spec-text as well, but will need some guidance. Right now the instructions are implemented by lowering to plain i32.load8_u/i32.store8's for memory and table.get/table.set for tables. I think there are a couple options here.
I think all of these can be equivalent in the single-threaded case, but I'm having a hard time reasoning about the implications for threading. |
Hi @eqrion, thanks for moving forward with this. Turns out we were in a race. :) I had started on a similar patch last week but didn't get to finish the spec part yet. I uploaded it here so that we can compare. But mine is more WIP. In particular, I did not properly fix the test generators. And I only started on the spec itself. So we should probably go with yours instead. However, one relevant difference is that I kept and adapted the small-step semantics for the interpreter instead of going back to monolithic implementations. This is important for two reasons: (1) the interpreter should match the spec rules, and (2) the rules need to use small-step in order to be forward-compatible with the threads proposal, where bulk ops are no longer atomic operations. How would you feel about incorporating my interpreter implementation into your patch? |
Ah apologies about the duplicated effort, I should have posted that I was taking a look at this. :) Good to know about needing the small-step semantics, I think that was what I was getting at with my question. I'll adapt your interpreter implementation into my patch. |
Cool, thanks! Forgot one thing. You mentioned:
This actually was an intentional fix in #115. The rationale being that accessing a dropped segment is equivalent to an out-of-bounds access, because a dropped segment is essentially a segment shrunk to size 0. A zero-length access should therefore behave consistently with no effect. |
Ah, I believe the exec-text for Spidermonkey will also need an update for this, as we will trap in this case. |
On further examination, it appears that the formal rules are correct and the prose is what may need an update. |
Ah, I see. If you want, please feel free to fix this as part of this PR. |
b48f259
to
0a57f0f
Compare
I've updated the interpreter commit to use your patch, keep the small step semantics, and extend early bounds checking to the table operations. That commit should be good to go. I've also added a commit for the dropped segments issue, and started looking at the spec text. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
0a57f0f
to
ca594d9
Compare
Spec issue: WebAssembly#111 This commit changes the semantics of bulk-memory instructions to perform an upfront bounds check and trap if any access would be out-of-bounds without writing. This affects the following: * memory.init/copy/fill * table.init/copy (fill requires reftypes) * data segment init (lowers to memory.init) * elem segment init (lowers to table.init)
The formal rules (and interpreter) allow 'memory/table.init' when the count = 0. The prose specifies a trap before checking if count = 0.
ca594d9
to
766a295
Compare
@rossberg Is this ready to go now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks!
Thanks! |
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated. 3. nullref is now permitted in the text and binary format.
The two primary changes involved are: 1. Removal of `assert_return_canonical_nan`/`arithetic nan` in favor of special `nan:canonical`/`nan:arithmetic` constants that can only be used in test expectations. See: WebAssembly/spec#1104 2. New trapping behaviour for bulk memory operations. Range checks are now performed up front for opterations such as memory.fill and memory.copy. See: WebAssembly/bulk-memory-operations#111 And: WebAssembly/bulk-memory-operations#123 The old behaviour is still kept around to support table.fill which is defined in reference-types proposal and has yet to be updated.
Spec issue: #111
This commit changes the semantics of bulk-memory instructions to perform
an upfront bounds check and trap if any access would be out-of-bounds without
writing.
This affects the following:
This commit corrects an edge case where a memory/table.init with zero
length wouldn't trap even if the data/elem segment had been dropped.
This was due to an extra pattern in eval that would match zero-length
instructions and not check if the segment had been dropped. One test
case in bulk.wast had to be changed for this.