Skip to content

Add test for consuming interface types inputs #1900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ jobs:
# - template: ci/azure-install-sccache.yml
- script: rustup target add wasm32-unknown-unknown
displayName: "install wasm target"
- task: NodeTool@0
inputs:
versionSpec: '>=13.0'
- script: cargo test -p wasm-bindgen-cli-support
displayName: "wasm-bindgen-cli-support tests"
- script: cargo test -p wasm-bindgen-cli
Expand Down
6 changes: 4 additions & 2 deletions crates/cli-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ Shared support for the wasm-bindgen-cli package, an internal dependency
edition = '2018'

[dependencies]
base64 = "0.9"
anyhow = "1.0"
base64 = "0.9"
log = "0.4"
rustc-demangle = "0.1.13"
serde_json = "1.0"
tempfile = "3.0"
walrus = "0.14.0"
wasm-bindgen-anyref-xform = { path = '../anyref-xform', version = '=0.2.55' }
wasm-bindgen-shared = { path = "../shared", version = '=0.2.55' }
wasm-bindgen-multi-value-xform = { path = '../multi-value-xform', version = '=0.2.55' }
wasm-bindgen-shared = { path = "../shared", version = '=0.2.55' }
wasm-bindgen-threads-xform = { path = '../threads-xform', version = '=0.2.55' }
wasm-bindgen-wasm-conventions = { path = '../wasm-conventions', version = '=0.2.55' }
wasm-bindgen-wasm-interpreter = { path = "../wasm-interpreter", version = '=0.2.55' }
wit-text = "0.1.1"
wit-walrus = "0.1.0"
wit-validator = "0.1.0"
6 changes: 4 additions & 2 deletions crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ impl Bindgen {
(mem::replace(m, blank_module), &name[..])
}
Input::Path(ref path) => {
let contents = fs::read(&path)
let wasm = wit_text::parse_file(&path)
.with_context(|| format!("failed to read `{}`", path.display()))?;
wit_validator::validate(&wasm)
.with_context(|| format!("failed to validate `{}`", path.display()))?;
let module = walrus::ModuleConfig::new()
// Skip validation of the module as LLVM's output is
// generally already well-formed and so we won't gain much
Expand All @@ -278,7 +280,7 @@ impl Bindgen {
.generate_name_section(!self.remove_name_section)
.generate_producers_section(!self.remove_producers_section)
.on_parse(wit_walrus::on_parse)
.parse(&contents)
.parse(&wasm)
.context("failed to parse input file as wasm")?;
let stem = match &self.out_name {
Some(name) => &name,
Expand Down
4 changes: 2 additions & 2 deletions crates/cli-support/src/wit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ pub fn process(

impl<'a> Context<'a> {
fn init(&mut self) -> Result<(), Error> {
let stack_pointer = wasm_bindgen_wasm_conventions::get_shadow_stack_pointer(self.module)?;
self.aux.shadow_stack_pointer = Some(stack_pointer);
self.aux.shadow_stack_pointer =
wasm_bindgen_wasm_conventions::get_shadow_stack_pointer(self.module);

// Make a map from string name to ids of all exports
for export in self.module.exports.iter() {
Expand Down
5 changes: 5 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,17 @@ rayon = "1.0"
tempfile = "3.0"
walrus = "0.14"
wit-printer = "0.1"
wit-text = "0.1"
wit-validator = "0.1"
wit-walrus = "0.1"

[[test]]
name = "reference"
harness = false

[[test]]
name = "interface-types"
harness = false

[features]
vendored-openssl = ['openssl/vendored']
85 changes: 85 additions & 0 deletions crates/cli/tests/interface-types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use anyhow::{bail, Result};
use assert_cmd::prelude::*;
use rayon::prelude::*;
use std::env;
use std::path::Path;
use std::process::Command;

fn main() -> Result<()> {
let filter = env::args().nth(1);

let mut tests = Vec::new();
let dir = env::current_dir()?.join("tests/interface-types");
for entry in dir.read_dir()? {
let path = entry?.path();
if path.extension().and_then(|s| s.to_str()) != Some("wit") {
continue;
}
if let Some(filter) = &filter {
if !path.display().to_string().contains(filter) {
continue;
}
}
tests.push(path);
}
tests.sort();

let errs = tests
.par_iter()
.filter_map(|t| runtest(t).err().map(|e| (t, e)))
.collect::<Vec<_>>();

if errs.len() == 0 {
println!("{} tests passed", tests.len());
return Ok(());
}
eprintln!("failed tests:\n");
for (test, err) in errs {
eprintln!("{} failure\n{}", test.display(), tab(&format!("{:?}", err)));
}
bail!("tests failed");
}

fn runtest(test: &Path) -> Result<()> {
let js = test.with_extension("js");
let td = tempfile::TempDir::new()?;

let mut bindgen = Command::cargo_bin("wasm-bindgen")?;
bindgen
.arg("--out-dir")
.arg(td.path())
.arg(test)
.arg("--out-name=wasm")
.arg("--nodejs")
.arg("--no-typescript");
exec(&mut bindgen)?;

exec(Command::new("node")
.arg("--experimental-wasm-anyref")
.arg("--experimental-wasm-mv")
.arg(&js).env("NODE_PATH", td.path()))?;

Ok(())
}

fn exec(cmd: &mut Command) -> Result<()> {
let output = cmd.output()?;
if output.status.success() {
return Ok(());
}
let mut err = format!("command failed {:?}", cmd);
err.push_str(&format!("\nstatus: {}", output.status));
err.push_str(&format!(
"\nstderr:\n{}",
tab(&String::from_utf8_lossy(&output.stderr))
));
err.push_str(&format!(
"\nstdout:\n{}",
tab(&String::from_utf8_lossy(&output.stdout))
));
bail!("{}", err);
}

fn tab(s: &str) -> String {
format!(" {}", s.replace("\n", "\n "))
}
16 changes: 16 additions & 0 deletions crates/cli/tests/interface-types/anyref.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const assert = require('assert');
const wasm = require('wasm');

const obj = {};
assert.strictEqual(wasm.foo(obj), obj);

wasm.store('x');
assert.strictEqual(wasm.load(), 'x');

const obj2 = {};
wasm.store(obj2);
assert.strictEqual(wasm.load(), obj2);
assert.strictEqual(wasm.load(), obj2);

wasm.store(undefined);
assert.strictEqual(wasm.load(), undefined);
26 changes: 26 additions & 0 deletions crates/cli/tests/interface-types/anyref.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(module
(func $foo (param anyref) (result anyref)
local.get 0)

(func $store (param anyref)
i32.const 0
local.get 0
table.set 0)

(func $load (result anyref)
i32.const 0
table.get 0)

(table 1 anyref)

(@interface func (export "foo") (param anyref) (result anyref)
arg.get 0
call-core $foo)

(@interface func (export "store") (param anyref)
arg.get 0
call-core $store)

(@interface func (export "load") (result anyref)
call-core $load)
)
5 changes: 5 additions & 0 deletions crates/cli/tests/interface-types/defer-call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const wasm = require('wasm');
const assert = require('assert');

assert.strictEqual(wasm.foo(), 0);
assert.strictEqual(wasm.get(), 1);
21 changes: 21 additions & 0 deletions crates/cli/tests/interface-types/defer-call.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(module
(global $ctr (mut i32) (i32.const 0))

(func $increment
global.get $ctr
i32.const 1
i32.add
global.set $ctr)

(func $get (result i32)
global.get $ctr)

(@interface func (export "foo") (result s32)
defer-call-core $increment
call-core $get
i32-to-s32)

(@interface func (export "get") (result s32)
call-core $get
i32-to-s32)
)
2 changes: 2 additions & 0 deletions crates/cli/tests/interface-types/empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const m = require('wasm');

1 change: 1 addition & 0 deletions crates/cli/tests/interface-types/empty.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(module)
9 changes: 9 additions & 0 deletions crates/cli/tests/interface-types/integers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const assert = require('assert');
const wasm = require('wasm');

assert.strictEqual(wasm.add_i8(0, 1), 1);
assert.strictEqual(wasm.add_u8(0, 1), 1);
assert.strictEqual(wasm.add_i16(0, 1), 1);
assert.strictEqual(wasm.add_u16(0, 1), 1);
assert.strictEqual(wasm.add_i32(0, 1), 1);
assert.strictEqual(wasm.add_u32(0, 1), 1);
54 changes: 54 additions & 0 deletions crates/cli/tests/interface-types/integers.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(module
(func $add_i32 (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add)

(@interface func (export "add_i8") (param s8) (param s8) (result s8)
arg.get 0
s8-to-i32
arg.get 1
s8-to-i32
call-core $add_i32
i32-to-s8)

(@interface func (export "add_i16") (param s16) (param s16) (result s16)
arg.get 0
s16-to-i32
arg.get 1
s16-to-i32
call-core $add_i32
i32-to-s16)

(@interface func (export "add_i32") (param s32) (param s32) (result s32)
arg.get 0
s32-to-i32
arg.get 1
s32-to-i32
call-core $add_i32
i32-to-s32)

(@interface func (export "add_u8") (param s8) (param s8) (result s8)
arg.get 0
s8-to-i32
arg.get 1
s8-to-i32
call-core $add_i32
i32-to-s8)

(@interface func (export "add_u16") (param u16) (param u16) (result u16)
arg.get 0
u16-to-i32
arg.get 1
u16-to-i32
call-core $add_i32
i32-to-u16)

(@interface func (export "add_u32") (param u32) (param u32) (result u32)
arg.get 0
u32-to-i32
arg.get 1
u32-to-i32
call-core $add_i32
i32-to-u32)
)
5 changes: 5 additions & 0 deletions crates/cli/tests/interface-types/memory-to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const wasm = require('wasm');
const assert = require('assert');

assert.strictEqual(wasm.foo(), 'foo');
assert.strictEqual(wasm.hexa(), 'hexa');
21 changes: 21 additions & 0 deletions crates/cli/tests/interface-types/memory-to-string.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(module
(memory 1)

(func $foo (result i32 i32)
i32.const 0
i32.const 3)
(func $hexa (result i32 i32)
i32.const 10
i32.const 4)

(data (i32.const 0) "foo")
(data (i32.const 10) "hexa")

(@interface func (export "foo") (result string)
call-core $foo
memory-to-string)

(@interface func (export "hexa") (result string)
call-core $hexa
memory-to-string)
)
5 changes: 5 additions & 0 deletions crates/cli/tests/interface-types/no-wasm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const assert = require('assert');
const wasm = require('wasm');

wasm.nop();
assert.strictEqual(wasm.roundtrip(1), 1);
5 changes: 5 additions & 0 deletions crates/cli/tests/interface-types/no-wasm.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(module
(@interface func (export "nop"))
(@interface func (export "roundtrip") (param s32) (result s32)
arg.get 0)
)
11 changes: 11 additions & 0 deletions crates/cli/tests/interface-types/string-to-memory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const wasm = require('wasm');
const assert = require('assert');

const test = s => {
wasm.set(s);
assert.strictEqual(s, wasm.get());
};

test('');
test('x');
test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
27 changes: 27 additions & 0 deletions crates/cli/tests/interface-types/string-to-memory.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
(module
(memory 1)

(global $glen (mut i32) (i32.const 0))
(global $gptr (mut i32) (i32.const 0))

(func $malloc (param i32) (result i32) i32.const 23)

(func $set (param $ptr i32) (param $len i32)
local.get $ptr
global.set $gptr
local.get $len
global.set $glen)

(func $get (result i32 i32)
global.get $gptr
global.get $glen)

(@interface func (export "set") (param string)
arg.get 0
string-to-memory $malloc
call-core $set)

(@interface func (export "get") (result string)
call-core $get
memory-to-string)
)
3 changes: 2 additions & 1 deletion crates/threads-xform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ impl Config {
}

let memory = wasm_conventions::get_memory(module)?;
let stack_pointer = wasm_conventions::get_shadow_stack_pointer(module)?;
let stack_pointer = wasm_conventions::get_shadow_stack_pointer(module)
.ok_or_else(|| anyhow!("failed to find shadow stack pointer"))?;
let addr = allocate_static_data(module, memory, 4, 4)?;
let zero = InitExpr::Value(Value::I32(0));
let globals = Globals {
Expand Down
Loading