Add two apis for wasm function call (#375)

Add below two apis:

bool wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
                                                      WASMFunctionInstanceCommon *function,
                                                      uint32 num_results, wasm_val_t results[],
                                                      uint32 num_args, wasm_val_t args[])

bool wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
                                                      WASMFunctionInstanceCommon *function,
                                                      uint32 num_results, wasm_val_t results[],
                                                      uint32 num_args, ...)

Signed-off-by: Xiaokang Qin <xiaokang.qxk@antgroup.com>
This commit is contained in:
Xiaokang Qin
2020-09-08 13:03:35 +08:00
committed by GitHub
parent 2135badc54
commit 5418e09712
5 changed files with 359 additions and 3 deletions

View File

@ -71,17 +71,23 @@ if (!wasm_runtime_full_init(&init_args)) {
## Native calls WASM functions and passes parameters
After a module is instantiated, the runtime native can lookup WASM functions by the names and call them.
After a module is instantiated, the runtime embedder can lookup the target WASM function by name, and create execution environment to call the function.
```c
unit32 argv[2];
/* lookup a WASM function by its name
The function signature can NULL here */
func = wasm_runtime_lookup_function(module_inst, "fib", NULL);
/* creat an execution environment to execute the WASM functions */
exec_env = wasm_runtime_create_exec_env(module_inst, stack_size);
```
There are several ways to call WASM function:
1. Function call with parameters in an array of 32 bits elements and size:
```c
unit32 argv[2];
/* arguments are always transferred in 32-bit element */
argv[0] = 8;
@ -129,6 +135,44 @@ The parameters are transferred in an array of 32 bits elements. For parameters t
memcpy(&ret, &argv[0], sizeof(ret));
```
2. Function call with results and arguments both in `wasm_val_t` struct and size:
```c
unit32 num_args = 1, num_results = 1;
wasm_val_t args[1], results[1];
/* set the argument type and value */
args[0].kind = WASM_I32;
args[0].of.i32 = 8;
/* call the WASM function */
if (wasm_runtime_call_wasm_a(exec_env, func, num_results, results, num_args, args)) {
/* the return value is stored in results */
printf("fib function return: %d\n", results[0].of.i32);
}
else {
/* exception is thrown if call fails */
printf("%s\n", wasm_runtime_get_exception(module_inst));
}
```
3. Function call with variant argument support:
```c
unit32 num_args = 1, num_results = 1;
wasm_val_t results[1];
/* call the WASM function */
if (wasm_runtime_call_wasm_v(exec_env, func, 1, results, 1, 8)) {
/* the return value is stored in results */
printf("fib function return: %d\n", results[0].of.i32);
}
else {
/* exception is thrown if call fails */
printf("%s\n", wasm_runtime_get_exception(module_inst));
}
```
## Pass buffer to WASM function
If we need to transfer a buffer to WASM function, we can pass the buffer address through a parameter. **Attention**: The sandbox will forbid the WASM code to access outside memory, we must **allocate the buffer from WASM instance's own memory space and pass the buffer address in instance's space (not the runtime native address)**.