Convert some WebAssembly run-make tests to Rust

This commit rewrites a number of `run-make` tests centered around wasm
to instead use `rmake.rs` and additionally use the `wasm32-wasip1`
target instead of `wasm32-unknown-unknown`. Testing no longer requires
Node.js and additionally uses the `wasmparser` crate from crates.io to
parse outputs and power assertions.
This commit is contained in:
Alex Crichton 2024-03-06 12:39:07 -08:00
parent d255c6a57c
commit 7141379559
35 changed files with 439 additions and 336 deletions

View File

@ -3298,6 +3298,9 @@ dependencies = [
[[package]]
name = "run_make_support"
version = "0.0.0"
dependencies = [
"wasmparser",
]
[[package]]
name = "rust-demangler"

View File

@ -4,3 +4,4 @@ version = "0.0.0"
edition = "2021"
[dependencies]
wasmparser = "0.118.2"

View File

@ -2,13 +2,16 @@ use std::env;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
pub use wasmparser;
pub fn out_dir() -> PathBuf {
env::var_os("TMPDIR").unwrap().into()
}
fn setup_common_build_cmd() -> Command {
let rustc = env::var("RUSTC").unwrap();
let mut cmd = Command::new(rustc);
cmd.arg("--out-dir")
.arg(env::var("TMPDIR").unwrap())
.arg("-L")
.arg(env::var("TMPDIR").unwrap());
cmd.arg("--out-dir").arg(out_dir()).arg("-L").arg(out_dir());
cmd
}
@ -45,6 +48,11 @@ impl RustcInvocationBuilder {
self
}
pub fn args(&mut self, args: &[&str]) -> &mut RustcInvocationBuilder {
self.cmd.args(args);
self
}
#[track_caller]
pub fn run(&mut self) -> Output {
let caller_location = std::panic::Location::caller();

View File

@ -1,7 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(NODE) foo.js $(TMPDIR)/foo.wasm

View File

@ -1,22 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
const m = new WebAssembly.Module(buffer);
const i = new WebAssembly.Instance(m, {
host: {
two_i32: () => [100, 101],
two_i64: () => [102n, 103n],
two_f32: () => [104, 105],
two_f64: () => [106, 107],
mishmash: () => [108, 109, 110, 111n, 112, 113],
}
});
assert.deepEqual(i.exports.return_two_i32(), [1, 2])
assert.deepEqual(i.exports.return_two_i64(), [3, 4])
assert.deepEqual(i.exports.return_two_f32(), [5, 6])
assert.deepEqual(i.exports.return_two_f64(), [7, 8])
assert.deepEqual(i.exports.return_mishmash(), [9, 10, 11, 12, 13, 14])
i.exports.call_imports();

View File

@ -0,0 +1,22 @@
(module
(func (export "two_i32") (result i32 i32)
i32.const 100
i32.const 101)
(func (export "two_i64") (result i64 i64)
i64.const 102
i64.const 103)
(func (export "two_f32") (result f32 f32)
f32.const 104
f32.const 105)
(func (export "two_f64") (result f64 f64)
f64.const 106
f64.const 107)
(func (export "mishmash") (result f64 f32 i32 i64 i32 i32)
f64.const 108
f32.const 109
i32.const 110
i64.const 111
i32.const 112
i32.const 113)
)

View File

@ -0,0 +1,43 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc};
use std::path::Path;
use std::process::Command;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run();
let file = out_dir().join("foo.wasm");
let has_wasmtime = match Command::new("wasmtime").arg("--version").output() {
Ok(s) => s.status.success(),
_ => false,
};
if !has_wasmtime {
println!("skipping test, wasmtime isn't available");
return;
}
run(&file, "return_two_i32", "1\n2\n");
run(&file, "return_two_i64", "3\n4\n");
run(&file, "return_two_f32", "5\n6\n");
run(&file, "return_two_f64", "7\n8\n");
run(&file, "return_mishmash", "9\n10\n11\n12\n13\n14\n");
run(&file, "call_imports", "");
}
fn run(file: &Path, method: &str, expected_output: &str) {
let output = Command::new("wasmtime")
.arg("run")
.arg("--preload=host=host.wat")
.arg("--invoke")
.arg(method)
.arg(file)
.output()
.unwrap();
assert!(output.status.success());
assert_eq!(expected_output, String::from_utf8_lossy(&output.stdout));
}

View File

@ -1,8 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown
$(NODE) foo.js $(TMPDIR)/bar.wasm

View File

@ -1,36 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let sections = WebAssembly.Module.customSections(m, "baz");
console.log('section baz', sections);
assert.strictEqual(sections.length, 1);
let section = new Uint8Array(sections[0]);
console.log('contents', section);
assert.strictEqual(section.length, 2);
assert.strictEqual(section[0], 7);
assert.strictEqual(section[1], 8);
sections = WebAssembly.Module.customSections(m, "bar");
console.log('section bar', sections);
assert.strictEqual(sections.length, 1, "didn't pick up `bar` section from dependency");
section = new Uint8Array(sections[0]);
console.log('contents', section);
assert.strictEqual(section.length, 2);
assert.strictEqual(section[0], 3);
assert.strictEqual(section[1], 4);
sections = WebAssembly.Module.customSections(m, "foo");
console.log('section foo', sections);
assert.strictEqual(sections.length, 1, "didn't create `foo` section");
section = new Uint8Array(sections[0]);
console.log('contents', section);
assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections");
assert.strictEqual(section[0], 5);
assert.strictEqual(section[1], 6);
assert.strictEqual(section[2], 1);
assert.strictEqual(section[3], 2);
process.exit(0);

View File

@ -0,0 +1,28 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::HashMap;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run();
rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run();
let file = std::fs::read(&out_dir().join("bar.wasm")).unwrap();
let mut custom = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::CustomSection(s) = payload {
let prev = custom.insert(s.name(), s.data());
assert!(prev.is_none());
}
}
assert_eq!(custom.remove("foo"), Some(&[5, 6, 1, 2][..]));
assert_eq!(custom.remove("bar"), Some(&[3, 4][..]));
assert_eq!(custom.remove("baz"), Some(&[7, 8][..]));
}

View File

@ -1,7 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs -O --target wasm32-unknown-unknown
$(NODE) foo.js $(TMPDIR)/foo.wasm

View File

@ -1,15 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
sections = WebAssembly.Module.customSections(m, "foo");
console.log('section foo', sections);
assert.strictEqual(sections.length, 1, "didn't create `foo` section");
section = new Uint8Array(sections[0]);
console.log('contents', section);
assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections");
process.exit(0);

View File

@ -0,0 +1,30 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::HashMap;
use std::path::Path;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run();
verify(&out_dir().join("foo.wasm"));
}
fn verify(path: &Path) {
eprintln!("verify {path:?}");
let file = std::fs::read(&path).unwrap();
let mut custom = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::CustomSection(s) = payload {
let prev = custom.insert(s.name(), s.data());
assert!(prev.is_none());
}
}
assert_eq!(custom.remove("foo"), Some(&[1, 2, 3, 4][..]));
}

View File

@ -1,19 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) bar.rs --target wasm32-unknown-unknown
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(NODE) verify.js $(TMPDIR)/foo.wasm
$(RUSTC) main.rs --target wasm32-unknown-unknown
$(NODE) verify.js $(TMPDIR)/main.wasm
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
$(NODE) verify.js $(TMPDIR)/foo.wasm
$(RUSTC) main.rs --target wasm32-unknown-unknown -O
$(NODE) verify.js $(TMPDIR)/main.wasm
$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
$(NODE) verify.js $(TMPDIR)/foo.wasm
$(RUSTC) main.rs --target wasm32-unknown-unknown -C lto
$(NODE) verify.js $(TMPDIR)/main.wasm

View File

@ -0,0 +1,60 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::HashMap;
use std::path::Path;
use wasmparser::ExternalKind::*;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
test(&[]);
test(&["-O"]);
test(&["-Clto"]);
}
fn test(args: &[&str]) {
eprintln!("running with {args:?}");
rustc().arg("bar.rs").arg("--target=wasm32-wasip1").args(args).run();
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").args(args).run();
rustc().arg("main.rs").arg("--target=wasm32-wasip1").args(args).run();
verify_exports(
&out_dir().join("foo.wasm"),
&[("foo", Func), ("FOO", Global), ("memory", Memory)],
);
verify_exports(
&out_dir().join("main.wasm"),
&[
("foo", Func),
("FOO", Global),
("_start", Func),
("__main_void", Func),
("memory", Memory),
],
);
}
fn verify_exports(path: &Path, exports: &[(&str, wasmparser::ExternalKind)]) {
println!("verify {path:?}");
let file = std::fs::read(path).unwrap();
let mut wasm_exports = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ExportSection(s) = payload {
for export in s {
let export = export.unwrap();
wasm_exports.insert(export.name, export.kind);
}
}
}
eprintln!("found exports {wasm_exports:?}");
assert_eq!(exports.len(), wasm_exports.len());
for (export, expected_kind) in exports {
assert_eq!(wasm_exports[export], *expected_kind);
}
}

View File

@ -1,32 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let list = WebAssembly.Module.exports(m);
console.log('exports', list);
const my_exports = {};
let nexports = 0;
for (const entry of list) {
if (entry.kind == 'function'){
nexports += 1;
}
my_exports[entry.name] = entry.kind;
}
if (my_exports.foo != "function")
throw new Error("`foo` wasn't defined");
if (my_exports.FOO != "global")
throw new Error("`FOO` wasn't defined");
if (my_exports.main === undefined) {
if (nexports != 1)
throw new Error("should only have one function export");
} else {
if (nexports != 2)
throw new Error("should only have two function exports");
}

View File

@ -1,8 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown
$(NODE) foo.js $(TMPDIR)/bar.wasm

View File

@ -1,18 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let imports = WebAssembly.Module.imports(m);
console.log('imports', imports);
assert.strictEqual(imports.length, 2);
assert.strictEqual(imports[0].kind, 'function');
assert.strictEqual(imports[1].kind, 'function');
let modules = [imports[0].module, imports[1].module];
modules.sort();
assert.strictEqual(modules[0], './dep');
assert.strictEqual(modules[1], './me');

View File

@ -0,0 +1,32 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::HashMap;
use wasmparser::TypeRef::Func;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run();
rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run();
let file = std::fs::read(&out_dir().join("bar.wasm")).unwrap();
let mut imports = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ImportSection(s) = payload {
for i in s {
let i = i.unwrap();
imports.entry(i.module).or_insert(Vec::new()).push((i.name, i.ty));
}
}
}
let import = imports.remove("./dep");
assert!(matches!(import.as_deref(), Some([("dep", Func(_))])), "bad import {:?}", import);
let import = imports.remove("./me");
assert!(matches!(import.as_deref(), Some([("me_in_dep", Func(_))])), "bad import {:?}", import);
}

View File

@ -1,17 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg a
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "1024" ]
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg b
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg c
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg d
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]

View File

@ -0,0 +1,32 @@
#![deny(warnings)]
extern crate run_make_support;
use run_make_support::{out_dir, rustc};
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
test("a");
test("b");
test("c");
test("d");
}
fn test(cfg: &str) {
eprintln!("running cfg {cfg:?}");
rustc()
.arg("foo.rs")
.arg("--target=wasm32-wasip1")
.arg("-Clto")
.arg("-O")
.arg("--cfg")
.arg(cfg)
.run();
let bytes = std::fs::read(&out_dir().join("foo.wasm")).unwrap();
println!("{}", bytes.len());
assert!(bytes.len() < 40_000);
}

View File

@ -1,7 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) main.rs -C overflow-checks=yes -C panic=abort -C lto -C opt-level=z --target wasm32-unknown-unknown
$(NODE) verify.js $(TMPDIR)/main.wasm

View File

@ -0,0 +1,35 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::HashMap;
use wasmparser::TypeRef::Func;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc()
.arg("main.rs")
.arg("--target=wasm32-wasip1")
.arg("-Coverflow-checks=yes")
.arg("-Cpanic=abort")
.arg("-Clto")
.arg("-Copt-level=z")
.run();
let file = std::fs::read(&out_dir().join("main.wasm")).unwrap();
let mut imports = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ImportSection(s) = payload {
for i in s {
let i = i.unwrap();
imports.entry(i.module).or_insert(Vec::new()).push((i.name, i.ty));
}
}
}
assert!(imports.is_empty(), "imports are not empty {:?}", imports);
}

View File

@ -1,9 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let imports = WebAssembly.Module.imports(m);
console.log('imports', imports);
assert.strictEqual(imports.length, 0);

View File

@ -1,10 +0,0 @@
include ../tools.mk
ifeq ($(TARGET),wasm32-unknown-unknown)
all:
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "25000" ]
else
all:
endif

View File

@ -0,0 +1,17 @@
#![deny(warnings)]
extern crate run_make_support;
use run_make_support::{out_dir, rustc};
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run();
let bytes = std::fs::read(&out_dir().join("foo.wasm")).unwrap();
println!("{}", bytes.len());
assert!(bytes.len() < 50_000);
}

View File

@ -1,28 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo
$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
$(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
$(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O -C lto
$(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo
$(RUSTC) bar.rs --target wasm32-unknown-unknown
$(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f
$(RUSTC) bar.rs --target wasm32-unknown-unknown -C lto
$(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
$(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O -C lto
$(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f
$(RUSTC) baz.rs --target wasm32-unknown-unknown
$(NODE) verify-imports.js $(TMPDIR)/baz.wasm sqlite/allocate sqlite/deallocate
$(RUSTC) log.rs --target wasm32-unknown-unknown
$(NODE) verify-imports.js $(TMPDIR)/log.wasm test/log

View File

@ -0,0 +1,52 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::collections::{HashMap, HashSet};
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
test_file("foo.rs", &[("a", &["foo"]), ("b", &["foo"])]);
test_file("bar.rs", &[("m1", &["f", "g"]), ("m2", &["f"])]);
test_file("baz.rs", &[("sqlite", &["allocate", "deallocate"])]);
test_file("log.rs", &[("test", &["log"])]);
}
fn test_file(file: &str, expected_imports: &[(&str, &[&str])]) {
test(file, &[], expected_imports);
test(file, &["-Clto"], expected_imports);
test(file, &["-O"], expected_imports);
test(file, &["-Clto", "-O"], expected_imports);
}
fn test(file: &str, args: &[&str], expected_imports: &[(&str, &[&str])]) {
println!("test {file:?} {args:?} for {expected_imports:?}");
rustc().arg(file).arg("--target=wasm32-wasip1").args(args).run();
let file = std::fs::read(&out_dir().join(file).with_extension("wasm")).unwrap();
let mut imports = HashMap::new();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ImportSection(s) = payload {
for i in s {
let i = i.unwrap();
imports.entry(i.module).or_insert(HashSet::new()).insert(i.name);
}
}
}
eprintln!("imports {imports:?}");
for (expected_module, expected_names) in expected_imports {
let names = imports.remove(expected_module).unwrap();
assert_eq!(names.len(), expected_names.len());
for name in *expected_names {
assert!(names.contains(name));
}
}
assert!(imports.is_empty());
}

View File

@ -1,32 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let list = WebAssembly.Module.imports(m);
console.log('imports', list);
if (list.length !== process.argv.length - 3)
throw new Error("wrong number of imports")
const imports = new Map();
for (let i = 3; i < process.argv.length; i++) {
const [module, name] = process.argv[i].split('/');
if (!imports.has(module))
imports.set(module, new Map());
imports.get(module).set(name, true);
}
for (let i of list) {
if (imports.get(i.module) === undefined || imports.get(i.module).get(i.name) === undefined)
throw new Error(`didn't find import of ${i.module}::${i.name}`);
imports.get(i.module).delete(i.name);
if (imports.get(i.module).size === 0)
imports.delete(i.module);
}
console.log(imports);
if (imports.size !== 0) {
throw new Error('extra imports');
}

View File

@ -1,13 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(NODE) verify-exported-symbols.js $(TMPDIR)/foo.wasm
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
$(NODE) verify-exported-symbols.js $(TMPDIR)/foo.wasm
$(RUSTC) bar.rs --target wasm32-unknown-unknown
$(NODE) verify-exported-symbols.js $(TMPDIR)/bar.wasm
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
$(NODE) verify-exported-symbols.js $(TMPDIR)/bar.wasm

View File

@ -0,0 +1,41 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::path::Path;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run();
verify_symbols(&out_dir().join("foo.wasm"));
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run();
verify_symbols(&out_dir().join("foo.wasm"));
rustc().arg("bar.rs").arg("--target=wasm32-wasip1").run();
verify_symbols(&out_dir().join("bar.wasm"));
rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-O").run();
verify_symbols(&out_dir().join("bar.wasm"));
}
fn verify_symbols(path: &Path) {
eprintln!("verify {path:?}");
let file = std::fs::read(&path).unwrap();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ExportSection(s) = payload {
for e in s {
let e = e.unwrap();
if e.kind != wasmparser::ExternalKind::Func {
continue;
}
if e.name == "foo" {
continue;
}
panic!("unexpected export {e:?}");
}
}
}
}

View File

@ -1,21 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let list = WebAssembly.Module.exports(m);
console.log('exports', list);
let bad = false;
for (let i = 0; i < list.length; i++) {
const e = list[i];
if (e.name == "foo" || e.kind != "function")
continue;
console.log('unexpected exported symbol:', e.name);
bad = true;
}
if (bad)
process.exit(1);

View File

@ -1,13 +0,0 @@
include ../tools.mk
# only-wasm32-bare
all:
$(RUSTC) foo.rs --target wasm32-unknown-unknown
$(NODE) verify-no-imports.js $(TMPDIR)/foo.wasm
$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
$(NODE) verify-no-imports.js $(TMPDIR)/foo.wasm
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
$(NODE) verify-no-imports.js $(TMPDIR)/foo.wasm
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O -C lto
$(NODE) verify-no-imports.js $(TMPDIR)/foo.wasm

View File

@ -0,0 +1,31 @@
extern crate run_make_support;
use run_make_support::{out_dir, rustc, wasmparser};
use std::path::Path;
fn main() {
if std::env::var("TARGET").unwrap() != "wasm32-wasip1" {
return;
}
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run();
verify_symbols(&out_dir().join("foo.wasm"));
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").run();
verify_symbols(&out_dir().join("foo.wasm"));
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run();
verify_symbols(&out_dir().join("foo.wasm"));
rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run();
verify_symbols(&out_dir().join("foo.wasm"));
}
fn verify_symbols(path: &Path) {
eprintln!("verify {path:?}");
let file = std::fs::read(&path).unwrap();
for payload in wasmparser::Parser::new(0).parse_all(&file) {
let payload = payload.unwrap();
if let wasmparser::Payload::ImportSection(_) = payload {
panic!("import section found");
}
}
}

View File

@ -1,10 +0,0 @@
const fs = require('fs');
const process = require('process');
const assert = require('assert');
const buffer = fs.readFileSync(process.argv[2]);
let m = new WebAssembly.Module(buffer);
let list = WebAssembly.Module.imports(m);
console.log('imports', list);
if (list.length !== 0)
throw new Error("there are some imports");