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.
This commit is contained in:
Alex Crichton
2018-04-25 22:14:15 -07:00
parent faed98b843
commit d9a71b43db
4 changed files with 38 additions and 4 deletions

View File

@ -633,6 +633,15 @@ impl<'a> Context<'a> {
self.global(&format!("
let stack = [];
"));
if self.config.debug {
self.export("assertStackEmpty", "
function() {
if (stack.length === 0)
return;
throw new Error('stack is not currently empty');
}
");
}
}
fn expose_global_slab(&mut self) {
@ -640,6 +649,17 @@ impl<'a> Context<'a> {
return;
}
self.global(&format!("let slab = [];"));
if self.config.debug {
self.export("assertSlabEmpty", "
function() {
for (let i = 0; i < slab.length; i++) {
if (typeof(slab[i]) === 'number')
continue;
throw new Error('slab is not currently empty');
}
}
");
}
}
fn expose_global_slab_next(&mut self) {
@ -882,14 +902,14 @@ impl<'a> Context<'a> {
return;
}
self.expose_get_array_u32_from_wasm();
self.expose_get_object();
self.expose_take_object();
self.global(&format!("
function getArrayJsValueFromWasm(ptr, len) {{
const mem = getUint32Memory();
const slice = mem.slice(ptr / 4, ptr / 4 + len);
const result = [];
for (let i = 0; i < slice.length; i++) {{
result.push(getObject(slice[i]))
result.push(takeObject(slice[i]))
}}
return result;
}}

View File

@ -283,6 +283,7 @@ fn free_imports() {
#[test]
fn import_a_field() {
project()
.debug(false)
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]

View File

@ -48,11 +48,18 @@ fn project() -> Project {
("run.js".to_string(), r#"
import * as process from "process";
let wasm = import('./out');
const test = import("./test");
test.then(test => {
Promise.all([test, wasm]).then(results => {
let [test, wasm] = results;
test.test();
if (wasm.assertStackEmpty)
wasm.assertStackEmpty();
if (wasm.assertSlabEmpty)
wasm.assertSlabEmpty();
}).catch(error => {
console.error(error);
process.exit(1);

View File

@ -216,7 +216,7 @@ fn no_std() {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[wasm_bindgen(module = "./foo")]
extern {
fn test(a: &str);
@ -238,6 +238,12 @@ fn no_std() {
wasm.foo(1);
}
"#)
.file("foo.js", r#"
export class Js {
init() {
}
}
"#)
.test();
}