Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(c-api) Handle initialized but empty results in wasm_func_call #1783

Merged
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
## **[Unreleased]**

- [#1710](https://github.com/wasmerio/wasmer/pull/1710) Memory for function call trampolines is now owned by the Artifact.
- [#1783](https://github.com/wasmerio/wasmer/pull/1783) Handle initialized but empty results in `wasm_func_call` in the Wasm C API.

### Added

Expand Down
24 changes: 20 additions & 4 deletions lib/c-api/src/wasm_c_api/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,34 @@ pub unsafe extern "C" fn wasm_func_call(
.into_iter()
.map(TryInto::try_into)
.collect::<Result<Vec<Val>, _>>()
.expect("Argument conversion failed")
.expect("Arguments conversion failed")
})
.unwrap_or_default();

match func.inner.call(&params) {
Ok(wasm_results) => {
*results = wasm_results
let vals = wasm_results
.into_iter()
.map(TryInto::try_into)
.collect::<Result<Vec<wasm_val_t>, _>>()
.expect("Argument conversion failed")
.into();
.expect("Results conversion failed");

// `results` is an uninitialized vector. Set a new value.
if results.size == 0 || results.data.is_null() {
Hywan marked this conversation as resolved.
Show resolved Hide resolved
*results = vals.into();
}
// `results` is an initialized but empty vector. Fill it
// item per item.
else {
let slice = results
.into_slice_mut()
.expect("`wasm_func_call`, results' size is greater than 0 but data is NULL");

for (result, value) in slice.iter_mut().zip(vals.iter()) {
(*result).kind = value.kind;
(*result).of = value.of;
}
}

None
}
Expand Down
10 changes: 10 additions & 0 deletions lib/c-api/src/wasm_c_api/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ macro_rules! wasm_declare_vec {
}
}

impl [<wasm_ $name _vec_t>] {
pub unsafe fn into_slice_mut(&self) -> Option<&mut [[<wasm_ $name _t>]]>{
if self.data.is_null() {
return None;
}

Some(::std::slice::from_raw_parts_mut(self.data, self.size))
}
}

// 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
14 changes: 7 additions & 7 deletions lib/c-api/tests/wasm_c_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project (WasmerWasmCApiTests)
# Examples as tests from the `wasm-c-api` repository.
add_executable(wasm-c-api-callback wasm-c-api/example/callback.c)
#add_executable(wasm-c-api-finalize wasm-c-api/example/finalize.c)
#add_executable(wasm-c-api-global wasm-c-api/example/global.c)
add_executable(wasm-c-api-global wasm-c-api/example/global.c)
add_executable(wasm-c-api-hello wasm-c-api/example/hello.c)
#add_executable(wasm-c-api-hostref wasm-c-api/example/hostref.c)
#add_executable(wasm-c-api-memory wasm-c-api/example/memory.c)
Expand Down Expand Up @@ -57,12 +57,12 @@ add_test(NAME wasm-c-api-callback
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
#)

#target_link_libraries(wasm-c-api-global general ${WASMER_LIB})
#target_compile_options(wasm-c-api-global PRIVATE ${COMPILER_OPTIONS})
#add_test(NAME wasm-c-api-global
# COMMAND wasm-c-api-global
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
#)
target_link_libraries(wasm-c-api-global general ${WASMER_LIB})
target_compile_options(wasm-c-api-global PRIVATE ${COMPILER_OPTIONS})
add_test(NAME wasm-c-api-global
COMMAND wasm-c-api-global
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
)

target_link_libraries(wasm-c-api-hello general ${WASMER_LIB})
target_compile_options(wasm-c-api-hello PRIVATE ${COMPILER_OPTIONS})
Expand Down