Skip to content

Commit

Permalink
Rework run() to work with python37.emscripten.wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Jul 4, 2022
1 parent fe97cba commit 66a43f8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 17 deletions.
28 changes: 11 additions & 17 deletions lib/emscripten/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,31 +315,31 @@ pub fn set_up_emscripten(instance: &mut Instance) -> Result<(), RuntimeError> {

/// Looks for variations of the main function (usually
/// `["_main", "main"])`, then returns a reference to
/// the found function. Useful for determining whether
/// a module is executable.
/// the name of the first found function. Useful for
/// determining whether a module is executable.
///
/// Returns `ExportError` if none of the `main_func_names`
/// were found.
pub fn emscripten_get_main_func_name<'a>(
instance: &Instance,
main_func_names: &[&'a str],
) -> Result<&'a str, ExportError> {
let mut function_name = None;
let mut last_err = None;

for func_name in main_func_names.iter() {
match instance.exports.get::<Function>(func_name) {
Ok(_) => {
function_name = Some(func_name);
break;
return Ok(func_name);
}
Err(e) => {
last_err = Some(e);
}
}
}

match (function_name, last_err) {
(Some(s), _) => Ok(s),
(None, None) => Err(ExportError::Missing(format!("{main_func_names:?}"))),
(None, Some(e)) => Err(e),
match last_err {
None => Err(ExportError::Missing(format!("{main_func_names:?}"))),
Some(e) => Err(e),
}
}

Expand Down Expand Up @@ -401,15 +401,9 @@ pub fn run_emscripten_instance(
set_up_emscripten(instance)?;

let main_func_names = ["_main", "main"];
if let Some(ep) = entrypoint {
if let Some(ep) = entrypoint.as_ref() {
debug!("Running entry point: {}", &ep);
let arg = unsafe { allocate_cstr_on_stack(env, args[0]).0 };
//let (argc, argv) = store_module_arguments(instance.context_mut(), args);
let func: &Function = instance
.exports
.get(&ep)
.map_err(|e| RuntimeError::new(e.to_string()))?;
func.call(&[Val::I32(arg as i32)])?;
emscripten_call_main(instance, &ep, env, path, &args)?;
} else if let Ok(name) = emscripten_get_main_func_name(instance, &main_func_names) {
emscripten_call_main(instance, name, env, path, &args)?;
} else {
Expand Down
40 changes: 40 additions & 0 deletions tests/integration/cli/tests/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,46 @@ fn test_no_start_wat_path() -> String {
format!("{}/{}", ASSET_PATH, "no_start.wat")
}

// This test verifies that "wasmer run --invoke _start module.emscripten.wat"
// works the same as "wasmer run module.emscripten.wat" (without --invoke).
#[test]
fn run_invoke_works_with_nomain_emscripten() -> anyhow::Result<()> {
// In this example the function "wasi_unstable.arg_sizes_get"
// is a function that is imported from the WASI env.
let emscripten_wat = include_bytes("");
let random = rand::random::<u64>();
let module_file = std::env::temp_dir().join(&format!("{random}.emscripten.wat"));
std::fs::write(&module_file, wasi_wat.as_bytes()).unwrap();
let output = Command::new(WASMER_PATH)
.arg("run")
.arg(&module_file)
.output()?;

let stderr = std::str::from_utf8(&output.stderr).unwrap().to_string();
let success = output.status.success();
if !success {
println!("ERROR in 'wasmer run [module.emscripten.wat]':\r\n{stderr}");
panic!();
}

let output = Command::new(WASMER_PATH)
.arg("run")
.arg("--invoke")
.arg("_start")
.arg(&module_file)
.output()?;

let stderr = std::str::from_utf8(&output.stderr).unwrap().to_string();
let success = output.status.success();
if !success {
println!("ERROR in 'wasmer run --invoke _start [module.emscripten.wat]':\r\n{stderr}");
panic!();
}

std::fs::remove_file(&module_file).unwrap();
Ok(())
}

#[test]
fn run_wasi_works() -> anyhow::Result<()> {
let output = Command::new(WASMER_PATH)
Expand Down

0 comments on commit 66a43f8

Please sign in to comment.