wamr-python: Enable debugging WASM and grant dir access (#2449)

- Enable debugging a WASM loaded and executed from Python.
- Expose API to enable access to list of host directories. Similar to --dir in iwasm.
- Add another python language binding sample: native-symbol.
This commit is contained in:
tonibofarull
2023-08-15 04:32:43 +02:00
committed by GitHub
parent 365cdfeb71
commit 571c057549
10 changed files with 277 additions and 29 deletions

View File

@ -0,0 +1,44 @@
# Native Symbol
This sample demonstrates how to declare a Python function as `NativeSymbol`.
Steps of the example:
1. Load WASM from Python
2. Call `c_func` from WASM.
3. `c_func` calls `python_func` from Python.
4. `python_func` calls `add` from WASM.
5. Result shown by Python.
## Build
Follow instructions [build wamr Python package](../../README.md).
Compile WASM app example,
```sh
./compile.sh
```
## Run sample
```sh
python main.py
```
Output:
```
python: calling c_func(10)
c: in c_func with input: 10
c: calling python_func(11)
python: in python_func with input: 11
python: calling add(11, 1000)
python: result from add: 1011
c: result from python_func: 1012
c: returning 1013
python: result from c_func: 1013
deleting ExecEnv
deleting Instance
deleting Module
deleting Engine
```

View File

@ -0,0 +1,14 @@
#!/bin/sh
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/opt/wasi-sdk/bin/clang \
-O0 -z stack-size=4096 -Wl,--initial-memory=65536 \
-Wl,--export=main -Wl,--export=__main_argc_argv \
-Wl,--export=__data_end -Wl,--export=__heap_base \
-Wl,--strip-all,--no-entry \
-Wl,--allow-undefined \
-Wl,--export=c_func\
-Wl,--export=add\
-o func.wasm func.c

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
int
python_func(int val);
int
add(int val1, int val2)
{
return val1 + val2;
}
int
c_func(int val)
{
printf("c: in c_func with input: %d\n", val);
printf("c: calling python_func(%d)\n", val + 1);
int res = python_func(val + 1);
printf("c: result from python_func: %d\n", res);
printf("c: returning %d\n", res + 1);
return res + 1;
}
int
main()
{}

View File

@ -0,0 +1,59 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
from wamr.wamrapi.wamr import Engine, Module, Instance, ExecEnv
from ctypes import c_uint
import pathlib
from ctypes import c_int32
from ctypes import c_uint
from ctypes import c_void_p
from ctypes import cast
from ctypes import CFUNCTYPE
from wamr.wamrapi.iwasm import NativeSymbol
from wamr.wamrapi.iwasm import String
from wamr.wamrapi.wamr import ExecEnv
def python_func(env: int, value: int) -> int:
print("python: in python_func with input:", value)
# Example of generating ExecEnv from `wasm_exec_env_t``
exec_env = ExecEnv.wrap(env)
add = exec_env.get_module_inst().lookup_function("add")
const = 1000
argv = (c_uint * 2)(value, const)
print(f"python: calling add({value}, {const})")
exec_env.call(add, 2, argv)
res = argv[0]
print("python: result from add:", res)
return res + 1
native_symbols = (NativeSymbol * 1)(
*[
NativeSymbol(
symbol=String.from_param("python_func"),
func_ptr=cast(
CFUNCTYPE(c_int32, c_void_p, c_int32)(python_func), c_void_p
),
signature=String.from_param("(i)i"),
)
]
)
def main():
engine = Engine()
engine.register_natives("env", native_symbols)
module = Module.from_file(engine, pathlib.Path(__file__).parent / "func.wasm")
module_inst = Instance(module)
exec_env = ExecEnv(module_inst)
func = module_inst.lookup_function("c_func")
inp = 10
print(f"python: calling c_func({inp})")
argv = (c_uint)(inp)
exec_env.call(func, 1, argv)
print("python: result from c_func:", argv.value)
if __name__ == "__main__":
main()