Skip to content

Commit 49bed0e

Browse files
authored
Add --type-section-suffix to the Rust generator (#859)
Same motivation as the C generator, just for a different one.
1 parent b98e460 commit 49bed0e

File tree

10 files changed

+114
-6
lines changed

10 files changed

+114
-6
lines changed

crates/guest-rust/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
274274
/// // case above if possible.
275275
/// ownership: Borrowing { duplicate_if_necessary: false },
276276
///
277+
/// // This will suffix the custom section containing component type
278+
/// // information with the specified string. This is not required by
279+
/// // default but if the same world is generated in two different locations
280+
/// // in the crate then one bindings generation location will need this
281+
/// // suffix to avoid having the custom sections corrupt each other.
282+
/// type_section_suffix: "suffix",
283+
///
277284
/// // Configures the path to the `wit-bindgen` crate itself. By default
278285
/// // this is `wit_bindgen` assuming that your crate depends on the
279286
/// // `wit-bindgen` crate itself.

crates/rust-macro/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ impl Parse for Config {
103103
.collect()
104104
}
105105
Opt::With(with) => opts.with.extend(with),
106+
Opt::TypeSectionSuffix(suffix) => {
107+
opts.type_section_suffix = Some(suffix.value())
108+
}
106109
}
107110
}
108111
} else {
@@ -216,6 +219,7 @@ mod kw {
216219
syn::custom_keyword!(export_prefix);
217220
syn::custom_keyword!(additional_derives);
218221
syn::custom_keyword!(with);
222+
syn::custom_keyword!(type_section_suffix);
219223
}
220224

221225
#[derive(Clone)]
@@ -276,6 +280,7 @@ enum Opt {
276280
// Parse as paths so we can take the concrete types/macro names rather than raw strings
277281
AdditionalDerives(Vec<syn::Path>),
278282
With(HashMap<String, String>),
283+
TypeSectionSuffix(syn::LitStr),
279284
}
280285

281286
impl Parse for Opt {
@@ -381,6 +386,10 @@ impl Parse for Opt {
381386
let fields: Punctuated<_, Token![,]> =
382387
contents.parse_terminated(with_field_parse, Token![,])?;
383388
Ok(Opt::With(HashMap::from_iter(fields.into_iter())))
389+
} else if l.peek(kw::type_section_suffix) {
390+
input.parse::<kw::type_section_suffix>()?;
391+
input.parse::<Token![:]>()?;
392+
Ok(Opt::TypeSectionSuffix(input.parse()?))
384393
} else {
385394
Err(l.error())
386395
}

crates/rust/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ pub struct Opts {
171171
/// Remapping of interface names to rust module names.
172172
#[cfg_attr(feature = "clap", arg(long, value_parser = parse_with, default_value = ""))]
173173
pub with: HashMap<String, String>,
174+
175+
/// Add the specified suffix to the name of the custome section containing
176+
/// the component type.
177+
#[cfg_attr(feature = "clap", arg(long))]
178+
pub type_section_suffix: Option<String>,
174179
}
175180

176181
impl Opts {
@@ -533,8 +538,10 @@ impl WorldGenerator for RustWasm {
533538
// otherwise is attempted to be unique here to ensure that this doesn't get
534539
// concatenated to other custom sections by LLD by accident since LLD will
535540
// concatenate custom sections of the same name.
536-
self.src
537-
.push_str(&format!("#[link_section = \"component-type:{}\"]\n", name,));
541+
let suffix = self.opts.type_section_suffix.as_deref().unwrap_or("");
542+
self.src.push_str(&format!(
543+
"#[link_section = \"component-type:{name}{suffix}\"]\n"
544+
));
538545

539546
let mut producers = wasm_metadata::Producers::empty();
540547
producers.add(

crates/test-rust-wasm/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,7 @@ test = false
102102
[[bin]]
103103
name = "resource_borrow_simple"
104104
test = false
105+
106+
[[bin]]
107+
name = "type_section_suffix"
108+
test = false
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include!("../../../../tests/runtime/type_section_suffix/wasm.rs");
2+
3+
fn main() {}

tests/runtime/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mod resource_with_lists;
3535
mod resources;
3636
mod smoke;
3737
mod strings;
38+
mod type_section_suffix;
3839
mod variants;
3940
mod versions;
4041

tests/runtime/type_section_suffix.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use anyhow::{Ok, Result};
2+
use wasmtime::Store;
3+
4+
wasmtime::component::bindgen!("required-exports" in "tests/runtime/type_section_suffix");
5+
use self::test::suffix::imports::Host;
6+
7+
#[derive(Default)]
8+
pub struct MyFoo;
9+
10+
impl Host for MyFoo {
11+
fn foo(&mut self) -> wasmtime::Result<()> {
12+
Ok(())
13+
}
14+
}
15+
16+
#[test]
17+
fn run() -> Result<()> {
18+
crate::run_test(
19+
"type_section_suffix",
20+
|linker| RequiredExports::add_to_linker(linker, |x| &mut x.0),
21+
|store, component, linker| RequiredExports::instantiate(store, component, linker),
22+
run_test,
23+
)
24+
}
25+
26+
fn run_test(exports: RequiredExports, store: &mut Store<crate::Wasi<MyFoo>>) -> Result<()> {
27+
exports.call_run(&mut *store)?;
28+
Ok(())
29+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
wit_bindgen::generate!({
2+
path: "../../tests/runtime/type_section_suffix",
3+
world: "required-exports",
4+
exports: {
5+
world: Exports
6+
}
7+
});
8+
9+
// generate bindings once here
10+
mod a {
11+
wit_bindgen::generate!(
12+
"available-imports" in "../../tests/runtime/type_section_suffix"
13+
);
14+
}
15+
16+
// generate bindings again for the same world, this time using a different
17+
// suffix
18+
mod b {
19+
wit_bindgen::generate!({
20+
world: "available-imports",
21+
path: "../../tests/runtime/type_section_suffix",
22+
type_section_suffix: "hello i am a suffix how are you doing today",
23+
});
24+
}
25+
26+
struct Exports;
27+
28+
impl Guest for Exports {
29+
fn run() {
30+
a::test::suffix::imports::foo();
31+
b::test::suffix::imports::foo();
32+
}
33+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test:suffix;
2+
3+
interface imports {
4+
foo: func();
5+
}
6+
7+
world available-imports {
8+
import imports;
9+
}
10+
11+
world required-exports {
12+
include available-imports;
13+
14+
export run: func();
15+
}

tests/runtime/versions/wasm.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ impl Guest for Component {
2424
}
2525

2626
struct Component1;
27-
impl v1 for Component1{
27+
impl v1 for Component1 {
2828
fn x() -> f32 {
2929
1.0
3030
}
3131

3232
fn y(a: f32) -> f32 {
33-
1.0+a
33+
1.0 + a
3434
}
3535
}
3636

3737
struct Component2;
38-
impl v2 for Component2{
38+
impl v2 for Component2 {
3939
fn x() -> f32 {
4040
2.0
4141
}
4242

4343
fn z(a: f32, b: f32) -> f32 {
44-
2.0+a+b
44+
2.0 + a + b
4545
}
4646
}

0 commit comments

Comments
 (0)