Skip to content

Commit

Permalink
Initial (failing) symmetric smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
cpetig committed Aug 31, 2024
1 parent 5f0ec6c commit 3d79f54
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 11 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions crates/cpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2799,7 +2799,8 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
let tmp = self.tmp();
let len = format!("len{}", tmp);
uwriteln!(self.src, "auto {} = {};\n", len, operands[1]);
let result = if self.gen.gen.opts.symmetric && !self.gen.gen.opts.new_api
let result = if self.gen.gen.opts.symmetric
&& !self.gen.gen.opts.new_api
&& matches!(self.variant, AbiVariant::GuestExport)
{
uwriteln!(self.src, "auto string{tmp} = wit::string::from_view(std::string_view((char const *)({}), {len}));\n", operands[0]);
Expand All @@ -2811,7 +2812,10 @@ impl<'a, 'b> Bindgen for FunctionBindgen<'a, 'b> {
} else if self.gen.gen.opts.host {
uwriteln!(self.src, "char const* ptr{} = (char const*)wasm_runtime_addr_app_to_native(wasm_runtime_get_module_inst(exec_env), {});\n", tmp, operands[0]);
format!("std::string_view(ptr{}, {len})", tmp)
} else if self.gen.gen.opts.short_cut || (self.gen.gen.opts.new_api && matches!(self.variant, AbiVariant::GuestExport)) {
} else if self.gen.gen.opts.short_cut
|| (self.gen.gen.opts.new_api
&& matches!(self.variant, AbiVariant::GuestExport))
{
format!("std::string_view((char const*)({}), {len})", operands[0])
} else {
format!("wit::string((char const*)({}), {len})", operands[0])
Expand Down
141 changes: 141 additions & 0 deletions crates/cpp/tests/symmetric.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use std::{
fs::{self, File},
io::{self, Write},
path::PathBuf,
process::Command,
};

fn tests(
dir_name: &str,
out_dir: &PathBuf,
toplevel: &PathBuf,
source_files: &PathBuf,
tester_source_dir: &PathBuf,
) -> io::Result<()> {
// modelled after wit-bindgen/tests/runtime/main.rs
let mut dir = source_files.clone();
dir.push(dir_name);

// let mut rust = Vec::new();
let mut cpp = Vec::new();
for file in dir.read_dir()? {
let path = file?.path();
match path.extension().and_then(|s| s.to_str()) {
// Some("rs") => rust.push(path),
Some("cpp") => cpp.push(path),
_ => {}
}
}

let mut out_dir = out_dir.clone();
out_dir.push(dir_name);
// println!("{cpp:?} {out_dir:?}");

drop(std::fs::remove_dir_all(&out_dir));
std::fs::create_dir_all(&out_dir)?;
let mut testee_dir = out_dir.clone();
testee_dir.push("rust");
std::fs::create_dir(&testee_dir)?;
let testee_cargo = format!(
"[package]\n\
name = \"{dir_name}\"\n\
publish = false\n\
edition = \"2021\"\n\
\n\
[dependencies]\n\
wit-bindgen = {{ path = \"{toplevel}/crates/guest-rust\" }}\n\
\n\
[lib]\n\
crate-type = [\"cdylib\"]\n\
",
toplevel = toplevel.display()
);
let mut filename = testee_dir.clone();
filename.push("Cargo.toml");
File::create(&filename)?.write_all(testee_cargo.as_bytes())?;
filename.pop();
filename.push("src");
std::fs::create_dir(&filename)?;
filename.push(format!("lib.rs"));
let mut original = dir.clone();
original.push("wasm.rs");
std::os::unix::fs::symlink(original, filename);
drop(testee_cargo);

let tester_cargo = format!(
"[workspace]\n\
members = [ \"rust\" ]\n\
resolver = \"2\"\n\
\n\
[package]\n\
name = \"tester\"\n\
publish = false\n\
edition = \"2021\"\n\
\n\
[dependencies]\n\
wit-bindgen = {{ path = \"{toplevel}/crates/guest-rust\" }}\n\
{dir_name} = {{ path = \"rust\" }}\n\
",
toplevel = toplevel.display()
);
let mut filename = out_dir.clone();
filename.push("Cargo.toml");
File::create(&filename)?.write_all(tester_cargo.as_bytes())?;
filename.pop();
filename.push("src");
std::fs::create_dir(&filename)?;
filename.push(format!("main.rs"));
let mut original = tester_source_dir.clone();
original.push(&format!("{dir_name}.rs"));
std::os::unix::fs::symlink(original, &filename);

let mut cmd = Command::new("cargo");
cmd.arg("build")
.current_dir(testee_dir)
.env("SYMMETRIC_ABI", "1")
.env("WIT_BINDGEN_DEBUG", "1");
let status = cmd.status().unwrap();
assert!(status.success());

Ok(())
}

#[test]
fn symmetric_integration() -> io::Result<()> {
let mut out_dir = std::env::current_exe()?;
out_dir.pop();
out_dir.pop();
out_dir.pop();
out_dir.push("symmetric-tests");

let mut manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));

let mut toplevel = manifest_dir.clone();
toplevel.pop();
toplevel.pop();

let mut test_link = out_dir.clone();
test_link.push("tests");
if !fs::exists(&test_link)? {
let mut original = toplevel.clone();
original.push("tests");
std::os::unix::fs::symlink(original, &test_link);
}

let mut source_files = toplevel.clone();
source_files.push("tests");
source_files.push("runtime");

let mut tester_source_dir = manifest_dir.clone();
tester_source_dir.push("tests");
tester_source_dir.push("symmetric_tests");

tests(
"smoke",
&out_dir,
&toplevel,
&source_files,
&tester_source_dir,
)?;
Ok(())
}
25 changes: 25 additions & 0 deletions crates/cpp/tests/symmetric_tests/smoke.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::sync::atomic::AtomicBool;

wit_bindgen::generate!({
path: "../tests/runtime/smoke",
symmetric: true,
invert_direction: true,
});

export!(MyExports);

pub struct MyExports;

static HIT: AtomicBool = AtomicBool::new(false);

impl exports::test::smoke::imports::Guest for MyExports {
fn thunk() {
HIT.store(true, std::sync::atomic::Ordering::SeqCst);
println!("tester called");
}
}

pub fn main() {
thunk();
assert!(HIT.load(std::sync::atomic::Ordering::SeqCst));
}
29 changes: 27 additions & 2 deletions crates/guest-rust/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ impl Parse for Config {
Opt::DisableCustomSectionLinkHelpers(disable) => {
opts.disable_custom_section_link_helpers = disable.value();
}
Opt::Symmetric(enable) => {
opts.symmetric = enable.value();
}
Opt::InvertDirection(enable) => {
opts.invert_direction = enable.value();
}
}
}
} else {
Expand All @@ -166,10 +172,13 @@ impl Parse for Config {
)]));
}
}
let (resolve, pkgs, files) =
let (mut resolve, pkgs, files) =
parse_source(&source, &features).map_err(|err| anyhow_to_syn(call_site, err))?;
let world = select_world(&resolve, &pkgs, world.as_deref())
.map_err(|e| anyhow_to_syn(call_site, e))?;
if opts.invert_direction {
resolve.invert_direction(world);
}
Ok(Config {
opts,
resolve,
Expand Down Expand Up @@ -260,8 +269,12 @@ fn parse_source(
}

impl Config {
fn expand(self) -> Result<TokenStream> {
fn expand(mut self) -> Result<TokenStream> {
let mut files = Default::default();
// for testing the symmetric ABI (modify guest code)
if std::env::var("SYMMETRIC_ABI").is_ok() {
self.opts.symmetric = true;
}
let mut generator = self.opts.build();
generator
.generate(&self.resolve, self.world, &mut files)
Expand Down Expand Up @@ -335,6 +348,8 @@ mod kw {
syn::custom_keyword!(imports);
syn::custom_keyword!(debug);
syn::custom_keyword!(disable_custom_section_link_helpers);
syn::custom_keyword!(symmetric);
syn::custom_keyword!(invert_direction);
}

#[derive(Clone)]
Expand Down Expand Up @@ -396,6 +411,8 @@ enum Opt {
Async(AsyncConfig, Span),
Debug(syn::LitBool),
DisableCustomSectionLinkHelpers(syn::LitBool),
Symmetric(syn::LitBool),
InvertDirection(syn::LitBool),
}

impl Parse for Opt {
Expand Down Expand Up @@ -574,6 +591,14 @@ impl Parse for Opt {
input.parse::<kw::disable_custom_section_link_helpers>()?;
input.parse::<Token![:]>()?;
Ok(Opt::DisableCustomSectionLinkHelpers(input.parse()?))
} else if l.peek(kw::symmetric) {
input.parse::<kw::symmetric>()?;
input.parse::<Token![:]>()?;
Ok(Opt::Symmetric(input.parse()?))
} else if l.peek(kw::invert_direction) {
input.parse::<kw::invert_direction>()?;
input.parse::<Token![:]>()?;
Ok(Opt::InvertDirection(input.parse()?))
} else {
Err(l.error())
}
Expand Down
4 changes: 4 additions & 0 deletions crates/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ pub struct Opts {
#[cfg_attr(feature = "clap", arg(long, default_value_t = bool::default()))]
pub symmetric: bool,

/// Flip import and export on world (used for symmetric testing)
#[cfg_attr(feature = "clap", arg(long, default_value_t = bool::default()))]
pub invert_direction: bool,

/// Determines which functions to lift or lower `async`, if any.
#[cfg_attr(feature = "clap", arg(long = "async", value_parser = parse_async, default_value_t = Default::default()))]
pub async_: AsyncConfig,
Expand Down

0 comments on commit 3d79f54

Please sign in to comment.