From a2d96d9ba7ee744196a3a9f039917387a50ce154 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 26 Oct 2020 15:12:26 +0100 Subject: [PATCH 1/6] feat(c-api) Implement the `traps` argument of `wasm_instance_new`. When running `Instance::new`, it can error with an `InstantiationError`. There is 2 scenarii: 1. Either it's a `InstantiationError::Link`. In this case, the `wasm_instance_new` function must return `NULL` and register the error in the Wasmer error registry. 2. Either it's a `InstantiationError::Start`. In this case, the `wasm_instance_new` function must return `NULL` and the error must be converted into a `wasm_trap_t`, which is stored in the `wasm_trap_t**` array. This array is initialized by `wasm_instance_new` itself. --- lib/c-api/src/wasm_c_api/instance.rs | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index 3b16e1eeffa..38893f3bc7b 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -5,7 +5,7 @@ use super::trap::wasm_trap_t; use crate::ordered_resolver::OrderedResolver; use std::mem; use std::sync::Arc; -use wasmer::{Extern, Instance}; +use wasmer::{Extern, Instance, InstantiationError}; #[allow(non_camel_case_types)] pub struct wasm_instance_t { @@ -17,8 +17,7 @@ pub unsafe extern "C" fn wasm_instance_new( _store: &wasm_store_t, module: &wasm_module_t, imports: &wasm_extern_vec_t, - // own - _traps: *mut *mut wasm_trap_t, + traps: *mut *mut wasm_trap_t, ) -> Option> { let wasm_module = &module.inner; let module_imports = wasm_module.imports(); @@ -32,7 +31,35 @@ pub unsafe extern "C" fn wasm_instance_new( .cloned() .collect(); - let instance = Arc::new(c_try!(Instance::new(wasm_module, &resolver))); + let instance = match Instance::new(wasm_module, &resolver) { + Ok(instance) => Arc::new(instance), + + Err(InstantiationError::Link(link_error)) => { + crate::error::update_last_error(link_error); + + return None; + } + + Err(InstantiationError::Start(runtime_error)) => { + let pointer = { + let trap: Box = Box::new(runtime_error.into()); + let mut traps: Vec<*mut wasm_trap_t> = Vec::with_capacity(1); + traps.push(Box::into_raw(trap)); + + debug_assert!(traps.len() == traps.capacity()); + + let pointer = traps.as_mut_ptr(); + mem::forget(traps); + + pointer + }; + + *traps = *pointer; + + return None; + } + }; + Some(Box::new(wasm_instance_t { inner: instance })) } From 38c57e138f56060cb43425aca2b894a738251949 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 26 Oct 2020 15:27:08 +0100 Subject: [PATCH 2/6] test(c-api) Enable the `wasm-c-api-start` test. --- lib/c-api/tests/wasm_c_api/CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/c-api/tests/wasm_c_api/CMakeLists.txt b/lib/c-api/tests/wasm_c_api/CMakeLists.txt index 1ac9b3eaf53..d725c5a4f0a 100644 --- a/lib/c-api/tests/wasm_c_api/CMakeLists.txt +++ b/lib/c-api/tests/wasm_c_api/CMakeLists.txt @@ -11,7 +11,7 @@ add_executable(wasm-c-api-hello wasm-c-api/example/hello.c) #add_executable(wasm-c-api-multi wasm-c-api/example/multi.c) add_executable(wasm-c-api-reflect wasm-c-api/example/reflect.c) add_executable(wasm-c-api-serialize wasm-c-api/example/serialize.c) -#add_executable(wasm-c-api-start wasm-c-api/example/start.c) +add_executable(wasm-c-api-start wasm-c-api/example/start.c) #add_executable(wasm-c-api-table wasm-c-api/example/table.c) #add_executable(wasm-c-api-threads wasm-c-api/example/threads.c) add_executable(wasm-c-api-trap wasm-c-api/example/trap.c) @@ -106,12 +106,12 @@ add_test(NAME wasm-c-api-serialize WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/ ) -#target_link_libraries(wasm-c-api-start general ${WASMER_LIB}) -#target_compile_options(wasm-c-api-start PRIVATE ${COMPILER_OPTIONS}) -#add_test(NAME wasm-c-api-start -# COMMAND wasm-c-api-start -# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/ -#) +target_link_libraries(wasm-c-api-start general ${WASMER_LIB}) +target_compile_options(wasm-c-api-start PRIVATE ${COMPILER_OPTIONS}) +add_test(NAME wasm-c-api-start + COMMAND wasm-c-api-start + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/ +) #target_link_libraries(wasm-c-api-table general ${WASMER_LIB}) #target_compile_options(wasm-c-api-table PRIVATE ${COMPILER_OPTIONS}) From 246b7d2866da52542bb11693a443cbd2bc9d8648 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 26 Oct 2020 15:34:45 +0100 Subject: [PATCH 3/6] doc(changelog) Add #1761. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4621db71a3e..ab45e523c11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,10 @@ ## **[Unreleased]** - [#1710](https://github.com/wasmerio/wasmer/pull/1710) Memory for function call trampolines is now owned by the Artifact. + ### Added +- [#1761](https://github.com/wasmerio/wasmer/pull/1761) Implement the `wasm_trap_t**` argument of `wasm_instance_new` in the Wasm C API. - [#1741](https://github.com/wasmerio/wasmer/pull/1741) Implement `wasm_memory_type` in the Wasm C API. - [#1736](https://github.com/wasmerio/wasmer/pull/1736) Implement `wasm_global_type` in the Wasm C API. - [#1699](https://github.com/wasmerio/wasmer/pull/1699) Update `wasm.h` to its latest version. From 452181326aeaa9420b9acf56361bb26609e6ca35 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 27 Oct 2020 11:44:38 +0100 Subject: [PATCH 4/6] fix(c-api) Remove a `debug_assert` macro. --- lib/c-api/src/wasm_c_api/instance.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index 38893f3bc7b..423c2c1efcd 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -46,8 +46,6 @@ pub unsafe extern "C" fn wasm_instance_new( let mut traps: Vec<*mut wasm_trap_t> = Vec::with_capacity(1); traps.push(Box::into_raw(trap)); - debug_assert!(traps.len() == traps.capacity()); - let pointer = traps.as_mut_ptr(); mem::forget(traps); From 4102dcb9acdcfe88c750d39402c02dc335d75073 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 27 Oct 2020 11:49:01 +0100 Subject: [PATCH 5/6] feat(c-api) Shrink vector of traps. Ensure that the size of the vector of the instance's traps equals its capacity by shrinking it. --- lib/c-api/src/wasm_c_api/instance.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index 423c2c1efcd..d090cf144fc 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -45,6 +45,7 @@ pub unsafe extern "C" fn wasm_instance_new( let trap: Box = Box::new(runtime_error.into()); let mut traps: Vec<*mut wasm_trap_t> = Vec::with_capacity(1); traps.push(Box::into_raw(trap)); + traps.shrink_to_fit(); let pointer = traps.as_mut_ptr(); mem::forget(traps); From 9583a91678a81debfe70ef8c311f3d6f85c646cd Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 30 Oct 2020 09:34:37 +0100 Subject: [PATCH 6/6] fix(c-api) `wasm_trap_t**` in `wasm_instance_new` does not represent an array. The `wasm_trap_t**` argument of `wasm_instance_new` represents an output pointer to a `wasm_trap_t*`, not an array of `wasm_trap_t*`. This patch updates the code accordingly. --- lib/c-api/src/wasm_c_api/instance.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index d090cf144fc..f1f46d1d719 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -41,19 +41,8 @@ pub unsafe extern "C" fn wasm_instance_new( } Err(InstantiationError::Start(runtime_error)) => { - let pointer = { - let trap: Box = Box::new(runtime_error.into()); - let mut traps: Vec<*mut wasm_trap_t> = Vec::with_capacity(1); - traps.push(Box::into_raw(trap)); - traps.shrink_to_fit(); - - let pointer = traps.as_mut_ptr(); - mem::forget(traps); - - pointer - }; - - *traps = *pointer; + let trap: Box = Box::new(runtime_error.into()); + *traps = Box::into_raw(trap); return None; }