Skip to content

Commit d9a71b4

Browse files
committed
Assert empty JS heap/stack in tests
Turns out there was a bug when passing a vector of `JsValue` instances back to JS all objects were leaked rather than correctly removed from the global slab.
1 parent faed98b commit d9a71b4

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,13 +633,33 @@ impl<'a> Context<'a> {
633633
self.global(&format!("
634634
let stack = [];
635635
"));
636+
if self.config.debug {
637+
self.export("assertStackEmpty", "
638+
function() {
639+
if (stack.length === 0)
640+
return;
641+
throw new Error('stack is not currently empty');
642+
}
643+
");
644+
}
636645
}
637646

638647
fn expose_global_slab(&mut self) {
639648
if !self.exposed_globals.insert("slab") {
640649
return;
641650
}
642651
self.global(&format!("let slab = [];"));
652+
if self.config.debug {
653+
self.export("assertSlabEmpty", "
654+
function() {
655+
for (let i = 0; i < slab.length; i++) {
656+
if (typeof(slab[i]) === 'number')
657+
continue;
658+
throw new Error('slab is not currently empty');
659+
}
660+
}
661+
");
662+
}
643663
}
644664

645665
fn expose_global_slab_next(&mut self) {
@@ -882,14 +902,14 @@ impl<'a> Context<'a> {
882902
return;
883903
}
884904
self.expose_get_array_u32_from_wasm();
885-
self.expose_get_object();
905+
self.expose_take_object();
886906
self.global(&format!("
887907
function getArrayJsValueFromWasm(ptr, len) {{
888908
const mem = getUint32Memory();
889909
const slice = mem.slice(ptr / 4, ptr / 4 + len);
890910
const result = [];
891911
for (let i = 0; i < slice.length; i++) {{
892-
result.push(getObject(slice[i]))
912+
result.push(takeObject(slice[i]))
893913
}}
894914
return result;
895915
}}

tests/all/imports.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ fn free_imports() {
283283
#[test]
284284
fn import_a_field() {
285285
project()
286+
.debug(false)
286287
.file("src/lib.rs", r#"
287288
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
288289

tests/all/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,18 @@ fn project() -> Project {
4848

4949
("run.js".to_string(), r#"
5050
import * as process from "process";
51+
let wasm = import('./out');
5152
5253
const test = import("./test");
5354
54-
test.then(test => {
55+
Promise.all([test, wasm]).then(results => {
56+
let [test, wasm] = results;
5557
test.test();
58+
59+
if (wasm.assertStackEmpty)
60+
wasm.assertStackEmpty();
61+
if (wasm.assertSlabEmpty)
62+
wasm.assertSlabEmpty();
5663
}).catch(error => {
5764
console.error(error);
5865
process.exit(1);

tests/all/simple.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ fn no_std() {
216216
217217
use wasm_bindgen::prelude::*;
218218
219-
#[wasm_bindgen]
219+
#[wasm_bindgen(module = "./foo")]
220220
extern {
221221
fn test(a: &str);
222222
@@ -238,6 +238,12 @@ fn no_std() {
238238
wasm.foo(1);
239239
}
240240
"#)
241+
.file("foo.js", r#"
242+
export class Js {
243+
init() {
244+
}
245+
}
246+
"#)
241247
.test();
242248
}
243249

0 commit comments

Comments
 (0)