Merge pull request #1670 from fitzgen/check-for-use-after-move-in-methods

Check for use-after-move in JS glue when `--debug` is enabled again
This commit is contained in:
Alex Crichton 2019-07-17 10:07:01 -05:00 committed by GitHub
commit 2529bb0b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 12 deletions

View File

@ -138,15 +138,20 @@ impl<'a, 'b> Builder<'a, 'b> {
// method, so the leading parameter is the this pointer stored on // method, so the leading parameter is the this pointer stored on
// the JS object, so synthesize that here. // the JS object, so synthesize that here.
match self.method { match self.method {
Some(true) => { Some(consumes_self) => {
drop(webidl_params.next()); drop(webidl_params.next());
self.args_prelude.push_str("const ptr = this.ptr;\n"); if self.cx.config.debug {
self.args_prelude.push_str("this.ptr = 0;\n"); self.args_prelude.push_str(
arg_names.push("ptr".to_string()); "if (this.ptr == 0) throw new Error('Attempt to use a moved value');\n",
} );
Some(false) => { }
drop(webidl_params.next()); if consumes_self {
arg_names.push("this.ptr".to_string()); self.args_prelude.push_str("const ptr = this.ptr;\n");
self.args_prelude.push_str("this.ptr = 0;\n");
arg_names.push("ptr".to_string());
} else {
arg_names.push("this.ptr".to_string());
}
} }
None => {} None => {}
} }

View File

@ -1,23 +1,36 @@
const wasm = require('wasm-bindgen-test.js'); const wasm = require('wasm-bindgen-test.js');
const assert = require('assert'); const assert = require('assert');
// NB: `wasm-pack` uses the presence of checks for moved values as a way to test
// whether it is correctly enabling `--debug` when configured to do so, so don't
// change this expected debug output without also updating `wasm-pack`'s tests.
const assertMovedPtrThrows = process.env.WASM_BINDGEN_NO_DEBUG == null
? f => assert.throws(f, /Attempt to use a moved value/)
: f => assert.throws(f, /null pointer passed to rust/);
const useMoved = () => { const useMoved = () => {
const apple = new wasm.Fruit('apple'); const apple = new wasm.Fruit('apple');
apple.name(); apple.name();
wasm.eat(apple); wasm.eat(apple);
assert.throws(() => apple.name(), assertMovedPtrThrows(() => apple.name());
/Attempt to use a moved value|null pointer passed to rust/);
}; };
const moveMoved = () => { const moveMoved = () => {
const pear = new wasm.Fruit('pear'); const pear = new wasm.Fruit('pear');
pear.name(); pear.name();
wasm.eat(pear); wasm.eat(pear);
assert.throws(() => wasm.eat(pear), assertMovedPtrThrows(() => wasm.eat(pear));
/Attempt to use a moved value|null pointer passed to rust/); };
const methodMoved = () => {
const quince = new wasm.Fruit('quince');
quince.name();
quince.rot();
assertMovedPtrThrows(() => quince.rot());
}; };
exports.js_works = () => { exports.js_works = () => {
useMoved(); useMoved();
moveMoved(); moveMoved();
methodMoved();
}; };

View File

@ -21,6 +21,10 @@ impl Fruit {
pub fn new(name: String) -> Self { pub fn new(name: String) -> Self {
Fruit { name } Fruit { name }
} }
pub fn rot(self) {
drop(self);
}
} }
#[wasm_bindgen] #[wasm_bindgen]