Skip to content

Commit 59a0727

Browse files
authored
Bind more options to ComponentEncoder (#59)
* Bind more options to `ComponentEncoder` Add `--reject-legacy-names` and `--realloc-via-memory-grow`. * Bump action dependency * Always pipe stdout
1 parent 253fb11 commit 59a0727

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
if: matrix.target != ''
4848
- run: $CENTOS cargo build --release
4949
- run: ./ci/build-tarballs.sh "${{ matrix.build }}" "${{ matrix.target }}"
50-
- uses: actions/upload-artifact@v3
50+
- uses: actions/upload-artifact@v4
5151
with:
5252
name: bins-${{ matrix.build }}
5353
path: dist

src/lib.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,27 @@ struct ComponentLdArgs {
275275
#[clap(long = "adapt", value_name = "[NAME=]MODULE", value_parser = parse_adapter)]
276276
adapters: Vec<(String, Vec<u8>)>,
277277

278+
/// Whether or not "legacy" names are rejected during componentization.
279+
///
280+
/// This option can be used to require the naming scheme outlined in
281+
/// <https://github.com/WebAssembly/component-model/pull/378> to be used
282+
/// and rejects all modules using the previous ad-hoc naming scheme.
283+
///
284+
/// This defaults to `false`.
285+
#[clap(long)]
286+
reject_legacy_names: bool,
287+
288+
/// Whether or not the `cabi_realloc` function used by the adapter is backed
289+
/// by `memory.grow`.
290+
///
291+
/// By default the adapter will import `cabi_realloc` from the main module
292+
/// and use that, but this can be used to instead back memory allocation
293+
/// requests with `memory.grow` instead.
294+
///
295+
/// This defaults to `false`.
296+
#[clap(long)]
297+
realloc_via_memory_grow: bool,
298+
278299
/// WIT file representing additional component type information to use.
279300
///
280301
/// May be specified more than once.
@@ -624,7 +645,9 @@ impl App {
624645
)?;
625646
}
626647

627-
let mut encoder = wit_component::ComponentEncoder::default();
648+
let mut encoder = wit_component::ComponentEncoder::default()
649+
.reject_legacy_names(self.component.reject_legacy_names)
650+
.realloc_via_memory_grow(self.component.realloc_via_memory_grow);
628651
if let Some(validate) = self.component.validate_component {
629652
encoder = encoder.validate(validate);
630653
}

tests/all.rs

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use anyhow::{bail, Context, Result};
12
use std::env;
23
use std::fs;
3-
use std::io::{Read, Write};
4+
use std::io::Write;
45
use std::process::{Command, Stdio};
56

67
fn compile(args: &[&str], src: &str) -> Vec<u8> {
@@ -22,11 +23,16 @@ impl Project {
2223
}
2324

2425
fn compile(&self, args: &[&str], src: &str) -> Vec<u8> {
26+
self.try_compile(args, src, true).unwrap()
27+
}
28+
29+
fn try_compile(&self, args: &[&str], src: &str, inherit_stderr: bool) -> Result<Vec<u8>> {
2530
let mut myself = env::current_exe().unwrap();
2631
myself.pop(); // exe name
2732
myself.pop(); // 'deps'
2833
myself.push("wasm-component-ld");
29-
let mut rustc = Command::new("rustc")
34+
let mut rustc = Command::new("rustc");
35+
rustc
3036
.arg("--target")
3137
.arg("wasm32-wasip1")
3238
.arg("-")
@@ -35,22 +41,40 @@ impl Project {
3541
.arg("-C")
3642
.arg(&format!("linker={}", myself.to_str().unwrap()))
3743
.args(args)
38-
.current_dir(self.tempdir.path())
39-
.stdout(Stdio::piped())
4044
.stdin(Stdio::piped())
41-
.spawn()
42-
.expect("failed to spawn rustc");
45+
.stdout(Stdio::piped())
46+
.current_dir(self.tempdir.path());
47+
if !inherit_stderr {
48+
rustc.stderr(Stdio::piped());
49+
}
50+
let mut rustc = rustc.spawn().context("failed to spawn rustc")?;
4351

4452
rustc
4553
.stdin
4654
.take()
47-
.unwrap()
55+
.context("stdin should be present")?
4856
.write_all(src.as_bytes())
49-
.unwrap();
50-
let mut ret = Vec::new();
51-
rustc.stdout.take().unwrap().read_to_end(&mut ret).unwrap();
52-
assert!(rustc.wait().unwrap().success());
53-
ret
57+
.context("failed to write stdin")?;
58+
let output = rustc
59+
.wait_with_output()
60+
.context("failed to wait for subprocess")?;
61+
if !output.status.success() {
62+
let mut error = format!("subprocess failed: {:?}", output.status);
63+
if !output.stdout.is_empty() {
64+
error.push_str(&format!(
65+
"\nstdout: {}",
66+
String::from_utf8_lossy(&output.stdout)
67+
));
68+
}
69+
if !output.stderr.is_empty() {
70+
error.push_str(&format!(
71+
"\nstderr: {}",
72+
String::from_utf8_lossy(&output.stderr)
73+
));
74+
}
75+
bail!("{error}")
76+
}
77+
Ok(output.stdout)
5478
}
5579
}
5680

@@ -227,3 +251,35 @@ fn rustc_using_argfile() {
227251
let output = p.compile(&["-Ccodegen-units=1000", "-Clink-arg=@args"], &src);
228252
assert_module(&output);
229253
}
254+
255+
#[test]
256+
fn hello_world_with_realloc_as_memory_grow() {
257+
let output = compile(
258+
&["-Clink-arg=--realloc-via-memory-grow"],
259+
r#"
260+
fn main() {
261+
println!("hello!");
262+
}
263+
"#,
264+
);
265+
assert_component(&output);
266+
}
267+
268+
// The adapter uses legacy names, so this option will always result in an error
269+
// right now.
270+
#[test]
271+
fn legacy_names_currently_required() {
272+
let result = Project::new().try_compile(
273+
&["-Clink-arg=--reject-legacy-names"],
274+
r#"
275+
fn main() {
276+
println!("hello!");
277+
}
278+
"#,
279+
false,
280+
);
281+
let err = result.unwrap_err();
282+
let err = format!("{err:?}");
283+
println!("error: {err}");
284+
assert!(err.contains("unknown or invalid component model import syntax"));
285+
}

0 commit comments

Comments
 (0)