mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 21:58:20 +00:00
feat(c-api) Handle initialized but empty results in wasm_func_call.
Our implementation of `wasm_func_call` was correct for C code as follows: ```c wasm_val_vec_t arguments = WASM_EMPTY_VEC; wasm_val_vec_t results = WASM_EMPTY_VEC; wasm_func_call(func, &arguments, &results); ``` However, for a C code such as: ```c wasm_val_t vals[1]; wasm_val_vec_t arguments = WASM_EMPTY_VEC; wasm_val_vec_t results = WASM_ARRAY_VEC(vals); wasm_func_call(func, &arguments, &results); ``` the `vals` array were kept empty/unchanged. Why? Because `wasm_func_call` was replacing the value of `results` by a new `wasm_val_vec_t`. It is correct when `results` is an empty vector, but it is incorrect when `results` is initialized with empty values. This patch tries to detect this pattern: If `results.data` is `null`, it means the vector is empty/uninitialized, and we can set a new `wasm_val_vec_t`, otherwise it means the vector is initialized with empty values, and we need to update each item individually.
This commit is contained in:
24
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
24
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
@@ -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(¶ms) {
|
||||
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() {
|
||||
*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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user