Skip to content

Commit

Permalink
Implemented multithreading and fixed a number of bugs with WASIX
Browse files Browse the repository at this point in the history
  • Loading branch information
john-sharratt committed Jun 14, 2022
1 parent dced984 commit 6aad270
Show file tree
Hide file tree
Showing 30 changed files with 2,187 additions and 1,899 deletions.
5 changes: 2 additions & 3 deletions examples/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

println!("Creating `WasiEnv`...");
// First, we create the `WasiEnv`
let wasi_env = WasiState::new("hello")
let mut wasi_env = WasiState::new("hello")
// .args(&["world"])
// .env("KEY", "Value")
.finalize()?;

println!("Instantiating module with WASI imports...");
// Then, we get the import object related to our WASI
// and attach it to the Wasm instance.
let mut wasi_thread = wasi_env.new_thread();
let import_object = wasi_thread.import_object(&module)?;
let import_object = wasi_env.import_object(&module)?;
let instance = Instance::new(&module, &import_object)?;

println!("Call WASI `_start` function...");
Expand Down
5 changes: 2 additions & 3 deletions examples/wasi_pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// First, we create the `WasiEnv` with the stdio pipes
let mut input = Pipe::new();
let mut output = Pipe::new();
let wasi_env = WasiState::new("hello")
let mut wasi_env = WasiState::new("hello")
.stdin(Box::new(input.clone()))
.stdout(Box::new(output.clone()))
.finalize()?;

println!("Instantiating module with WASI imports...");
// Then, we get the import object related to our WASI
// and attach it to the Wasm instance.
let mut wasi_thread = wasi_env.new_thread();
let import_object = wasi_thread.import_object(&module)?;
let import_object = wasi_env.import_object(&module)?;
let instance = Instance::new(&module, &import_object)?;

let msg = "racecar go zoom";
Expand Down
10 changes: 6 additions & 4 deletions lib/c-api/examples/early-exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
// Use the last_error API to retrieve error messages
void print_wasmer_error() {
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
if (error_len > 0) {
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
}
}

void print_frame(wasm_frame_t* frame) {
Expand Down
18 changes: 14 additions & 4 deletions lib/c-api/examples/wasi.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -12,13 +13,16 @@
void print_wasmer_error()
{
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
if (error_len > 0) {
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
}
}

int main(int argc, const char* argv[]) {

// Initialize.
printf("Initializing...\n");
wasm_engine_t* engine = wasm_engine_new();
Expand Down Expand Up @@ -119,6 +123,7 @@ int main(int argc, const char* argv[]) {
printf("> Error calling function!\n");
return 1;
}
printf("Call completed\n");

{
FILE *memory_stream;
Expand All @@ -137,6 +142,11 @@ int main(int argc, const char* argv[]) {

do {
data_read_size = wasi_env_read_stdout(wasi_env, buffer, BUF_SIZE);
if (data_read_size == -1) {
printf("failed to read stdout: %s\n", strerror(errno));
print_wasmer_error();
return -1;
}

if (data_read_size > 0) {
stdout_size += data_read_size;
Expand Down
5 changes: 2 additions & 3 deletions lib/c-api/src/wasm_c_api/unstable/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::super::{
wasi::wasi_env_t,
};
use wasmer_api::{Exportable, Extern};
use wasmer_wasi::{generate_import_object_from_thread, get_wasi_version};
use wasmer_wasi::{generate_import_object_from_env, get_wasi_version};

/// Unstable non-standard type wrapping `wasm_extern_t` with the
/// addition of two `wasm_name_t` respectively for the module name and
Expand Down Expand Up @@ -170,8 +170,7 @@ fn wasi_get_unordered_imports_inner(
let version = c_try!(get_wasi_version(&module.inner, false)
.ok_or("could not detect a WASI version on the given module"));

let thread = wasi_env.inner.new_thread();
let import_object = generate_import_object_from_thread(store, thread, version);
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);

imports.set_buffer(
import_object
Expand Down
93 changes: 0 additions & 93 deletions lib/c-api/src/wasm_c_api/wasi/capture_files.rs

This file was deleted.

53 changes: 20 additions & 33 deletions lib/c-api/src/wasm_c_api/wasi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
//!
//! This API will be superseded by a standard WASI API when/if such a standard is created.
mod capture_files;

pub use super::unstable::wasi::wasi_get_unordered_imports;
use super::{
externals::{wasm_extern_vec_t, wasm_func_t},
Expand All @@ -12,15 +10,14 @@ use super::{
store::wasm_store_t,
};
use crate::error::update_last_error;
use std::cmp::min;
use std::convert::TryFrom;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::slice;
use wasmer_api::{Exportable, Extern};
use wasmer_wasi::{
generate_import_object_from_thread, get_wasi_version, WasiEnv, WasiFile, WasiState,
WasiStateBuilder, WasiVersion,
generate_import_object_from_env, get_wasi_version, WasiEnv, WasiFile, WasiState,
WasiStateBuilder, WasiVersion, Pipe,
};

#[derive(Debug)]
Expand Down Expand Up @@ -177,13 +174,13 @@ pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<was
if !config.inherit_stdout {
config
.state_builder
.stdout(Box::new(capture_files::OutputCapturer::new()));
.stdout(Box::new(Pipe::new()));
}

if !config.inherit_stderr {
config
.state_builder
.stderr(Box::new(capture_files::OutputCapturer::new()));
.stderr(Box::new(Pipe::new()));
}

// TODO: impl capturer for stdin
Expand All @@ -206,19 +203,19 @@ pub unsafe extern "C" fn wasi_env_read_stdout(
buffer_len: usize,
) -> isize {
let inner_buffer = slice::from_raw_parts_mut(buffer as *mut _, buffer_len as usize);
let mut state = env.inner.state();
let state = env.inner.state();

let stdout = if let Ok(stdout) = state.fs.stdout_mut() {
if let Ok(mut stdout) = state.stdout() {
if let Some(stdout) = stdout.as_mut() {
stdout
read_inner(stdout, inner_buffer)
} else {
update_last_error("could not find a file handle for `stdout`");
return -1;
}
} else {
update_last_error("could not find a file handle for `stdout`");
return -1;
};
read_inner(stdout, inner_buffer)
}
}

#[no_mangle]
Expand All @@ -228,36 +225,27 @@ pub unsafe extern "C" fn wasi_env_read_stderr(
buffer_len: usize,
) -> isize {
let inner_buffer = slice::from_raw_parts_mut(buffer as *mut _, buffer_len as usize);
let mut state = env.inner.state();
let inodes = state.inodes.write().unwrap();
let stderr = if let Ok(stderr) = inodes.stderr_mut(&state.fs.fd_map) {
let state = env.inner.state();
if let Ok(mut stderr) = state.stderr() {
if let Some(stderr) = stderr.as_mut() {
stderr
read_inner(stderr, inner_buffer)
} else {
update_last_error("could not find a file handle for `stderr`");
return -1;
}
} else {
update_last_error("could not find a file handle for `stderr`");
return -1;
};
read_inner(stderr, inner_buffer)
}
}

fn read_inner(wasi_file: &mut Box<dyn WasiFile>, inner_buffer: &mut [u8]) -> isize {
if let Some(oc) = wasi_file.downcast_mut::<capture_files::OutputCapturer>() {
let total_to_read = min(inner_buffer.len(), oc.buffer.len());

for (address, value) in inner_buffer
.iter_mut()
.zip(oc.buffer.drain(..total_to_read))
{
*address = value;
fn read_inner(wasi_file: &mut Box<dyn WasiFile + Send + Sync + 'static>, inner_buffer: &mut [u8]) -> isize {
match wasi_file.read(inner_buffer) {
Ok(a) => a as isize,
Err(err) => {
update_last_error(format!("failed to read wasi_file: {}", err));
-1
}

total_to_read as isize
} else {
-1
}
}

Expand Down Expand Up @@ -356,8 +344,7 @@ fn wasi_get_imports_inner(
let version = c_try!(get_wasi_version(&module.inner, false)
.ok_or("could not detect a WASI version on the given module"));

let mut thread = wasi_env.inner.new_thread();
let import_object = generate_import_object_from_thread(store, thread, version);
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);

imports.set_buffer(c_try!(module
.inner
Expand Down
12 changes: 8 additions & 4 deletions lib/cli/src/commands/run/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use anyhow::Result;
use std::collections::BTreeSet;
use std::path::PathBuf;
use wasmer::{Instance, Module, RuntimeError, Val};
use wasmer_wasi::{get_wasi_versions, WasiError, WasiState, WasiVersion};
use wasmer_wasi::{get_wasi_versions, is_wasix_module, WasiError, WasiState, WasiVersion};

use structopt::StructOpt;

Expand Down Expand Up @@ -96,9 +96,13 @@ impl Wasi {
}
}

let wasi_env = wasi_state_builder.finalize()?;
let mut wasi_thread = wasi_env.new_thread();
let import_object = wasi_thread.import_object_for_all_wasi_versions(&module)?;
let mut wasi_env = wasi_state_builder.finalize()?;
wasi_env.state.fs.is_wasix.store(
is_wasix_module(&module),
std::sync::atomic::Ordering::Release,
);

let import_object = wasi_env.import_object_for_all_wasi_versions(&module)?;
let instance = Instance::new(&module, &import_object)?;
Ok(instance)
}
Expand Down
12 changes: 7 additions & 5 deletions lib/cli/src/commands/wasmer_create_exe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@

static void print_wasmer_error() {
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char *error_str = (char *)malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("%s\n", error_str);
free(error_str);
if (error_len > 0) {
printf("Error len: `%d`\n", error_len);
char *error_str = (char *)malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("%s\n", error_str);
free(error_str);
}
}

#ifdef WASI
Expand Down
Loading

0 comments on commit 6aad270

Please sign in to comment.