Skip to content

Commit 2529bb0

Browse files
authored
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
2 parents 1807de7 + 8fd5f4e commit 2529bb0

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

crates/cli-support/src/js/binding.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,20 @@ impl<'a, 'b> Builder<'a, 'b> {
138138
// method, so the leading parameter is the this pointer stored on
139139
// the JS object, so synthesize that here.
140140
match self.method {
141-
Some(true) => {
141+
Some(consumes_self) => {
142142
drop(webidl_params.next());
143-
self.args_prelude.push_str("const ptr = this.ptr;\n");
144-
self.args_prelude.push_str("this.ptr = 0;\n");
145-
arg_names.push("ptr".to_string());
146-
}
147-
Some(false) => {
148-
drop(webidl_params.next());
149-
arg_names.push("this.ptr".to_string());
143+
if self.cx.config.debug {
144+
self.args_prelude.push_str(
145+
"if (this.ptr == 0) throw new Error('Attempt to use a moved value');\n",
146+
);
147+
}
148+
if consumes_self {
149+
self.args_prelude.push_str("const ptr = this.ptr;\n");
150+
self.args_prelude.push_str("this.ptr = 0;\n");
151+
arg_names.push("ptr".to_string());
152+
} else {
153+
arg_names.push("this.ptr".to_string());
154+
}
150155
}
151156
None => {}
152157
}

tests/wasm/validate_prt.js

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
const wasm = require('wasm-bindgen-test.js');
22
const assert = require('assert');
33

4+
// NB: `wasm-pack` uses the presence of checks for moved values as a way to test
5+
// whether it is correctly enabling `--debug` when configured to do so, so don't
6+
// change this expected debug output without also updating `wasm-pack`'s tests.
7+
const assertMovedPtrThrows = process.env.WASM_BINDGEN_NO_DEBUG == null
8+
? f => assert.throws(f, /Attempt to use a moved value/)
9+
: f => assert.throws(f, /null pointer passed to rust/);
10+
411
const useMoved = () => {
512
const apple = new wasm.Fruit('apple');
613
apple.name();
714
wasm.eat(apple);
8-
assert.throws(() => apple.name(),
9-
/Attempt to use a moved value|null pointer passed to rust/);
15+
assertMovedPtrThrows(() => apple.name());
1016
};
1117

1218
const moveMoved = () => {
1319
const pear = new wasm.Fruit('pear');
1420
pear.name();
1521
wasm.eat(pear);
16-
assert.throws(() => wasm.eat(pear),
17-
/Attempt to use a moved value|null pointer passed to rust/);
22+
assertMovedPtrThrows(() => wasm.eat(pear));
23+
};
24+
25+
const methodMoved = () => {
26+
const quince = new wasm.Fruit('quince');
27+
quince.name();
28+
quince.rot();
29+
assertMovedPtrThrows(() => quince.rot());
1830
};
1931

2032
exports.js_works = () => {
2133
useMoved();
2234
moveMoved();
35+
methodMoved();
2336
};

tests/wasm/validate_prt.rs

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ impl Fruit {
2121
pub fn new(name: String) -> Self {
2222
Fruit { name }
2323
}
24+
25+
pub fn rot(self) {
26+
drop(self);
27+
}
2428
}
2529

2630
#[wasm_bindgen]

0 commit comments

Comments
 (0)