Skip to content

Commit

Permalink
Address feedback, clean up wasm_T_vec_t conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark McCaskey committed Sep 29, 2020
1 parent d53d58e commit ffe1c5a
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 61 deletions.
8 changes: 4 additions & 4 deletions examples/early_exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn main() -> anyhow::Result<()> {
};
let instance = Instance::new(&module, &import_object)?;

// get the `run` function which we'll use as our entrypoint.
// Get the `run` function which we'll use as our entrypoint.
let run_func: NativeFunc<(i32, i32), i32> =
instance.exports.get_native_function("run").unwrap();

Expand All @@ -66,10 +66,10 @@ fn main() -> anyhow::Result<()> {
result
);
}
// we're expecting it to fail.
// we attempt to downcast the error into the error type that we were expecting.
// We're expecting it to fail.
// We attempt to downcast the error into the error type that we were expecting.
Err(e) => match e.downcast::<ExitCode>() {
// we found the exit code used to terminate execution.
// We found the exit code used to terminate execution.
Ok(exit_code) => {
println!("Exited early with exit code: {}", exit_code);
Ok(())
Expand Down
65 changes: 39 additions & 26 deletions lib/c-api/src/wasm_c_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,13 +713,10 @@ pub unsafe extern "C" fn wasm_func_new(
];

let trap = callback(processed_args.as_ptr(), results.as_mut_ptr());
dbg!(&trap);
if !trap.is_null() {
let trap: Box<wasm_trap_t> = Box::from_raw(trap);
dbg!("raising trap!");
RuntimeError::raise(Box::new(trap.inner));
}
// TODO: do something with `traps`

let processed_results = results
.into_iter()
Expand Down Expand Up @@ -1056,6 +1053,38 @@ macro_rules! wasm_declare_vec {
}
}


impl<'a> From<Vec<[<wasm_ $name _t>]>> for [<wasm_ $name _vec_t>] {
fn from(other: Vec<[<wasm_ $name _t>]>) -> Self {
let mut boxed_slice = other.into_boxed_slice();
let size = boxed_slice.len();
let data = boxed_slice.as_mut_ptr();
mem::forget(boxed_slice);
Self {
size,
data,
}
}
}

impl<'a, T: Into<[<wasm_ $name _t>]> + Clone> From<&'a [T]> for [<wasm_ $name _vec_t>] {
fn from(other: &'a [T]) -> Self {
let size = other.len();
let mut copied_data = other
.iter()
.cloned()
.map(Into::into)
.collect::<Vec<[<wasm_ $name _t>]>>()
.into_boxed_slice();
let data = copied_data.as_mut_ptr();
mem::forget(copied_data);
Self {
size,
data,
}
}
}

// TODO: investigate possible memory leak on `init` (owned pointer)
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new>](out: *mut [<wasm_ $name _vec_t>], length: usize, init: *mut [<wasm_ $name _t>]) {
Expand Down Expand Up @@ -1185,39 +1214,23 @@ pub unsafe extern "C" fn wasm_trap_delete(_trap: Option<Box<wasm_trap_t>>) {}
#[no_mangle]
pub unsafe extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out_ptr: &mut wasm_byte_vec_t) {
let message = trap.inner.message();
out_ptr.size = message.len();
// TODO: make helper function for converting `Vec<T>` into owned `wasm_T_vec_t`
let mut dupe_data: Box<[u8]> = message.into_bytes().into_boxed_slice();
out_ptr.data = dupe_data.as_mut_ptr();
mem::forget(dupe_data);
let byte_vec: wasm_byte_vec_t = message.into_bytes().into();
out_ptr.size = byte_vec.size;
out_ptr.data = byte_vec.data;
}

#[no_mangle]
pub unsafe extern "C" fn wasm_trap_origin(trap: &wasm_trap_t) -> Option<Box<wasm_frame_t>> {
trap.inner.trace().first().map(Into::into).map(Box::new)
}

// TODO: old comment, rm after finish implementation
// in trap/RuntimeError we need to store
// 1. message
// 2. origin (frame); frame contains:
// 1. func index
// 2. func offset
// 3. module offset
// 4. which instance this was apart of

#[no_mangle]
pub unsafe extern "C" fn wasm_trap_trace(trap: &wasm_trap_t, out_ptr: &mut wasm_frame_vec_t) {
let frames = trap.inner.trace();
out_ptr.size = frames.len();
// TODO: make helper function for converting `Vec<T>` into owned `wasm_T_vec_t`
let mut dupe_data: Box<[wasm_frame_t]> = frames
.iter()
.map(Into::into)
.collect::<Vec<wasm_frame_t>>()
.into_boxed_slice();
out_ptr.data = dupe_data.as_mut_ptr();
mem::forget(dupe_data);
let frame_vec: wasm_frame_vec_t = frames.into();

out_ptr.size = frame_vec.size;
out_ptr.data = frame_vec.data;
}

#[repr(C)]
Expand Down
3 changes: 2 additions & 1 deletion lib/c-api/tests/assets/call_trap.wat
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
(i32.add
(local.get $x)
(local.get $y)))
(export "run" (func $run)))
(export "run" (func $run)))

62 changes: 32 additions & 30 deletions lib/c-api/tests/wasm-c-api-early-exit.c
Original file line number Diff line number Diff line change
@@ -1,40 +1,48 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include "wasm.h"
#include "wasmer_wasm.h"

// Use the last_error API to retrieve error messages
void print_wasmer_error()
{
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);
}

wasm_store_t* store = NULL;
void print_frame(wasm_frame_t* frame) {
printf("> %p @ 0x%zx = %"PRIu32".0x%zx\n",
wasm_frame_instance(frame),
wasm_frame_module_offset(frame),
wasm_frame_func_index(frame),
wasm_frame_func_offset(frame)
);
}

own wasm_trap_t* early_exit(const wasm_val_t args[], wasm_val_t results[]) {
wasm_store_t *store = NULL;

own wasm_trap_t *early_exit(const wasm_val_t args[], wasm_val_t results[]) {
own wasm_message_t trap_message;
wasm_name_new_from_string(&trap_message,"trapping from a host import");
own wasm_trap_t* trap = wasm_trap_new(store, &trap_message);
wasm_name_new_from_string(&trap_message, "trapping from a host import");
own wasm_trap_t *trap = wasm_trap_new(store, &trap_message);
wasm_name_delete(&trap_message);
return trap;
}

int main(int argc, const char* argv[]) {
int main(int argc, const char *argv[]) {
// Initialize.
printf("Initializing...\n");
wasm_engine_t* engine = wasm_engine_new();
wasm_engine_t *engine = wasm_engine_new();
store = wasm_store_new(engine);

// Load binary.
printf("Loading binary...\n");
FILE* file = fopen("assets/call_trap.wasm", "r");
FILE *file = fopen("assets/call_trap.wasm", "r");
if (!file) {
printf("> Error loading module!\n");
return 1;
Expand All @@ -52,7 +60,7 @@ int main(int argc, const char* argv[]) {

// Compile.
printf("Compiling module...\n");
own wasm_module_t* module = wasm_module_new(store, &binary);
own wasm_module_t *module = wasm_module_new(store, &binary);
if (!module) {
printf("> Error compiling module!\n");
return 1;
Expand All @@ -63,14 +71,14 @@ int main(int argc, const char* argv[]) {
// Instantiate.
printf("Instantiating module...\n");

wasm_functype_t* host_func_type = wasm_functype_new_0_0();
wasm_func_t* host_func = wasm_func_new(store, host_func_type, early_exit);
wasm_functype_t *host_func_type = wasm_functype_new_0_0();
wasm_func_t *host_func = wasm_func_new(store, host_func_type, early_exit);

wasm_functype_delete(host_func_type);

const wasm_extern_t* imports[] = { wasm_func_as_extern(host_func) };
own wasm_instance_t* instance =
wasm_instance_new(store, module, imports, NULL);
const wasm_extern_t *imports[] = {wasm_func_as_extern(host_func)};
own wasm_instance_t *instance =
wasm_instance_new(store, module, imports, NULL);
if (!instance) {
printf("> Error instantiating module!\n");
print_wasmer_error();
Expand All @@ -88,11 +96,11 @@ int main(int argc, const char* argv[]) {
return 1;
}
fprintf(stderr, "found %zu exports\n", exports.size);

wasm_module_delete(module);
wasm_instance_delete(instance);

wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
wasm_func_t *run_func = wasm_extern_as_func(exports.data[0]);
if (run_func == NULL) {
printf("> Error accessing export!\n");
print_wasmer_error();
Expand All @@ -102,17 +110,11 @@ int main(int argc, const char* argv[]) {
// Call.
printf("Calling export...\n");
own const wasm_val_t args[] = {
{
.kind = WASM_I32,
.of = { .i32 = 1 }
},
{
.kind = WASM_I32,
.of = { .i32 = 7 }
},
{.kind = WASM_I32, .of = {.i32 = 1}},
{.kind = WASM_I32, .of = {.i32 = 7}},
};
own wasm_val_t rets[1] = { };
own wasm_trap_t* trap = wasm_func_call(run_func, args, rets);
own wasm_val_t rets[1] = {};
own wasm_trap_t *trap = wasm_func_call(run_func, args, rets);
if (!trap) {
printf("> Error calling function: expected trap!\n");
return 1;
Expand All @@ -123,7 +125,7 @@ int main(int argc, const char* argv[]) {
wasm_trap_message(trap, &message);
printf("> %s\n", message.data);

/* printf("Printing origin...\n");
printf("Printing origin...\n");
own wasm_frame_t* frame = wasm_trap_origin(trap);
if (frame) {
print_frame(frame);
Expand All @@ -143,7 +145,7 @@ int main(int argc, const char* argv[]) {
printf("> Empty trace.\n");
}

wasm_frame_vec_delete(&trace);*/
wasm_frame_vec_delete(&trace);
wasm_trap_delete(trap);
wasm_name_delete(&message);

Expand Down

0 comments on commit ffe1c5a

Please sign in to comment.