wasm2es6js: Fix handling of start function

This is split out from #1002 and is intended to fix the tool's handling
of the `start` function. For the most accurate emulation of the wasm ESM
spec I believe we need to defer execution of the start function until
all our exports are wired up which should allow valid cyclical
references during instantiation.

The fix here is to remove the start function, if one is present, and
inject an invocation of it at the end of initialization (after our
exports are wired up). This fixes tests on #1002, but doesn't have any
direct analogue for tests here just yet.

Along the way because multiple files now come out of `wasm2es6js` by
default I've added an `--out-dir` argument as well as `-o` to ensure
that a folder for all outputs can be specified.
This commit is contained in:
Alex Crichton
2018-11-29 11:52:23 -08:00
parent bbde39fe66
commit 522e973694
3 changed files with 85 additions and 20 deletions

View File

@ -68,8 +68,10 @@ pub fn spawn(
let output = Config::new()
.fetch(Some(format!("/{}", wasm_name)))
.generate(&wasm)?;
let js = output.js()?;
let (js, wasm) = output.js_and_wasm()?;
let wasm = wasm.unwrap();
fs::write(tmpdir.join(format!("{}_bg.js", module)), js).context("failed to write JS file")?;
fs::write(tmpdir.join(format!("{}_bg.wasm", module)), wasm).context("failed to write wasm file")?;
// For now, always run forever on this port. We may update this later!
let tmpdir = tmpdir.to_path_buf();

View File

@ -25,6 +25,7 @@ Usage:
Options:
-h --help Show this screen.
-o --output FILE File to place output in
--out-dir DIR Directory to place ouptut in
--typescript Output a `*.d.ts` file next to the JS output
--base64 Inline the wasm module using base64 encoding
--fetch PATH Load module by passing the PATH argument to `fetch()`
@ -37,6 +38,7 @@ bundlers for working with wasm. Use this program with care!
#[derive(Debug, Deserialize)]
struct Args {
flag_output: Option<PathBuf>,
flag_out_dir: Option<PathBuf>,
flag_typescript: bool,
flag_base64: bool,
flag_fetch: Option<String>,
@ -68,22 +70,34 @@ fn rmain(args: &Args) -> Result<(), Error> {
.generate(&wasm)?;
if args.flag_typescript {
if let Some(ref p) = args.flag_output {
let dst = p.with_extension("d.ts");
let ts = object.typescript();
fs::write(&dst, ts).with_context(|_| format!("failed to write `{}`", dst.display()))?;
}
let ts = object.typescript();
write(&args, "d.ts", ts.as_bytes(), false)?;
}
let js = object.js()?;
let (js, wasm) = object.js_and_wasm()?;
match args.flag_output {
Some(ref p) => {
fs::write(p, js).with_context(|_| format!("failed to write `{}`", p.display()))?;
}
None => {
println!("{}", js);
}
write(args, "js", js.as_bytes(), false)?;
if let Some(wasm) = wasm {
write(args, "wasm", &wasm, false)?;
}
Ok(())
}
fn write(
args: &Args,
extension: &str,
contents: &[u8],
print_fallback: bool,
) -> Result<(), Error> {
if let Some(p) = &args.flag_output {
let dst = p.with_extension(extension);
fs::write(&dst, contents).with_context(|_| format!("failed to write `{}`", dst.display()))?;
} else if let Some(p) = &args.flag_out_dir {
let filename = args.arg_input.file_name().unwrap();
let dst = p.join(filename).with_extension(extension);
fs::write(&dst, contents).with_context(|_| format!("failed to write `{}`", dst.display()))?;
} else if print_fallback {
println!("{}", String::from_utf8_lossy(contents))
}
Ok(())