Skip to content

Commit

Permalink
Merge pull request astrale-sharp#14 from arnaudgolfouse/tests
Browse files Browse the repository at this point in the history
Tests
  • Loading branch information
astrale-sharp authored Aug 6, 2023
2 parents fc685b3 + b56ffba commit b05bb81
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 102 deletions.
2 changes: 1 addition & 1 deletion examples/hello_c/hello.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ EMSCRIPTEN_KEEPALIVE void wasm_minimal_protocol_free_byte_buffer(uint8_t *ptr,

EMSCRIPTEN_KEEPALIVE
int32_t hello(void) {
const char static_message[] = "Hello world !";
const char static_message[] = "Hello from wasm!!!";
const size_t length = sizeof(static_message);
char *message = malloc(length);
memcpy((void *)message, (void *)static_message, length);
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn hello() -> Vec<u8> {

#[wasm_func]
pub fn double_it(arg: &[u8]) -> Vec<u8> {
[arg, b".", arg].concat()
[arg, arg].concat()
}

#[wasm_func]
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_zig/hello.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export fn wasm_minimal_protocol_free_byte_buffer(ptr: [*]u8, len: usize) void {
// ===

export fn hello() i32 {
const message = "Hello world !";
const message = "Hello from wasm!!!";
var result = allocator.alloc(u8, message.len) catch return 1;
@memcpy(result, message);
wasm_minimal_protocol_send_result_to_host(result.ptr, result.len);
Expand Down
71 changes: 41 additions & 30 deletions examples/host-wasmi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ impl<'a> ReturnedData<'a> {

impl Drop for ReturnedData<'_> {
fn drop(&mut self) {
self.free_function
.call(
&mut *self.context_mut,
&[Value::I32(self.ptr as _), Value::I32(self.len as _)],
&mut [],
)
.unwrap();
if self.ptr != 0 {
self.free_function
.call(
&mut *self.context_mut,
&[Value::I32(self.ptr as _), Value::I32(self.len as _)],
&mut [],
)
.unwrap();
}
}
}

Expand Down Expand Up @@ -123,36 +125,40 @@ impl PluginInstance {
})
}

fn write(&mut self, args: &[&[u8]]) {
self.store.data_mut().arg_buffer = args.concat();
}

pub fn call(&mut self, function: &str, args: &[&[u8]]) -> Result<ReturnedData, String> {
self.write(args);
pub fn call<'a>(
&mut self,
function: &str,
args: impl IntoIterator<Item = &'a [u8]>,
) -> Result<ReturnedData, String> {
self.store.data_mut().result_ptr = 0;
self.store.data_mut().result_len = 0;

let mut result_args = Vec::new();
let arg_buffer = &mut self.store.data_mut().arg_buffer;
arg_buffer.clear();
for arg in args {
result_args.push(Value::I32(arg.len() as _));
arg_buffer.extend_from_slice(arg);
}

let (_, function) = self
.functions
.iter()
.find(|(s, _)| s == function)
.ok_or(format!("Plugin doesn't have the method: {function}"))?;

let result_args = args
.iter()
.map(|a| Value::I32(a.len() as _))
.collect::<Vec<_>>();
.ok_or(format!("plugin doesn't have the method: {function}"))?;

let mut code = [Value::I32(2)];
let is_err = function
.call(&mut self.store, &result_args, &mut code)
.is_err();
let code = if is_err {
Value::I32(2)
} else {
code.first().cloned().unwrap_or(Value::I32(3)) // if the function returns nothing
};
let mut code = Value::I32(2);
let ty = function.ty(&self.store);
if ty.params().len() != result_args.len() {
return Err("incorrect number of arguments".to_string());
}

let call_result = function.call(
&mut self.store,
&result_args,
std::array::from_mut(&mut code),
);
let (ptr, len) = (self.store.data().result_ptr, self.store.data().result_len);

let result = ReturnedData {
memory: self.memory,
ptr,
Expand All @@ -161,13 +167,18 @@ impl PluginInstance {
context_mut: &mut self.store,
};

match call_result {
Ok(()) => {}
Err(wasmi::Error::Trap(_)) => return Err("plugin panicked".to_string()),
Err(_) => return Err("plugin did not respect the protocol".to_string()),
};

match code {
Value::I32(0) => Ok(result),
Value::I32(1) => Err(match std::str::from_utf8(result.get()) {
Ok(err) => format!("plugin errored with: '{}'", err,),
Err(_) => String::from("plugin errored and did not return valid UTF-8"),
}),
Value::I32(2) => Err("plugin panicked".to_string()),
_ => Err("plugin did not respect the protocol".to_string()),
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/test-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ edition = "2021"
anyhow = "1.0.71"
cfg-if = "1.0.0"
host-wasmi = { path = "../host-wasmi" }
wasi-stub = { path = "../../wasi-stub", optional = true }
wasi-stub = { path = "../../wasi-stub" }


[features]
default = []
wasi = ["dep:wasi-stub"]
wasi = []
Loading

0 comments on commit b05bb81

Please sign in to comment.