From 3d34a91f0b7046b1f4fde5c69d8ae4bb05d8baaa Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 31 May 2022 16:39:46 +0800 Subject: [PATCH] Implement Python language binding (#1192) (#1195) Implement the first version of Python language binding Co-authored-by: liang.he --- language-bindings/python/.gitignore | 160 ++ language-bindings/python/LICENSE | 1 + language-bindings/python/README.md | 31 + language-bindings/python/docs/design.md | 708 ++++++ .../docs/images/python_package_life_cycle.png | Bin 0 -> 76811 bytes .../python/docs/setup_dev_env.md | 12 + language-bindings/python/pyproject.toml | 3 + language-bindings/python/requirements.txt | 5 + language-bindings/python/samples/hello.wat | 4 + language-bindings/python/samples/hello_oop.py | 41 + .../python/samples/hello_procedural.py | 93 + language-bindings/python/setup.py | 30 + language-bindings/python/tests/__init__.py | 7 + language-bindings/python/tests/context.py | 13 + .../python/tests/test_advanced.py | 525 +++++ language-bindings/python/tests/test_basic.py | 1588 +++++++++++++ language-bindings/python/utils/bindgen.py | 386 ++++ language-bindings/python/wamr/__init__.py | 7 + language-bindings/python/wamr/binding.py | 2020 +++++++++++++++++ language-bindings/python/wamr/ffi.py | 642 ++++++ 20 files changed, 6276 insertions(+) create mode 100644 language-bindings/python/.gitignore create mode 120000 language-bindings/python/LICENSE create mode 100644 language-bindings/python/README.md create mode 100644 language-bindings/python/docs/design.md create mode 100644 language-bindings/python/docs/images/python_package_life_cycle.png create mode 100644 language-bindings/python/docs/setup_dev_env.md create mode 100644 language-bindings/python/pyproject.toml create mode 100644 language-bindings/python/requirements.txt create mode 100644 language-bindings/python/samples/hello.wat create mode 100644 language-bindings/python/samples/hello_oop.py create mode 100644 language-bindings/python/samples/hello_procedural.py create mode 100755 language-bindings/python/setup.py create mode 100644 language-bindings/python/tests/__init__.py create mode 100644 language-bindings/python/tests/context.py create mode 100644 language-bindings/python/tests/test_advanced.py create mode 100644 language-bindings/python/tests/test_basic.py create mode 100644 language-bindings/python/utils/bindgen.py create mode 100644 language-bindings/python/wamr/__init__.py create mode 100644 language-bindings/python/wamr/binding.py create mode 100644 language-bindings/python/wamr/ffi.py diff --git a/language-bindings/python/.gitignore b/language-bindings/python/.gitignore new file mode 100644 index 00000000..65efaeda --- /dev/null +++ b/language-bindings/python/.gitignore @@ -0,0 +1,160 @@ +# Refer to https://github.com/github/gitignore/blob/main/Python.gitignore +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# virtual environment +Pipfile + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# VSCode settings +.vscode/ + diff --git a/language-bindings/python/LICENSE b/language-bindings/python/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/language-bindings/python/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/language-bindings/python/README.md b/language-bindings/python/README.md new file mode 100644 index 00000000..2698a059 --- /dev/null +++ b/language-bindings/python/README.md @@ -0,0 +1,31 @@ +# wamr-python + +## Installation + +### Installing from the source code + +Installing from local source tree is in _development mode_. The package appears to be installed but still is editable from the source tree. + +```bash +$ python -m pip install -e /path/to/wamr-root/binding/python +``` + +## Usage + +```python +import wamr.ffi as ffi +``` + +### Preparation + +The binding will load the shared library _libiwasm.so_ from the WAMR repo. So before running the binding, you need to build the library yourself. + +The default compile options are good enough. + +Please be aware that `wasm_frame_xxx` and `wasm_trap_xxx` only work well when enabling `WAMR_BUILD_DUMP_CALL_STACK`. + +### Examples + +There is a [simple example](./samples/hello_procedural.py) to show how to use bindings. Actually, the python binding follows C-APIs. There it should be easy if be familiar with _programming with wasm-c-api_. + +Unit test cases under _./tests_ could be another but more complete references. diff --git a/language-bindings/python/docs/design.md b/language-bindings/python/docs/design.md new file mode 100644 index 00000000..6c3bc916 --- /dev/null +++ b/language-bindings/python/docs/design.md @@ -0,0 +1,708 @@ +# how to implement a python binding of WAMR + +A python language binding of Wasm runtime allows its users to call a set of APIs of +the runtime from the python world. Those APIs maybe implemented in C, C++, or Rust. + +In the WAMR case, a python binding allows APIs in `core/iwasm/include/wasm_c_api.h` +to be used in the python scripts. To achieve that, we will create two kinds +of stuff: wrappers of structured data types and wrappers of functions under the +help of _ctypes_. + +Cyptes is a tool in the standard library for creating Python bindings. It +provides a low-level toolset for loading shared libraries and marshaling +data between Python and C. Other options include _cffi_, _pybind11_, +_cpython_ and so on. Because we tend to make the binding depending on least +items. The built-in module, _ctypes_, is a good choice. + +## General rules to marshal + +The core of the idea of a language binding is how to translate different +representations of types in different language. + +### load libraries + +The `ctypes` supports locating a dynamic link library in a way similar to the +compiler does. + +Currently, `ctypes.LoadLibrary` supports: + +- `CDLL`. Those libraries use the standard C calling conversion. +- `OleDLL` and `WinDLL`. Those libraries use the `stdcall` calling conversion on + Windows only + +### fundamental datatypes + +_ctypes_ provides [primitive C compatiable data types](https://docs.python.org/3/library/ctypes.html#fundamental-data-types). +Like `c_bool`, `c_byte`, `c_int`, `c_long` and so on. + +> `c_int` represents the _C_ `signed int` datatype. On platforms where +> `sizeof(int) == sizeof(long)` it is an alias to `c_long`. + +| c datatypes | ctypes | +| ------------------- | ----------------------- | +| bool | c_bool | +| byte_t | c_ubyte | +| char | c_char | +| float32_t | c_float | +| float64_t | c_double | +| int32_t | c_int32 | +| int64_t | c_int64 | +| intptr_t | c_void_p | +| size_t | c_size_t | +| uint8_t | c_uint8 | +| uint32_t | c_uint32 | +| void | None | +| wasm_byte_t | c_ubyte | +| wasm_externkind_t | c_uint8 | +| wasm_memory_pages_t | c_uint32 | +| wasm_mutability_t | c_bool | +| wasm_table_size_t | c_uint32 | +| wasm_valkind_t | c_uint8 | +| wasm_data_type\* | POINTER(wasm_data_type) | + +- `c_void_p` only represents `void *` only +- `None` represents `void` in function parameter lists and return lists + +### structured datatypes + +Create a corresponding concept for every native structured data type includes +`enum`, `struct` and `union`, in the python world. + +#### Enum types + +For example, if there is a `enum wams_mutability_enum` in native. + +```c +typedef uint8_t wams_mutability_t; +enum wams_mutability_enum { + WASM_CONST, + WASM_VAR +}; +``` + +Use `ctypes.int`(or any integer types in ctypes) to represents its value directly. + +```python +# represents enum wams_mutability_enum +wasm_mutability_t = c_uint8 + +WASM_CONST = 0 +WASM_VAR = 1 +``` + +> C standard only requires "Each enumerated type shall be compatible with char, +> a signed integer type, or an unsigned integer type. The choice of the integer +> type is implementation-defined, but shall be capable of representing the +> values of all the members of the enumeration. + +#### Struct types + +If there is a `struct wasm_byte_vec_t` in native(in C). + +```c +typedef struct wasm_byte_vec_t { + size_t size; + wasm_byte_t *data; + size_t num_elems; + size_t size_of_elem; +} wasm_byte_vec_t; +``` + +Use `ctypes.Structure` to create its corresponding data type in python. + +```python +class wasm_byte_vec_t(ctypes.Structure): + _fileds_ = [ + ("size", ctypes.c_size_t), + ("data", ctypes.POINTER(c_ubyte)), + ("num_elems", ctypes.c_size_t), + ("size_of_elem", ctypes.c_size_t), + ] +``` + +a list of `Structures` + +| name | +| ----------------- | +| wasm_engine_t | +| wasm_store_t | +| wasm_limits_t | +| wasm_valtype_t | +| wasm_functype_t | +| wasm_globaltype_t | +| wasm_tabletype_t | +| wasm_memorytype_t | +| wasm_externtype_t | +| wasm_importtype_t | +| wasm_exporttype_t | +| wasm_ref_t | +| wasm_ref_t | +| wasm_frame_t | +| wasm_trap_t | +| wasm_foreign_t | +| WASMModuleCommon | +| WASMModuleCommon | +| wasm_func_t | +| wasm_global_t | +| wasm_table_t | +| wasm_memory_t | +| wasm_extern_t | +| wasm_instance_t | + +not supported `struct` + +- wasm_config_t + +If there is an anonymous `union` in native. + +```c +typedef struct wasm_val_t { + wasm_valkind_t kind; + union { + int32_t i32; + int64_t i64; + float32_t f32; + float64_t f64; + } of; +} wasm_val_t; +``` + +Use `ctypes.Union` to create its corresponding data type in python. + +```python +class _OF(ctypes.Union): + _fields_ = [ + ("i32", ctypes.c_int32), + ("i64", ctypes.c_int64), + ("f32", ctypes.c_float), + ("f64", ctypes.c_double), + ] + +class wasm_val_t(ctypes.Structure): + _anonymous_ = ("of",) + _fields_ = [ + ("kind", ctypes.c_uint8) + ("of", _OF) + ] +``` + +### wrappers of functions + +Foreign functions (C functions) can be accessed as attributes of loaded shared +libraries or an instance of function prototypes. Callback functions(python +functions) can only be accessed by instantiating function prototypes. + +For example, + +```c +void wasm_name_new(wasm_name_t* out, size_t len, wasm_byte_t [] data); +``` + +Assume there are: + +- `class wasm_name_t` of python represents `wasm_name_t` of C +- `libiwasm` represents loaded _libiwasm.so_ + +If to access a c function like an attribute, + +```python +def wasm_name_new(out, len, data): + _wasm_name_new = libiwasm.wasm_name_new + _wasm_name_new.argtypes = (ctypes.POINTER(wasm_name_t), ctypes.c_size_t, ctypes.POINTER(ctypes.c_ubyte)) + _wasm_name_new.restype = None + return _wasm_name_new(out, len, data) +``` + +Or to instantiate a function prototype, + +```python +def wasm_name_new(out, len, data): + return ctypes.CFUNCTYPE(None, (ctypes.POINTER(wasm_name_t), ctypes.c_size_t, ctypes.POINTER(ctypes.c_ubyte)))( + ("wasm_name_new", libiwasm), out, len, data) +``` + +Now it is able to create a `wasm_name_t` with `wasm_name_new()` in python. + +Sometimes, need to create a python function as a callback of c. + +```c +wasm_trap_t* (*wasm_func_callback_t)(wasm_val_vec_t* args, wasm_val_vec_t *results); +``` + +Use `cyptes.CFUNCTYPE` to create a _pointer of function_ + +```python +def hello(args, results): + print("hello from a callback") + +wasm_func_callback_t = ctypes.CFUNCTYPE(c_size_t, POINTER(wasm_val_vec_t), POINTER(wasm_val_vec_t)) +hello_callback = wasm_func_callback_t(hello) +``` + +or with a decorator + +```python +def wasm_func_cb_decl(func): + return @ctypes.CFUNCTYPE(ctypes.POINTER(wasm_trap_t), (ctypes.POINTER(wasm_val_vec_t), ctypes.POINTER(wasm_val_vec_t)))(func) + +@wasm_func_cb_decl +def hello(args, results): + print("hello from a callback") +``` + +### programming tips + +#### `struct` and `ctypes.Structure` + +There are two kinds of `cytes.Structure` in `binding.py`. + +- has `__field__` definition. like `class wasm_byte_vec_t(Structure)` +- doesn't have `__field__` definition. like `class wasm_config_t(Structure)` + +Since, `ctypes` will create its C world _mirror_ variable according to `__field__` +information, `wasm_config_t()` will only create a python instance without binding +to any C variable. `wasm_byte_vec_t()` will return a python instance with an internal +C variable. + +That is why `pointer(wasm_config_t())` is a NULL pointer which can not be dereferenced. + +#### deal with pointers + +`byref()` and `pointer()` are two functions can return a pointer. + +```python +x = ctypes.c_int(2) + +# use pointer() to creates a new pointer instance which would later be used in Python +x_ptr = ctypes.pointer(x) +... +struct_use_pointer = Mystruct() +struct_use_pointer.ptr = x_ptr + +# use byref() pass a pointer to an object to a foreign function call +func(ctypes.byref(x)) +``` + +The main difference is that `pointer()` does a lot more work since it +constructs a real pointer object. It is faster to use `byref(`) if don't need +the pointer object in Python itself(e.g. only use it as an argument to pass +to a function). + +There is no doubt that `wasm_xxx_new()` which return type is `ctypes.POINTER` +can return a pointer. Plus, the return value of `wasm_xxx_t()` can also be +used as a pointer without casting by `byref` or `pointer`. + +#### array + +In [ctypes document](https://docs.python.org/3/library/ctypes.html#arrays), +it states that "The recommended way to create array types is by multiplying a +data type with a positive integer". So _multiplying a data type_ should be a +better way to create arrays + +```python +from ctypes import * + +class POINT(Structure): + _fields_ = ("x", c_int), ("y", c_int) + +# multiplying a data type +# type(TenPointsArrayType) is +TenPointsArrayType = POINT * 10 + +# Instances are created in the usual way, by calling the class: +arr = TenPointsArrayType() +arr[0] = POINT(3,2) +for pt in arr: + print(pt.x, pt.y) +``` + +On both sides, it is OK to assign an array to a pointer. + +```c +char buf[128] = {0}; +char *ptr = buf; +``` + +```python +binary = wasm_byte_vec_t() +binary.data = (ctypes.c_ubyte * len(wasm)).from_buffer_copy(wasm) +``` + +#### exceptions and traps + +Interfaces of _wasm-c-api_ have their return values to represent failures. +The python binding should just keep and transfer them to callers instead of +raising any additional exception. + +The python binding should raise exceptions when the python partial is failed. + +#### readonly buffer + +```python +with open("hello.wasm", "rb") as f: + wasm = f.read() + binary = wasm_byte_vec_t() + wasm_byte_vec_new_uninitialized(byref(binary), len(wasm)) + # create a ctypes instance (byte[] in c) and copy the content + # from wasm(bytearray in python) + binary.data = (ctypes.c_ubyte * len(wasm)).from_buffer_copy(wasm) +``` + +in the above example, `wasm` is a python-created readable buffer. It is not +writable and needs to be copied into a ctype array. + +#### variable arguments + +A function with _variable arugments_ makes it hard to specify the required +argument types for the function prototype. It leaves us one way to call it +directly without any arguments type checking. + +```python +libc.printf(b"Hello, an int %d, a float %f, a string %s\n", c_int(1), c_doulbe(3.14), "World!") +``` + +#### Use `c_bool` to represent `wasm_mutability_t ` + +- `True` for `WASM_CONST` +- `False` for `WASM_VALUE` + +#### customize class builtins + +- `__eq__` for comparation. +- `__repr__` for printing. + +### bindgen.py + +`bindge.py` is a tool to create WAMR python binding automatically. `binding.py` +is generated. We should avoid modification on it. Additional helpers should go +to `ffi.py`. + +`bindgen.py` uses _pycparser_. Visit the AST of `core/iwasm/include/wasm_c_api.h` +created by _gcc_ and generate necessary wrappers. + +```python +from pycparser import c_ast + +class Visitor(c_ast.NodeVisitor): + def visit_Struct(self, node): + pass + + def visit_Union(self, node): + pass + + def visit_TypeDef(self, node): + pass + + def visit_FuncDecl(self, node): + pass + +ast = parse_file(...) +v = Visitor() +v.visit(ast) +``` + +Before running _bindgen.py_, the shared library _libiwasm.so_ should be generated. + +```bash +$ cd /path/to/wamr/repo +$ # if it is in linux +$ pushd product-mini/platforms/linux/ +$ cmake -S . -B build .. +$ cmake --build build --target iwasm +$ popd +$ cd binding/python +$ python utils/bindgen.py +``` + +`wasm_frame_xxx` and `wasm_trap_xxx` only work well when enabling `WAMR_BUILD_DUMP_CALL_STACK`. + +```bash +$ cmake -S . -B build -DWAMR_BUILD_DUMP_CALL_STACK=1 .. +``` + +## OOP wrappers + +Based on the above general rules, there will be corresponding python +APIs for every C API in `wasm_c_api.h` with same name. Users can do procedural +programming with those. + +In next phase, we will create OOP APIs. Almost follow the +[C++ version of wasm_c_api](https://github.com/WebAssembly/wasm-c-api/blob/master/include/wasm.hh) + +## A big list + +| WASM Concept | Procedural APIs | OOP APIs | OOP APIs methods | +| ------------ | ------------------------------ | ---------- | ---------------- | +| XXX_vec | wasm_xxx_vec_new | | list | +| | wasm_xxx_vec_new_uninitialized | | | +| | wasm_xxx_vec_new_empty | | | +| | wasm_xxx_vec_copy | | | +| | wasm_xxx_vec_delete | | | +| valtype | wasm_valtype_new | valtype | \_\_init\_\_ | +| | wasm_valtype_delete | | \_\_del\_\_ | +| | wasm_valtype_kind | | \_\_eq\_\_ | +| | wasm_valtype_copy | | | +| | _vector methods_ | | | +| functype | wasm_functype_new | functype | | +| | wasm_functype_delete | | | +| | wasm_functype_params | | | +| | wasm_functype_results | | | +| | wasm_functype_copy | | | +| | _vector methods_ | | | +| globaltype | wasm_globaltype_new | globaltype | \_\_init\_\_ | +| | wasm_globaltype_delete | | \_\_del\_\_ | +| | wasm_globaltype_content | | \_\_eq\_\_ | +| | wasm_globaltype_mutability | | | +| | wasm_globaltype_copy | | | +| | _vector methods_ | | | +| tabletype | wasm_tabletype_new | tabletype | \_\_init\_\_ | +| | wasm_tabletype_delete | | \_\_del\_\_ | +| | wasm_tabletype_element | | \_\_eq\_\_ | +| | wasm_tabletype_limits | | | +| | wasm_tabletype_copy | | | +| | _vector methods_ | | | +| memorytype | wasm_memorytype_new | memorytype | \_\_init\_\_ | +| | wasm_memorytype_delete | | \_\_del\_\_ | +| | wasm_memorytype_limits | | \_\_eq\_\_ | +| | wasm_memorytype_copy | | | +| | _vector methods_ | | | +| externtype | wasm_externtype_as_XXX | externtype | | +| | wasm_XXX_as_externtype | | | +| | wasm_externtype_copy | | | +| | wasm_externtype_delete | | | +| | wasm_externtype_kind | | | +| | _vector methods_ | | | +| importtype | wasm_importtype_new | importtype | | +| | wasm_importtype_delete | | | +| | wasm_importtype_module | | | +| | wasm_importtype_name | | | +| | wasm_importtype_type | | | +| | wasm_importtype_copy | | | +| | _vector methods_ | | | +| exportype | wasm_exporttype_new | exporttype | | +| | wasm_exporttype_delete | | | +| | wasm_exporttype_name | | | +| | wasm_exporttype_type | | | +| | wasm_exporttype_copy | | | +| | _vector methods_ | | | +| val | wasm_val_delete | val | | +| | wasm_val_copy | | | +| | _vector methods_ | | | +| frame | wasm_frame_delete | frame | | +| | wasm_frame_instance | | | +| | wasm_frame_func_index | | | +| | wasm_frame_func_offset | | | +| | wasm_frame_module_offset | | | +| | wasm_frame_copy | | | +| | _vector methods_ | | | +| trap | wasm_trap_new | trap | | +| | wasm_trap_delete | | | +| | wasm_trap_message | | | +| | wasm_trap_origin | | | +| | wasm_trap_trace | | | +| | _vector methods_ | | | +| foreign | wasm_foreign_new | foreign | | +| | wasm_foreign_delete | | | +| | _vector methods_ | | | +| engine | wasm_engine_new | engine | | +| | wasm_engine_new_with_args\* | | | +| | wasm_engine_new_with_config | | | +| | wasm_engine_delete | | | +| store | wasm_store_new | store | | +| | wasm_store_delete | | | +| | _vector methods_ | | | +| module | wasm_module_new | module | | +| | wasm_module_delete | | | +| | wasm_module_validate | | | +| | wasm_module_imports | | | +| | wasm_module_exports | | | +| instance | wasm_instance_new | instance | | +| | wasm_instance_delete | | | +| | wasm_instance_new_with_args\* | | | +| | wasm_instance_exports | | | +| | _vector methods_ | | | +| func | wasm_func_new | func | | +| | wasm_func_new_with_env | | | +| | wasm_func_delete | | | +| | wasm_func_type | | | +| | wasm_func_call | | | +| | wasm_func_param_arity | | | +| | wasm_func_result_arity | | | +| | _vector methods_ | | | +| global | wasm_global_new | global | | +| | wasm_global_delete | | | +| | wasm_global_type | | | +| | wasm_global_get | | | +| | wasm_global_set | | | +| | _vector methods_ | | | +| table | wasm_table_new | table | | +| | wasm_table_delete | | | +| | wasm_table_type | | | +| | wasm_table_get | | | +| | wasm_table_set | | | +| | wasm_table_size | | | +| | _vector methods_ | | | +| memory | wasm_memory_new | memory | | +| | wasm_memory_delete | | | +| | wasm_memory_type | | | +| | wasm_memory_data | | | +| | wasm_memory_data_size | | | +| | wasm_memory_size | | | +| | _vector methods_ | | | +| extern | wasm_extern_delete | extern | | +| | wasm_extern_as_XXX | | | +| | wasm_XXX_as_extern | | | +| | wasm_extern_kind | | | +| | wasm_extern_type | | | +| | _vector methods_ | | | + +not supported _functions_ + +- wasm_config_XXX +- wasm_module_deserialize +- wasm_module_serialize +- wasm_ref_XXX +- wasm_XXX_as_ref +- wasm_XXX_as_ref_const +- wasm_XXX_copy +- wasm_XXX_get_host_info +- wasm_XXX_set_host_info + +## test + +there will be two kinds of tests in the project + +- unit test. located in `./tests`. driven by _unittest_. run by + `$ python -m unittest` or `$ make test`. +- integration test. located in `./samples`. + +The whole project is under test-driven development. Every wrapper function will +have two kinds of test cases. The first kind is a positive case. It checks a +wrapper function with expected and safe arguments combinations. Its goal is the +function should work well with expected inputs. Another kind is a negative +case. It feeds unexpected arguments combinations into a wrapper function. Arguments +should include but not be limited to `None`. It ensures that the function will +gracefully handle invalid input or unexpected behaviors. + +## distribution + +### package + +Create a python package named `wamr`. Users should import it after installation +just like any other python module. + +```python +from wamr import * +``` + +### PyPI + +Refer to [tutorial provided by PyPA](https://packaging.python.org/en/latest/tutorials/packaging-projects/). +Steps to publish WAMR Python library: + +1. Creating `pyproject.toml` tells build tools (like pip and build) what is + required to build a project. An example .toml file uses _setuptools_ + + ```toml + [build-system] + requires = [ + "setuptools>=42", + "wheel" + ] + build-backend = "setuptools.build_meta" + ``` + +2. Configuring metadata tells build tools about a package (such as the name + and the version), as well as which code files to include + + - Static metadata (`setup.cfg`): guaranteed to be the same every time. + It is simpler, easier to read, and avoids many common errors, like + encoding errors. + + - Dynamic metadata (`setup.py`): possibly non-deterministic. Any items that + are dynamic or determined at install-time, as well as extension modules + or extensions to setuptools, need to go into setup.py. + + **_Static metadata should be preferred_**. Dynamic metadata should be used + only as an escape hatch when necessary. setup.py used to be + required, but can be omitted with newer versions of setuptools and pip. + +3. Including other files in the distribution + + - For [source distribution](https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist): + + It's usually generated using `python setup.py sdist`, providing metadata + and the essential source files needed for installing by a tool like pip, + or for generating a Built Distribution. + + It includes our Python modules, pyproject.toml, metadata, README.md, + LICENSE. If you want to control what goes in this explicitly, + see [Including files in source distributions with MANIFEST.in](https://packaging.python.org/en/latest/guides/using-manifest-in/#using-manifest-in). + + - For [final built distribution](https://packaging.python.org/en/latest/glossary/#term-Built-Distribution) + + A Distribution format containing files and metadata that only need to be + moved to the correct location on the target system, to be installed. + e.g. `Wheel` + + It will have the Python files in the discovered or listed Python packages. + If you want to control what goes here, such as to add data files, + see [Including Data Files](https://setuptools.pypa.io/en/latest/userguide/datafiles.html) from the [setuptools docs](https://setuptools.pypa.io/en/latest/index.html). + +4. Generating distribution archives. These are archives that are uploaded to + the Python Package Index and can be installed by pip. + + example using `setuptools` + + ```shell + python3 -m pip install --upgrade build + python3 -m build + ``` + + generated files: + + ```shell + dist/ + WAMR-package-0.0.1-py3-none-any.whl + WAMR-package-0.0.1.tar.gz + ``` + + The `tar.gz` file is a _source archive_ whereas the `.whl file` is a + _built distribution_. Newer pip versions preferentially install built + distributions but will fall back to source archives if needed. You should + always upload a source archive and provide built archives for compatibility + reasons. + +5. Uploading the distribution archives + + - Register an account on https://pypi.org. + - To securely upload your project, you’ll need a + [PyPI API token](https://pypi.org/help/#apitoken). It can create at + [here](https://pypi.org/manage/account/#api-tokens), and the “Scope” + the setting needs to be “Entire account”. + - After registration, now twine can be used to upload the distribution packages. + + ```shell + # install twine + python3 -m pip install --upgrade twine + # --repository is https://pypi.org/ by default. + # You will be prompted for a username and password. For the username, use __token__. For the password, use the token value, including the pypi- prefix. + twine upload dist/* + ``` + +after all, the python binding will be installed with + +```shell +$ pip install wamr +``` + +PS: A example lifecycle of a python package +![python-package-lifecycle](images/python_package_life_cycle.png) + +## CI + +There are several parts: + +- code format check. +- test. include running all unit test cases and examples. +- publish built distribution. diff --git a/language-bindings/python/docs/images/python_package_life_cycle.png b/language-bindings/python/docs/images/python_package_life_cycle.png new file mode 100644 index 0000000000000000000000000000000000000000..90856e1816c33c8f177ab59b870059522d28daa0 GIT binary patch literal 76811 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Ų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 literal 0 HcmV?d00001 diff --git a/language-bindings/python/docs/setup_dev_env.md b/language-bindings/python/docs/setup_dev_env.md new file mode 100644 index 00000000..6612748f --- /dev/null +++ b/language-bindings/python/docs/setup_dev_env.md @@ -0,0 +1,12 @@ +Use a python virtual environment tool to create an environment for development. All necessary packages are in _../requirements.txt_. + +python code formatter is provided by _black_. + +python code linter is provided by _pylint_ and default configuration. + +Unit tests are driven by _unittest_. + +```bash +$ python -m unittest -v tests/test_basics.py +$ python -m unittest -v tests/test_advanced.py +``` diff --git a/language-bindings/python/pyproject.toml b/language-bindings/python/pyproject.toml new file mode 100644 index 00000000..b0f07653 --- /dev/null +++ b/language-bindings/python/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=42"] +build-backend = "setuptools.build_meta" diff --git a/language-bindings/python/requirements.txt b/language-bindings/python/requirements.txt new file mode 100644 index 00000000..7bb68ba6 --- /dev/null +++ b/language-bindings/python/requirements.txt @@ -0,0 +1,5 @@ +black +nose +pycparser +pylint + diff --git a/language-bindings/python/samples/hello.wat b/language-bindings/python/samples/hello.wat new file mode 100644 index 00000000..1c56c558 --- /dev/null +++ b/language-bindings/python/samples/hello.wat @@ -0,0 +1,4 @@ +(module + (func $hello (import "" "hello")) + (func (export "run") (call $hello)) +) diff --git a/language-bindings/python/samples/hello_oop.py b/language-bindings/python/samples/hello_oop.py new file mode 100644 index 00000000..666f63cd --- /dev/null +++ b/language-bindings/python/samples/hello_oop.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +import ctypes +from wamr import * + + +def hello_callback(): + print("Calling back...") + print("> Hello World!") + + +def main(): + print("Initializing...") + engine = Engine() + store = Store(engine) + + print("Loading binary...") + print("Compiling module...") + module = Module.from_file(engine, "./hello.wasm") + + print("Creating callback...") + hello = Func(store, FuncType([], []), hello_callback) + + print("Instantiating module...") + instance = Instance(store, module, [hello]) + + print("Extracting export...") + run = instance.exports(store)["run"] + + print("Calling export...") + run(store) + + print("Shutting down...") + print("Done.") + + +if __name__ == "__main__": + main() diff --git a/language-bindings/python/samples/hello_procedural.py b/language-bindings/python/samples/hello_procedural.py new file mode 100644 index 00000000..ed3002d5 --- /dev/null +++ b/language-bindings/python/samples/hello_procedural.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +import ctypes +import wamr.ffi as ffi + +WAMS_BINARY_CONTENT = ( + b"\x00asm\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01`\x00\x00\x02\x8a\x80" + b"\x80\x80\x00\x01\x00\x05hello\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00" + b"\x07\x87\x80\x80\x80\x00\x01\x03run\x00\x01\n\x8a\x80\x80\x80\x00\x01" + b"\x84\x80\x80\x80\x00\x00\x10\x00\x0b" +) + + +@ffi.wasm_func_cb_decl +def hello_callback(args, results): + print("Calling back...") + print("> Hello World!") + + +def main(): + print("Initializing...") + engine = ffi.wasm_engine_new() + store = ffi.wasm_store_new(engine) + + print("Loading binary...") + + # for convenience, use binary content instead of open file + # with open("./hello.wasm", "rb") as f: + # wasm = f.read() + wasm = WAMS_BINARY_CONTENT + binary = ffi.wasm_byte_vec_t() + ffi.wasm_byte_vec_new_uninitialized(binary, len(wasm)) + # underlying buffer is not writable + binary.data = (ctypes.c_ubyte * len(wasm)).from_buffer_copy(wasm) + + print("Compiling module...") + module = ffi.wasm_module_new(store, binary) + if not module: + raise RuntimeError("Compiling module failed") + + binary.data = None + ffi.wasm_byte_vec_delete(binary) + + print("Creating callback...") + hello_type = ffi.wasm_functype_new_0_0() + hello_func = ffi.wasm_func_new( + store, + hello_type, + hello_callback, + ) + + ffi.wasm_functype_delete(hello_type) + + print("Instantiating module...") + + imports = ffi.wasm_extern_vec_t() + ffi.wasm_extern_vec_new((imports), 1, ffi.wasm_func_as_extern(hello_func)) + instance = ffi.wasm_instance_new(store, module, imports, None) + + ffi.wasm_func_delete(hello_func) + + print("Extracting export...") + exports = ffi.wasm_extern_vec_t() + ffi.wasm_instance_exports(instance, exports) + + run_func = ffi.wasm_extern_as_func(exports.data[0]) + if not run_func: + raise RuntimeError("can not extract exported function") + + ffi.wasm_instance_delete(instance) + ffi.wasm_module_delete(module) + + print("Calling export...") + args = ffi.wasm_val_vec_t() + results = ffi.wasm_val_vec_t() + + ffi.wasm_val_vec_new_empty(args) + ffi.wasm_val_vec_new_empty(results) + ffi.wasm_func_call(run_func, args, results) + + print("Shutting down...") + ffi.wasm_store_delete(store) + ffi.wasm_engine_delete(engine) + + print("Done.") + + +if __name__ == "__main__": + main() diff --git a/language-bindings/python/setup.py b/language-bindings/python/setup.py new file mode 100755 index 00000000..c7868187 --- /dev/null +++ b/language-bindings/python/setup.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +# pylint: disable=missing-module-docstring + +from setuptools import setup, find_packages + + +with open("README.md") as f: + readme = f.read() + +with open("LICENSE") as f: + license = f.read() + +setup( + name="wamr-python", + version="0.1.0", + description="A WebAssembly runtime powered by WAMR", + long_description=readme, + author="The WAMR Project Developers", + author_email="hello@bytecodealliance.org", + url="https://github.com/bytecodealliance/wamr-python", + license=license, + packages=["wamr"], +) diff --git a/language-bindings/python/tests/__init__.py b/language-bindings/python/tests/__init__.py new file mode 100644 index 00000000..fd913c63 --- /dev/null +++ b/language-bindings/python/tests/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +__all__ = ["test_basic", "test_advanced"] diff --git a/language-bindings/python/tests/context.py b/language-bindings/python/tests/context.py new file mode 100644 index 00000000..15c30087 --- /dev/null +++ b/language-bindings/python/tests/context.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +import sys +import os + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +import wamr diff --git a/language-bindings/python/tests/test_advanced.py b/language-bindings/python/tests/test_advanced.py new file mode 100644 index 00000000..ad074f2b --- /dev/null +++ b/language-bindings/python/tests/test_advanced.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +# pylint: disable=missing-module-docstring + +import ctypes as c +import math +import unittest + +import wamr.ffi as ffi + + +# It is a module likes: +# (module +# (import "mod" "g0" (global i32)) +# (import "mod" "f0" (func (param f32) (result f64))) +# +# (func (export "f1") (param i32 i64)) +# (global (export "g1") (mut f32) (f32.const 3.14)) +# (memory (export "m1") 1 2) +# (table (export "t1") 1 funcref) +# +# (func (export "f2") (unreachable)) +# ) +MODULE_BINARY = ( + b"\x00asm\x01\x00\x00\x00\x01\x0e\x03`\x01}\x01|`\x02\x7f~\x00`\x00" + b"\x00\x02\x14\x02\x03mod\x02g0\x03\x7f\x00\x03mod\x02f0\x00\x00\x03\x03" + b"\x02\x01\x02\x04\x04\x01p\x00\x01\x05\x04\x01\x01\x01\x02\x06\t\x01}\x01C" + b"\xc3\xf5H@\x0b\x07\x1a\x05\x02f1\x00\x01\x02g1\x03\x01\x02m1\x02\x00\x02t1" + b"\x01\x00\x02f2\x00\x02\n\x08\x02\x02\x00\x0b\x03\x00\x00\x0b" +) + +# False -> True when testing with a library enabling WAMR_BUILD_DUMP_CALL_STACK flag +TEST_WITH_WAMR_BUILD_DUMP_CALL_STACK = False + + +@ffi.wasm_func_cb_decl +def callback(args, results): + args = ffi.dereference(args) + results = ffi.dereference(results) + + arg_v = args.data[0] + + result_v = ffi.wasm_f64_val(arg_v.of.f32 * 2.0) + ffi.wasm_val_copy(results.data[0], result_v) + results.num_elems = 1 + + print(f"\nIn callback: {arg_v} --> {result_v}\n") + + +@ffi.wasm_func_with_env_cb_decl +def callback_with_env(env, args, results): + # pylint: disable=unused-argument + print("summer") + + +class AdvancedTestSuite(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("Initializing...") + cls._wasm_engine = ffi.wasm_engine_new() + cls._wasm_store = ffi.wasm_store_new(cls._wasm_engine) + + def assertIsNullPointer(self, pointer): + # pylint: disable=invalid-name + if not ffi.is_null_pointer(pointer): + self.fail("not a non-null pointer") + + def assertIsNotNullPointer(self, pointer): + # pylint: disable=invalid-name + if ffi.is_null_pointer(pointer): + self.fail("not a non-null pointer") + + def load_binary(self, binary_string): + print("Load binary...") + binary = ffi.load_module_file(binary_string) + binary = c.pointer(binary) + self.assertIsNotNullPointer(binary) + return binary + + def compile(self, binary): + print("Compile...") + module = ffi.wasm_module_new(self._wasm_store, binary) + self.assertIsNotNullPointer(module) + return module + + def prepare_imports_local(self): + print("Prepare imports...") + func_type = ffi.wasm_functype_new_1_1( + ffi.wasm_valtype_new(ffi.WASM_F32), + ffi.wasm_valtype_new(ffi.WASM_F64), + ) + func = ffi.wasm_func_new(self._wasm_store, func_type, callback) + self.assertIsNotNullPointer(func) + ffi.wasm_functype_delete(func_type) + + glbl_type = ffi.wasm_globaltype_new(ffi.wasm_valtype_new(ffi.WASM_I32), True) + init = ffi.wasm_i32_val(1024) + glbl = ffi.wasm_global_new(self._wasm_store, glbl_type, init) + self.assertIsNotNullPointer(glbl) + ffi.wasm_globaltype_delete(glbl_type) + + imports = ffi.wasm_extern_vec_t() + data = ffi.list_to_carray( + c.POINTER(ffi.wasm_extern_t), + ffi.wasm_func_as_extern(func), + ffi.wasm_global_as_extern(glbl), + ) + ffi.wasm_extern_vec_new(imports, 2, data) + imports = c.pointer(imports) + self.assertIsNotNullPointer(imports) + return imports + + def instantiate(self, module, imports): + print("Instantiate module...") + instance = ffi.wasm_instance_new( + self._wasm_store, module, imports, ffi.create_null_pointer(ffi.wasm_trap_t) + ) + self.assertIsNotNone(instance) + self.assertIsNotNullPointer(instance) + return instance + + def extract_exports(self, instance): + print("Extracting exports...") + exports = ffi.wasm_extern_vec_t() + ffi.wasm_instance_exports(instance, exports) + exports = c.pointer(exports) + self.assertIsNotNullPointer(exports) + return exports + + def setUp(self): + binary = self.load_binary(MODULE_BINARY) + self.module = self.compile(binary) + self.imports = self.prepare_imports_local() + self.instance = self.instantiate(self.module, self.imports) + self.exports = self.extract_exports(self.instance) + + ffi.wasm_byte_vec_delete(binary) + + def tearDown(self): + if self.imports: + ffi.wasm_extern_vec_delete(self.imports) + + if self.exports: + ffi.wasm_extern_vec_delete(self.exports) + + ffi.wasm_instance_delete(self.instance) + ffi.wasm_module_delete(self.module) + + def test_wasm_func_call_wasm(self): + export_list = ffi.wasm_vec_to_list(self.exports) + print(export_list) + + func = ffi.wasm_extern_as_func(export_list[0]) + self.assertIsNotNullPointer(func) + + # make a call + params = ffi.wasm_val_vec_t() + data = ffi.list_to_carray( + ffi.wasm_val_t, + ffi.wasm_i32_val(1024), + ffi.wasm_i64_val(1024 * 1024), + ) + ffi.wasm_val_vec_new(params, 2, data) + + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(results) + + ffi.wasm_func_call(func, params, results) + + def test_wasm_func_call_native(self): + import_list = ffi.wasm_vec_to_list(self.imports) + + func = ffi.wasm_extern_as_func(import_list[0]) + self.assertIsNotNullPointer(func) + + params = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new( + params, 1, ffi.list_to_carray(ffi.wasm_val_t, ffi.wasm_f32_val(3.14)) + ) + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_uninitialized(results, 1) + ffi.wasm_func_call(func, params, results) + self.assertEqual(params.data[0].of.f32 * 2, results.data[0].of.f64) + + def test_wasm_func_call_wrong_params(self): + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[0]) + # make a call + params = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(params) + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(results) + trap = ffi.wasm_func_call(func, params, results) + + self.assertIsNotNullPointer(trap) + + def test_wasm_func_call_unlinked(self): + ft = ffi.wasm_functype_new_0_0() + func = ffi.wasm_func_new(self._wasm_store, ft, callback) + params = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(params) + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(results) + trap = ffi.wasm_func_call(func, params, results) + ffi.wasm_func_delete(func) + + def test_wasm_global_get_wasm(self): + export_list = ffi.wasm_vec_to_list(self.exports) + glb = ffi.wasm_extern_as_global(export_list[1]) + self.assertIsNotNullPointer(glb) + + # access the global + val = ffi.wasm_val_t() + ffi.wasm_global_get(glb, val) + self.assertAlmostEqual(val.of.f32, 3.14, places=3) + + def test_wasm_global_get_native(self): + import_list = ffi.wasm_vec_to_list(self.imports) + + glb = ffi.wasm_extern_as_global(import_list[1]) + self.assertIsNotNullPointer(glb) + + val = ffi.wasm_val_t() + ffi.wasm_global_get(glb, val) + self.assertEqual(val.of.i32, 1024) + + def test_wasm_global_get_unlinked(self): + gt = ffi.wasm_globaltype_new(ffi.wasm_valtype_new(ffi.WASM_I32), True) + init = ffi.wasm_i32_val(32) + glbl = ffi.wasm_global_new(self._wasm_store, gt, init) + val_ret = ffi.wasm_f32_val(3.14) + ffi.wasm_global_get(glbl, val_ret) + ffi.wasm_global_delete(glbl) + + # val_ret wasn't touched, keep the original value + self.assertAlmostEqual(val_ret.of.f32, 3.14, 3) + + def test_wasm_global_get_null_val(self): + export_list = ffi.wasm_vec_to_list(self.exports) + glb = ffi.wasm_extern_as_global(export_list[1]) + ffi.wasm_global_get(glb, ffi.create_null_pointer(ffi.wasm_val_t)) + + def test_wasm_global_get_null_global(self): + val = ffi.wasm_val_t() + ffi.wasm_global_get(ffi.create_null_pointer(ffi.wasm_global_t), val) + + def test_wasm_global_set_wasm(self): + export_list = ffi.wasm_vec_to_list(self.exports) + glb = ffi.wasm_extern_as_global(export_list[1]) + self.assertIsNotNullPointer(glb) + + # access the global + new_val = ffi.wasm_f32_val(math.e) + ffi.wasm_global_set(glb, new_val) + + val = ffi.wasm_val_t() + ffi.wasm_global_get(glb, val) + self.assertNotEqual(val.of.f32, 3.14) + + def test_wasm_global_set_native(self): + import_list = ffi.wasm_vec_to_list(self.imports) + + glb = ffi.wasm_extern_as_global(import_list[1]) + self.assertIsNotNullPointer(glb) + + new_val = ffi.wasm_i32_val(2048) + ffi.wasm_global_set(glb, new_val) + + val = ffi.wasm_val_t() + ffi.wasm_global_get(glb, val) + self.assertEqual(val, new_val) + + def test_wasm_global_set_unlinked(self): + gt = ffi.wasm_globaltype_new(ffi.wasm_valtype_new(ffi.WASM_I32), True) + init = ffi.wasm_i32_val(32) + glbl = ffi.wasm_global_new(self._wasm_store, gt, init) + val_ret = ffi.wasm_f32_val(3.14) + ffi.wasm_global_set(glbl, val_ret) + ffi.wasm_global_delete(glbl) + + def test_wasm_global_set_null_v(self): + export_list = ffi.wasm_vec_to_list(self.exports) + glb = ffi.wasm_extern_as_global(export_list[1]) + # access the global + ffi.wasm_global_set(glb, ffi.create_null_pointer(ffi.wasm_val_t)) + + def test_wasm_global_set_null_global(self): + # access the global + new_val = ffi.wasm_f32_val(math.e) + ffi.wasm_global_set(ffi.create_null_pointer(ffi.wasm_global_t), new_val) + + def test_wasm_table_size(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + self.assertIsNotNullPointer(tbl) + + tbl_sz = ffi.wasm_table_size(tbl) + self.assertEqual(tbl_sz, 1) + + def test_wasm_table_size_unlink(self): + vt = ffi.wasm_valtype_new(ffi.WASM_FUNCREF) + limits = ffi.wasm_limits_new(10, 15) + tt = ffi.wasm_tabletype_new(vt, limits) + tbl = ffi.wasm_table_new( + self._wasm_store, tt, ffi.create_null_pointer(ffi.wasm_ref_t) + ) + tbl_sz = ffi.wasm_table_size(tbl) + ffi.wasm_table_delete(tbl) + + def test_wasm_table_size_null_table(self): + ffi.wasm_table_size(ffi.create_null_pointer(ffi.wasm_table_t)) + + def test_wasm_table_get(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + self.assertIsNotNullPointer(tbl) + + ref = ffi.wasm_table_get(tbl, 0) + self.assertIsNullPointer(ref) + + ref = ffi.wasm_table_get(tbl, 4096) + self.assertIsNullPointer(ref) + + def test_wasm_table_get_unlinked(self): + vt = ffi.wasm_valtype_new(ffi.WASM_FUNCREF) + limits = ffi.wasm_limits_new(10, 15) + tt = ffi.wasm_tabletype_new(vt, limits) + tbl = ffi.wasm_table_new( + self._wasm_store, tt, ffi.create_null_pointer(ffi.wasm_ref_t) + ) + ffi.wasm_table_get(tbl, 0) + ffi.wasm_table_delete(tbl) + + def test_wasm_table_get_null_table(self): + ffi.wasm_table_get(ffi.create_null_pointer(ffi.wasm_table_t), 0) + + def test_wasm_table_get_out_of_bounds(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + ffi.wasm_table_get(tbl, 1_000_000_000) + + def test_wasm_ref(self): + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[0]) + self.assertIsNotNullPointer(func) + + ref = ffi.wasm_func_as_ref(func) + self.assertIsNotNullPointer(ref) + + func_from_ref = ffi.wasm_ref_as_func(ref) + self.assertEqual( + ffi.dereference(ffi.wasm_func_type(func)), + ffi.dereference(ffi.wasm_func_type(func_from_ref)), + ) + + def test_wasm_table_set(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + self.assertIsNotNullPointer(tbl) + + func = ffi.wasm_extern_as_func(export_list[0]) + ref = ffi.wasm_func_as_ref(func) + + ffi.wasm_table_set(tbl, 0, ref) + + ref_ret = ffi.wasm_table_get(tbl, 0) + self.assertIsNotNullPointer(ref_ret) + func_ret = ffi.wasm_ref_as_func(ref_ret) + self.assertEqual( + ffi.dereference(ffi.wasm_func_type(func)), + ffi.dereference(ffi.wasm_func_type(func_ret)), + ) + + def test_wasm_table_set_unlinked(self): + vt = ffi.wasm_valtype_new(ffi.WASM_FUNCREF) + limits = ffi.wasm_limits_new(10, 15) + tt = ffi.wasm_tabletype_new(vt, limits) + tbl = ffi.wasm_table_new( + self._wasm_store, tt, ffi.create_null_pointer(ffi.wasm_ref_t) + ) + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[0]) + ref = ffi.wasm_func_as_ref(func) + ffi.wasm_table_set(tbl, 0, ref) + ffi.wasm_table_delete(tbl) + + def test_wasm_table_set_null_table(self): + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[0]) + ref = ffi.wasm_func_as_ref(func) + ffi.wasm_table_set(ffi.create_null_pointer(ffi.wasm_table_t), 0, ref) + + def test_wasm_table_set_null_ref(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + ffi.wasm_table_set(tbl, 0, ffi.create_null_pointer(ffi.wasm_ref_t)) + + def test_wasm_table_set_out_of_bounds(self): + export_list = ffi.wasm_vec_to_list(self.exports) + tbl = ffi.wasm_extern_as_table(export_list[3]) + func = ffi.wasm_extern_as_func(export_list[0]) + ref = ffi.wasm_func_as_ref(func) + ffi.wasm_table_set(tbl, 1_000_000_000, ref) + + def test_wasm_memory_size(self): + export_list = ffi.wasm_vec_to_list(self.exports) + mem = ffi.wasm_extern_as_memory(export_list[2]) + self.assertIsNotNullPointer(mem) + + pg_sz = ffi.wasm_memory_size(mem) + self.assertEqual(pg_sz, 1) + + def test_wasm_memory_size_unlinked(self): + limits = ffi.wasm_limits_new(10, 12) + mt = ffi.wasm_memorytype_new(limits) + mem = ffi.wasm_memory_new(self._wasm_store, mt) + ffi.wasm_memory_size(mem) + ffi.wasm_memory_delete(mem) + + def test_wasm_memory_data(self): + export_list = ffi.wasm_vec_to_list(self.exports) + mem = ffi.wasm_extern_as_memory(export_list[2]) + self.assertIsNotNullPointer(mem) + + data_base = ffi.wasm_memory_data(mem) + self.assertIsNotNone(data_base) + + def test_wasm_memory_data_unlinked(self): + limits = ffi.wasm_limits_new(10, 12) + mt = ffi.wasm_memorytype_new(limits) + mem = ffi.wasm_memory_new(self._wasm_store, mt) + ffi.wasm_memory_data(mem) + ffi.wasm_memory_delete(mem) + + def test_wasm_memory_data_size(self): + export_list = ffi.wasm_vec_to_list(self.exports) + mem = ffi.wasm_extern_as_memory(export_list[2]) + self.assertIsNotNullPointer(mem) + + mem_sz = ffi.wasm_memory_data_size(mem) + self.assertGreater(mem_sz, 0) + + def test_wasm_memory_data_size_unlinked(self): + limits = ffi.wasm_limits_new(10, 12) + mt = ffi.wasm_memorytype_new(limits) + mem = ffi.wasm_memory_new(self._wasm_store, mt) + ffi.wasm_memory_data_size(mem) + ffi.wasm_memory_delete(mem) + + def test_wasm_trap(self): + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[0]) + # make a call + params = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(params) + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(results) + + trap = ffi.wasm_func_call(func, params, results) + self.assertIsNotNullPointer(trap) + + message = ffi.wasm_message_t() + ffi.wasm_trap_message(trap, message) + self.assertIsNotNullPointer(c.pointer(message)) + + # not a function internal exception + frame = ffi.wasm_trap_origin(trap) + self.assertIsNullPointer(frame) + + @unittest.skipUnless( + TEST_WITH_WAMR_BUILD_DUMP_CALL_STACK, + "need to enable WAMR_BUILD_DUMP_CALL_STACK", + ) + # assertions only works if enabling WAMR_BUILD_DUMP_CALL_STACK + def test_wasm_frame(self): + export_list = ffi.wasm_vec_to_list(self.exports) + func = ffi.wasm_extern_as_func(export_list[4]) + # make a call + params = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(params) + results = ffi.wasm_val_vec_t() + ffi.wasm_val_vec_new_empty(results) + + print("Making a call...") + trap = ffi.wasm_func_call(func, params, results) + + message = ffi.wasm_message_t() + ffi.wasm_trap_message(trap, message) + self.assertIsNotNullPointer(c.pointer(message)) + print(message) + + frame = ffi.wasm_trap_origin(trap) + self.assertIsNotNullPointer(frame) + print(ffi.dereference(frame)) + + traces = ffi.wasm_frame_vec_t() + ffi.wasm_trap_trace(trap, traces) + self.assertIsNotNullPointer(c.pointer(frame)) + + instance = ffi.wasm_frame_instance(frame) + self.assertIsNotNullPointer(instance) + + module_offset = ffi.wasm_frame_module_offset(frame) + + func_index = ffi.wasm_frame_func_index(frame) + self.assertEqual(func_index, 2) + + func_offset = ffi.wasm_frame_func_offset(frame) + self.assertGreater(func_offset, 0) + + @classmethod + def tearDownClass(cls): + print("Shutting down...") + ffi.wasm_store_delete(cls._wasm_store) + ffi.wasm_engine_delete(cls._wasm_engine) + + +if __name__ == "__main__": + unittest.main() diff --git a/language-bindings/python/tests/test_basic.py b/language-bindings/python/tests/test_basic.py new file mode 100644 index 00000000..556162bd --- /dev/null +++ b/language-bindings/python/tests/test_basic.py @@ -0,0 +1,1588 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +# pylint: disable=missing-module-docstring + +import ctypes as c +import unittest +from venv import create + +from wamr.ffi import * + +# It is a module likes: +# (module +# (import "mod" "g0" (global i32)) +# (import "mod" "f0" (func (param f32) (result f64))) +# +# (func (export "f1") (param i32 i64)) +# (global (export "g1") (mut f32) (f32.const 3.14)) +# (memory 1 2) +# (table 1 funcref) +# ) +MODULE_BINARY = ( + b"\x00asm\x01\x00\x00\x00\x01\x0b\x02`\x01}\x01|`\x02\x7f~\x00" + b"\x02\x14\x02\x03mod\x02g0\x03\x7f\x00\x03mod\x02f0\x00\x00\x03" + b"\x02\x01\x01\x04\x04\x01p\x00\x01\x05\x04\x01\x01\x01\x02\x06\t" + b"\x01}\x01C\xc3\xf5H@\x0b\x07\x0b\x02\x02f1\x00\x01\x02g1\x03\x01\n" + b"\x04\x01\x02\x00\x0b" +) + + +@wasm_func_cb_decl +def callback(args, results): + # pylint: disable=unused-argument + print("summer") + + +@wasm_func_with_env_cb_decl +def callback_with_env(env, args, results): + # pylint: disable=unused-argument + print("summer") + + +class BasicTestSuite(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._wasm_engine = wasm_engine_new() + cls._wasm_store = wasm_store_new(cls._wasm_engine) + + def assertIsNullPointer(self, c_pointer): + if not is_null_pointer(c_pointer): + self.fail("not a null pointer") + + def assertIsNotNullPointer(self, c_pointer): + if is_null_pointer(c_pointer): + self.fail("not a non-null pointer") + + def test_wasm_valkind(self): + self.assertEqual( + [WASM_I32, WASM_I64, WASM_F32, WASM_F64, WASM_ANYREF, WASM_FUNCREF], + [0, 1, 2, 3, 128, 129], + ) + + def test_wasm_valtype_new_pos(self): + vt = wasm_valtype_new(WASM_I32) + self.assertIsNotNullPointer(vt) + wasm_valtype_delete(vt) + + def test_wasm_valtype_new_neg(self): + vt = wasm_valtype_new(37) + self.assertIsNullPointer(vt) + wasm_valtype_delete(vt) + + def test_wasm_valtype_kind_pos(self): + vt = wasm_valtype_new(WASM_I64) + self.assertEqual(wasm_valtype_kind(vt), WASM_I64) + wasm_valtype_delete(vt) + + def test_wasm_valtype_kind_neg(self): + wasm_valtype_kind(create_null_pointer(wasm_valtype_t)) + + def test_wasm_valtype_delete_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + wasm_valtype_delete(vt) + + def test_wasm_valtype_delete_neg(self): + wasm_valtype_delete(create_null_pointer(wasm_valtype_t)) + + def test_wasm_valtype_copy_pos(self): + vt1 = wasm_valtype_new(WASM_FUNCREF) + vt2 = wasm_valtype_copy(vt1) + + self.assertIsNotNone(vt1) + self.assertIsNotNullPointer(vt1) + self.assertEqual(dereference(vt1), dereference(vt2)) + + wasm_valtype_delete(vt1) + wasm_valtype_delete(vt2) + + def test_wasm_valtype_copy_neg(self): + vt = wasm_valtype_copy(create_null_pointer(wasm_valtype_t)) + self.assertIsNotNone(vt) + self.assertIsNullPointer(vt) + + def test_list_to_carray(self): + v1 = wasm_valtype_new(WASM_I64) + v2 = wasm_valtype_new(WASM_F32) + v3 = wasm_valtype_new(WASM_FUNCREF) + data = list_to_carray(c.POINTER(wasm_valtype_t), v1, v2, v3) + + self.assertIsNotNone(data) + self.assertTrue(isinstance(data, c.Array)) + self.assertEqual(data._length_, 3) + self.assertEqual(dereference(data[0]), dereference(v1)) + self.assertEqual(dereference(data[1]), dereference(v2)) + self.assertEqual(dereference(data[2]), dereference(v3)) + + wasm_valtype_delete(v1) + wasm_valtype_delete(v2) + wasm_valtype_delete(v3) + + def test_wasm_valtype_vec_new_pos(self): + def_vt_list = [ + wasm_valtype_new(WASM_I32), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_FUNCREF), + ] + data = list_to_carray(c.POINTER(wasm_valtype_t), *def_vt_list) + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new(vt_vec, 3, data) + + self.assertEqual(vt_vec.size, 3) + self.assertEqual(vt_vec.num_elems, 3) + self.assertIsNotNullPointer(vt_vec.data) + + ret_vt_list = wasm_vec_to_list(vt_vec) + ret_vt_list = [dereference(vt) for vt in ret_vt_list] + def_vt_list = [dereference(vt) for vt in def_vt_list] + self.assertEqual(ret_vt_list, def_vt_list) + + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_new_neg(self): + data = list_to_carray( + c.POINTER(wasm_valtype_t), + wasm_valtype_new(WASM_I32), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_FUNCREF), + ) + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new(vt_vec, 1_000_000_000, data) + + self.assertEqual(vt_vec.size, 0) + self.assertIsNullPointer(vt_vec.data) + + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_new_null_out(self): + data = list_to_carray( + c.POINTER(wasm_valtype_t), + wasm_valtype_new(WASM_I32), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_FUNCREF), + ) + wasm_valtype_vec_new(create_null_pointer(wasm_valtype_vec_t), 10, data) + + def test_wasm_valtype_vec_new_null_data(self): + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new(vt_vec, 3, create_null_pointer(wasm_valtype_t)) + self.assertIsNotNone(vt_vec) + self.assertIsNotNullPointer(c.pointer(vt_vec)) + + def test_wasm_valtype_vec_new_uninitialized_pos(self): + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new_uninitialized((vt_vec), 2) + self.assertEqual(2, vt_vec.size) + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_new_uninitialized_neg(self): + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new_uninitialized(vt_vec, 1_000_000_000) + self.assertEqual(vt_vec.size, 0) + self.assertIsNullPointer(vt_vec.data) + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_new_uninitialized_null_out(self): + wasm_valtype_vec_new_uninitialized(create_null_pointer(wasm_valtype_vec_t), 2) + + def test_wasm_valtype_vec_new_empty_pos(self): + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new_empty(vt_vec) + self.assertEqual(0, vt_vec.size) + self.assertIsNullPointer(vt_vec.data) + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_new_empty_neg(self): + wasm_valtype_vec_new_empty(create_null_pointer(wasm_valtype_vec_t)) + + def test_wasm_valtype_vec_copy_pos(self): + vt_vec1 = wasm_valtype_vec_t() + vt1 = wasm_valtype_new(WASM_F32) + vt2 = wasm_valtype_new(WASM_I32) + data = list_to_carray(c.POINTER(wasm_valtype_t), vt1, vt2) + wasm_valtype_vec_new(vt_vec1, 2, data) + + vt_vec2 = wasm_valtype_vec_t() + wasm_valtype_vec_copy(vt_vec2, vt_vec1) + + print(f"{vt_vec1} --> {vt_vec2}") + + self.assertEqual(vt_vec2.size, 2) + self.assertEqual(vt_vec2.num_elems, 2) + self.assertEqual(dereference(vt_vec2.data[0]), dereference(vt1)) + self.assertEqual(dereference(vt_vec2.data[1]), dereference(vt2)) + + wasm_valtype_vec_delete(vt_vec1) + wasm_valtype_vec_delete(vt_vec2) + + def test_wasm_valtype_vec_copy_null_src(self): + dst = wasm_valtype_vec_t() + wasm_valtype_vec_copy(dst, create_null_pointer(wasm_valtype_vec_t)) + self.assertIsNotNullPointer(c.pointer(dst)) + self.assertIsNullPointer(dst.data) + + def test_wasm_valtype_vec_copy_null_dst(self): + src = wasm_valtype_vec_t() + wasm_valtype_vec_new_empty(src) + wasm_valtype_vec_copy(create_null_pointer(wasm_valtype_vec_t), src) + wasm_valtype_vec_delete(src) + + def test_wasm_valtype_vec_delete_pos(self): + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new_uninitialized(vt_vec, 10) + wasm_valtype_vec_delete(vt_vec) + + vt_vec = wasm_valtype_vec_t() + wasm_valtype_vec_new_empty(vt_vec) + wasm_valtype_vec_delete(vt_vec) + + def test_wasm_valtype_vec_delete_neg(self): + wasm_valtype_vec_delete(create_null_pointer(wasm_valtype_vec_t)) + + def test_wasm_functype_new_0_0(self): + ft = wasm_functype_new_0_0() + + self.assertIsNotNullPointer(ft) + self.assertEqual(0, dereference(wasm_functype_params(ft)).size) + self.assertEqual(0, dereference(wasm_functype_results(ft)).size) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_1_0(self): + vt = wasm_valtype_new(WASM_I64) + ft = wasm_functype_new_1_0(vt) + + self.assertIsNotNullPointer(ft) + params = wasm_vec_to_list(wasm_functype_params(ft)) + self.assertEqual([dereference(p) for p in params], [dereference(vt)]) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_2_0(self): + vt1 = wasm_valtype_new(WASM_I64) + vt2 = wasm_valtype_new(WASM_F64) + ft = wasm_functype_new_2_0(vt1, vt2) + + self.assertIsNotNullPointer(ft) + self.assertEqual(2, dereference(wasm_functype_params(ft)).size) + self.assertEqual(0, dereference(wasm_functype_results(ft)).size) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_3_0(self): + vt_list = [ + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_I64), + ] + ft = wasm_functype_new_3_0(*vt_list) + + params = wasm_vec_to_list(wasm_functype_params(ft)) + self.assertEqual( + [dereference(p) for p in params], + [dereference(vt) for vt in vt_list], + ) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_0_1(self): + vt1 = wasm_valtype_new(WASM_I64) + ft = wasm_functype_new_0_1(vt1) + + self.assertIsNotNullPointer(ft) + self.assertEqual(0, dereference(wasm_functype_params(ft)).size) + self.assertEqual(1, dereference(wasm_functype_results(ft)).size) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_1_1(self): + vt1 = wasm_valtype_new(WASM_I64) + vt2 = wasm_valtype_new(WASM_F64) + ft = wasm_functype_new_1_1(vt1, vt2) + + params = wasm_vec_to_list(wasm_functype_params(ft)) + self.assertEqual(dereference(params[0]), dereference(vt1)) + + results = wasm_vec_to_list(wasm_functype_results(ft)) + self.assertEqual(dereference(results[0]), dereference(vt2)) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_2_1(self): + vt_list = [ + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_I64), + ] + ft = wasm_functype_new_2_1(*vt_list) + + self.assertIsNotNullPointer(ft) + self.assertEqual(2, dereference(wasm_functype_params(ft)).size) + self.assertEqual(1, dereference(wasm_functype_results(ft)).size) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_3_1(self): + vt_list = [ + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_I32), + ] + ft = wasm_functype_new_3_1(*vt_list) + + params = wasm_vec_to_list(wasm_functype_params(ft)) + self.assertEqual( + [dereference(p) for p in params], [dereference(vt) for vt in vt_list[:3]] + ) + + results = wasm_vec_to_list(wasm_functype_results(ft)) + self.assertEqual(dereference(results[0]), dereference(vt_list[-1])) + + wasm_functype_delete(ft) + + def test_wasm_functype_new_neg(self): + ft = wasm_functype_new( + create_null_pointer(wasm_valtype_vec_t), + create_null_pointer(wasm_valtype_vec_t), + ) + + self.assertIsNotNullPointer(ft) + + wasm_functype_delete(ft) + + def test_wasm_functype_delete_pos(self): + ft = wasm_functype_new_0_0() + wasm_functype_delete(ft) + + def test_wasm_functype_delete_neg(self): + wasm_functype_delete(create_null_pointer(wasm_functype_t)) + + def test_wasm_functype_params_pos(self): + vt_list = [ + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_I64), + ] + ft = wasm_functype_new_3_0(*vt_list) + params = wasm_vec_to_list(wasm_functype_params(ft)) + + self.assertEqual( + [dereference(p) for p in params], + [dereference(vt) for vt in vt_list], + ) + + wasm_functype_delete(ft) + + def test_wasm_functype_params_neg(self): + params = wasm_functype_params(create_null_pointer(wasm_functype_t)) + self.assertIsNullPointer(params) + + def test_wasm_functype_results_pos(self): + vt1 = wasm_valtype_new(WASM_I64) + ft = wasm_functype_new_0_1(vt1) + results = wasm_vec_to_list(wasm_functype_results(ft)) + + self.assertEqual(dereference(results[0]), dereference(vt1)) + + wasm_functype_delete(ft) + + def test_wasm_functype_results_neg(self): + results = wasm_functype_results(create_null_pointer(wasm_functype_t)) + self.assertIsNullPointer(results) + + def test_wasm_functype_copy_pos(self): + ft1 = wasm_functype_new_2_1( + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_F64), + wasm_valtype_new(WASM_I64), + ) + ft2 = wasm_functype_copy(ft1) + + self.assertIsNotNullPointer(ft2) + self.assertEqual(2, dereference(wasm_functype_params(ft1)).size) + self.assertEqual(1, dereference(wasm_functype_results(ft2)).size) + + wasm_functype_delete(ft1) + wasm_functype_delete(ft2) + + def test_wasm_functype_copy_neg(self): + ft2 = wasm_functype_copy(create_null_pointer(wasm_functype_t)) + self.assertIsNullPointer(ft2) + wasm_functype_delete(ft2) + + def test_wasm_globaltype_new_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + gt = wasm_globaltype_new(vt, True) + + self.assertIsNotNullPointer(gt) + + wasm_globaltype_delete(gt) + + def test_wasm_globaltype_new_neg(self): + gt = wasm_globaltype_new(create_null_pointer(wasm_valtype_t), True) + self.assertIsNullPointer(gt) + wasm_globaltype_delete(gt) + + def test_wasm_globaltype_delete_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + gt = wasm_globaltype_new(vt, False) + wasm_globaltype_delete(gt) + + def test_wasm_globaltype_delete_neg(self): + wasm_globaltype_delete(create_null_pointer(wasm_globaltype_t)) + + def test_wasm_globaltype_content_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + gt = wasm_globaltype_new(vt, True) + gt_ret = wasm_globaltype_content(gt) + + self.assertEqual(dereference(vt), dereference(gt_ret)) + + wasm_globaltype_delete(gt) + + def test_wasm_globaltype_content_neg(self): + gt_ret = wasm_globaltype_content(create_null_pointer(wasm_globaltype_t)) + self.assertIsNullPointer(gt_ret) + + def test_wasm_globaltype_mutability_pos(self): + vt1 = wasm_valtype_new(WASM_F32) + gt1 = wasm_globaltype_new(vt1, False) + vt2 = wasm_valtype_new(WASM_F32) + gt2 = wasm_globaltype_new(vt2, True) + + self.assertFalse(wasm_globaltype_mutability(gt1)) + self.assertTrue(wasm_globaltype_mutability(gt2)) + + wasm_globaltype_delete(gt1) + wasm_globaltype_delete(gt2) + + def test_wasm_globaltype_mutability_neg(self): + self.assertFalse( + wasm_globaltype_mutability(create_null_pointer(wasm_globaltype_t)) + ) + + def test_wasm_globaltype_copy_pos(self): + vt = wasm_valtype_new(WASM_I32) + gt1 = wasm_globaltype_new(vt, True) + gt2 = wasm_globaltype_copy(gt1) + + self.assertEqual(dereference(gt1), dereference(gt2)) + + wasm_globaltype_delete(gt1) + wasm_globaltype_delete(gt2) + + def test_wasm_globaltype_copy_neg(self): + gt2 = wasm_globaltype_copy(create_null_pointer(wasm_globaltype_t)) + + self.assertIsNullPointer(gt2) + wasm_globaltype_delete(gt2) + + def test_wasm_limit_new(self): + limit = wasm_limits_new(10, 20) + self.assertIsNotNullPointer(limit) + self.assertEqual(dereference(limit).min, 10) + self.assertEqual(dereference(limit).max, 20) + + def test_wasm_tabletype_new_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limit = wasm_limits_new(0, 0xFF) + tt = wasm_tabletype_new(vt, limit) + + self.assertIsNotNullPointer(tt) + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_new_null_val_type(self): + limit = wasm_limits_new(0, 0xFFFFFFFF) + tt = wasm_tabletype_new(create_null_pointer(wasm_valtype_t), limit) + + self.assertIsNullPointer(tt) + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_new_null_limits(self): + vt = wasm_valtype_new(WASM_FUNCREF) + tt = wasm_tabletype_new(vt, create_null_pointer(wasm_limits_t)) + + self.assertIsNullPointer(tt) + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_delete_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limit = wasm_limits_new(0, 0xFFFFFFFF) + tt = wasm_tabletype_new(vt, limit) + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_delete_neg(self): + wasm_tabletype_delete(create_null_pointer(wasm_tabletype_t)) + + def test_wasm_tabletype_element_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limit = wasm_limits_new(0, 0xFFFFFFFF) + tt = wasm_tabletype_new(vt, limit) + vt_ret = wasm_tabletype_element(tt) + + self.assertEqual(dereference(vt), dereference(vt_ret)) + + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_element_neg(self): + vt_ret = wasm_tabletype_element(create_null_pointer(wasm_tabletype_t)) + self.assertIsNullPointer(vt_ret) + + def test_wasm_tabletype_limits_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limit = wasm_limits_new(100, 256) + tt = wasm_tabletype_new(vt, limit) + limit_ret = wasm_tabletype_limits(tt) + + self.assertEqual(dereference(limit), dereference(limit_ret)) + + wasm_tabletype_delete(tt) + + def test_wasm_tabletype_limits_neg(self): + limit_ret = wasm_tabletype_limits(create_null_pointer(wasm_tabletype_t)) + self.assertIsNullPointer(limit_ret) + + def test_wasm_tabletype_copy_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limit = wasm_limits_new(13, 19) + tt1 = wasm_tabletype_new(vt, limit) + tt2 = wasm_tabletype_copy(tt1) + + self.assertEqual(dereference(tt1), dereference(tt2)) + + wasm_tabletype_delete(tt1) + wasm_tabletype_delete(tt2) + + def test_wasm_tabletype_copy_neg(self): + tt2 = wasm_tabletype_copy(create_null_pointer(wasm_tabletype_t)) + self.assertIsNullPointer(tt2) + wasm_tabletype_delete(tt2) + + def test_wasm_memorytype_new_pos(self): + limit = wasm_limits_new(0, 3) + mt = wasm_memorytype_new(limit) + + self.assertIsNotNullPointer(mt) + + wasm_memorytype_delete(mt) + + def test_wasm_memorytype_new_neg(self): + mt = wasm_memorytype_new(None) + + self.assertIsNullPointer(mt) + + wasm_memorytype_delete(mt) + + def test_wasm_memorytype_delete_pos(self): + limit = wasm_limits_new(1, 2) + mt = wasm_memorytype_new(limit) + wasm_memorytype_delete(mt) + + def test_wasm_memorytype_delete_neg(self): + wasm_memorytype_delete(create_null_pointer(wasm_memorytype_t)) + + def test_wasm_memorytype_limits_pos(self): + limit = wasm_limits_new(3, 8) + mt = wasm_memorytype_new(limit) + limit_ret = wasm_memorytype_limits(mt) + + self.assertEqual(dereference(limit), dereference(limit_ret)) + + wasm_memorytype_delete(mt) + + def test_wasm_memorytype_limits_neg(self): + wasm_memorytype_limits(create_null_pointer(wasm_memorytype_t)) + + def test_wasm_memorytype_copy_pos(self): + limit = wasm_limits_new(7, 13) + mt1 = wasm_memorytype_new(limit) + mt2 = wasm_memorytype_copy(mt1) + + self.assertEqual( + dereference(mt1), + dereference(mt2), + ) + + wasm_memorytype_delete(mt1) + wasm_memorytype_delete(mt2) + + def test_wasm_memorytype_copy_neg(self): + mt2 = wasm_memorytype_copy(create_null_pointer(wasm_memorytype_t)) + + self.assertIsNullPointer(mt2) + + wasm_memorytype_delete(mt2) + + def test_wasm_externtype_kind_pos(self): + ft = wasm_functype_new_0_0() + gt = wasm_globaltype_new(wasm_valtype_new(WASM_FUNCREF), True) + mt = wasm_memorytype_new(wasm_limits_new(1, 2)) + tt = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), wasm_limits_new(10, 20)) + ets = [ + wasm_functype_as_externtype(ft), + wasm_globaltype_as_externtype(gt), + wasm_memorytype_as_externtype(mt), + wasm_tabletype_as_externtype(tt), + ] + type_kinds = [wasm_externtype_kind(et) for et in ets] + + self.assertEqual( + type_kinds, + [ + WASM_EXTERN_FUNC, + WASM_EXTERN_GLOBAL, + WASM_EXTERN_MEMORY, + WASM_EXTERN_TABLE, + ], + ) + + [wasm_externtype_delete(et) for et in ets] + + def test_wasm_externtype_kind_neg(self): + et = wasm_memorytype_as_externtype(create_null_pointer(wasm_memorytype_t)) + self.assertIsNullPointer(et) + + def test_wasm_externtype_delete_pos(self): + mt = wasm_memorytype_new(wasm_limits_new(10, 20)) + et = wasm_memorytype_as_externtype(mt) + wasm_externtype_delete(et) + + def test_wasm_externtype_delete_neg(self): + et = wasm_globaltype_as_externtype(create_null_pointer(wasm_globaltype_t)) + wasm_externtype_delete(et) + + def test_wasm_externtype_copy_pos(self): + tt1 = wasm_tabletype_new( + wasm_valtype_new(WASM_FUNCREF), wasm_limits_new(10, 20) + ) + et1 = wasm_tabletype_as_externtype(tt1) + et2 = wasm_externtype_copy(et1) + + tt2 = wasm_externtype_as_tabletype(et2) + self.assertEqual(dereference(tt1), dereference(tt2)) + + wasm_externtype_delete(et2) + wasm_externtype_delete(et1) + + def test_wasm_externtype_copy_neg(self): + et1 = create_null_pointer(wasm_externtype_t) + et2 = wasm_externtype_copy(et1) + wasm_externtype_delete(et2) + wasm_externtype_delete(et1) + + def test_wasm_name_new_from_string(self): + s = "let the stars shine upon you" + name = wasm_name_new_from_string(s) + + name_data = c.cast(name.data, c.c_char_p) + name_data = bytes.decode(name_data.value) + self.assertEqual(name_data, s) + + def test_wasm_importtype_new_pos(self): + module_name = "mA" + field_name = "func#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(module_name, field_name, et) + + self.assertIsNotNullPointer(it) + self.assertEqual(dereference(wasm_importtype_module(it)), module_name) + self.assertEqual(dereference(wasm_importtype_name(it)), field_name) + self.assertEqual(dereference(wasm_importtype_type(it)), dereference(et)) + + wasm_importtype_delete(it) + + def test_wasm_importtype_new_null_ext_type(self): + module_name = "mA" + field_name = "func#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + it = wasm_importtype_new( + module_name, + field_name, + create_null_pointer(wasm_externtype_t), + ) + + self.assertIsNullPointer(it) + + wasm_importtype_delete(it) + + def test_wasm_importtype_new_null_module(self): + field_name = "func#1" + field_name = wasm_name_new_from_string(field_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(create_null_pointer(wasm_name_t), field_name, et) + + self.assertIsNullPointer(it) + + wasm_importtype_delete(it) + + def test_wasm_importtype_new_null_field(self): + module_name = "mA" + module_name = wasm_name_new_from_string(module_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(module_name, create_null_pointer(wasm_name_t), et) + + self.assertIsNullPointer(it) + + wasm_importtype_delete(it) + + def test_wasm_importtype_copy_pos(self): + module_name = "mA" + field_name = "memory#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + mt = wasm_memorytype_new(wasm_limits_new(10, 20)) + et = wasm_memorytype_as_externtype(mt) + it1 = wasm_importtype_new(module_name, field_name, et) + it2 = wasm_importtype_copy(it1) + + self.assertEqual(dereference(it1), dereference(it2)) + + wasm_importtype_delete(it1) + wasm_importtype_delete(it2) + + def test_wasm_importtype_copy_neg(self): + it1 = create_null_pointer(wasm_importtype_t) + it2 = wasm_importtype_copy(it1) + wasm_importtype_delete(it1) + wasm_importtype_delete(it2) + + def test_wasm_importtype_delete_pos(self): + module_name = "mA" + field_name = "memory#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + tt = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), wasm_limits_new(10, 20)) + et = wasm_tabletype_as_externtype(tt) + it = wasm_importtype_new(module_name, field_name, et) + wasm_importtype_delete(it) + + def test_wasm_importtype_delete_neg(self): + wasm_importtype_delete(create_null_pointer(wasm_importtype_t)) + + def test_wasm_importtype_module_pos(self): + module_name = "mA" + field_name = "func#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(module_name, field_name, et) + module_name_ret = wasm_importtype_module(it) + + self.assertEqual(dereference(module_name_ret), module_name) + + wasm_importtype_delete(it) + + def test_wasm_importtype_module_neg(self): + it = create_null_pointer(wasm_importtype_t) + wasm_importtype_module(it) + wasm_importtype_delete(it) + + def test_wasm_importtype_name_pos(self): + module_name = "mA" + field_name = "func#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(module_name, field_name, et) + field_name_ret = wasm_importtype_name(it) + + self.assertEqual(dereference(field_name_ret), field_name) + + wasm_importtype_delete(it) + + def test_wasm_importtype_name_neg(self): + it = create_null_pointer(wasm_importtype_t) + wasm_importtype_name(it) + wasm_importtype_delete(it) + + def test_wasm_importtype_type_pos(self): + module_name = "mA" + field_name = "func#1" + module_name = wasm_name_new_from_string(module_name) + field_name = wasm_name_new_from_string(field_name) + ft = wasm_functype_new_0_0() + et = wasm_functype_as_externtype(ft) + it = wasm_importtype_new(module_name, field_name, et) + et_ret = wasm_importtype_type(it) + + self.assertEqual(dereference(et_ret), dereference(et)) + + wasm_importtype_delete(it) + + def test_wasm_importtype_type_neg(self): + it = create_null_pointer(wasm_importtype_t) + wasm_importtype_type(it) + wasm_importtype_delete(it) + + def test_wasm_exporttype_new_pos(self): + name = "hello" + name = wasm_name_new_from_string(name) + ft = wasm_functype_new_0_0() + ft = wasm_functype_as_externtype(ft) + et = wasm_exporttype_new(name, ft) + + self.assertIsNotNullPointer(et) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_new_null_name(self): + name = create_null_pointer(wasm_name_t) + ft = wasm_functype_new_0_0() + ft = wasm_functype_as_externtype(ft) + et = wasm_exporttype_new(name, ft) + + self.assertIsNullPointer(et) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_new_null_ext_type(self): + name = "hello" + name = wasm_name_new_from_string(name) + ext_type = create_null_pointer(wasm_externtype_t) + et = wasm_exporttype_new(name, ext_type) + + self.assertIsNullPointer(et) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_copy_pos(self): + name = "hello" + name = wasm_name_new_from_string(name) + gt = wasm_globaltype_new(wasm_valtype_new(WASM_F32), True) + gt = wasm_globaltype_as_externtype(gt) + et1 = wasm_exporttype_new(name, gt) + et2 = wasm_exporttype_copy(et1) + + self.assertEqual( + dereference(et1), + dereference(et2), + ) + + wasm_exporttype_delete(et1) + wasm_exporttype_delete(et2) + + def test_wasm_exporttype_copy_neg(self): + et1 = create_null_pointer(wasm_exporttype_t) + et2 = wasm_exporttype_copy(et1) + + wasm_exporttype_delete(et1) + wasm_exporttype_delete(et2) + + def test_wasm_exporttype_delete_pos(self): + name = "hello" + name = wasm_name_new_from_string(name) + mt = wasm_memorytype_new(wasm_limits_new(10, 20)) + mt = wasm_memorytype_as_externtype(mt) + et = wasm_exporttype_new(name, mt) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_delete_neg(self): + et = create_null_pointer(wasm_exporttype_t) + wasm_exporttype_delete(et) + + def test_wasm_exporttype_name_pos(self): + name = "hello" + name = wasm_name_new_from_string(name) + tt = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), wasm_limits_new(10, 20)) + tt = wasm_tabletype_as_externtype(tt) + et = wasm_exporttype_new(name, tt) + name_ret = wasm_exporttype_name(et) + + self.assertEqual(dereference(name_ret), name) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_name_neg(self): + et = create_null_pointer(wasm_exporttype_t) + wasm_exporttype_name(et) + wasm_exporttype_delete(et) + + def test_wasm_exporttype_type_pos(self): + name = "hello" + name = wasm_name_new_from_string(name) + tt = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), wasm_limits_new(10, 20)) + tt = wasm_tabletype_as_externtype(tt) + et = wasm_exporttype_new(name, tt) + tt_ret = wasm_exporttype_type(et) + + self.assertEqual(dereference(tt_ret), dereference(tt)) + + wasm_exporttype_delete(et) + + def test_wasm_exporttype_type_neg(self): + et = create_null_pointer(wasm_exporttype_t) + wasm_exporttype_type(et) + wasm_exporttype_delete(et) + + def test_wasm_i32_val(self): + val = wasm_i32_val(100) + + self.assertEqual(val.kind, WASM_I32) + self.assertEqual(val.of.i32, 100) + + # can not use wasm_val_delete() because it is not malloced + + def test_wasm_i64_val(self): + val = wasm_i64_val(-100) + + self.assertEqual(val.kind, WASM_I64) + self.assertEqual(val.of.i64, -100) + + # can not use wasm_val_delete() because it is not malloced + + def test_wasm_f32_val(self): + val = wasm_f32_val(100) + + self.assertEqual(val.kind, WASM_F32) + self.assertEqual(val.of.f32, 100.0) + + # can not use wasm_val_delete() because it is not malloced + + def test_wasm_f64_val(self): + val = wasm_f64_val(-100) + + self.assertEqual(val.kind, WASM_F64) + self.assertEqual(val.of.f64, -100.0) + + # can not use wasm_val_delete() because it is not malloced + + # there is no wasm_val_new() to malloc a wasm_val_t + def test_wasm_val_delete(self): + pass + + def test_wasm_val_copy(self): + v1 = wasm_f32_val(3.14) + v2 = wasm_val_t() + wasm_val_copy(v1, v2) + + self.assertEqual(v1, v2) + # can not use wasm_val_delete() because it is not malloced + + def test_wasm_ref_delete_neg(self): + ref = create_null_pointer(wasm_ref_t) + wasm_ref_delete(ref) + + ref = wasm_ref_t() + wasm_ref_delete(ref) + + def test_wasm_trap_new_pos(self): + # can't create a trap with traces(wasm_frame_vec_t) + msg = wasm_name_new_from_string("a fake trap") + trap = wasm_trap_new(self._wasm_store, msg) + + self.assertIsNotNone(trap) + + wasm_trap_delete(trap) + + def test_wasm_trap_new_null_msg(self): + trap = wasm_trap_new(self._wasm_store, create_null_pointer(wasm_name_t)) + + self.assertIsNotNone(trap) + self.assertIsNotNullPointer(trap) + + wasm_trap_delete(trap) + + def test_wasm_trap_message_pos(self): + msg = wasm_name_new_from_string("a fake trap") + trap = wasm_trap_new(self._wasm_store, msg) + msg_in_trap = wasm_message_t() + wasm_trap_message(trap, msg_in_trap) + + self.assertEqual( + msg, + msg_in_trap, + ) + + wasm_trap_delete(trap) + + def test_wasm_trap_message_null_trap(self): + msg = wasm_name_new_from_string("a fake trap") + wasm_trap_message(create_null_pointer(wasm_trap_t), msg) + + def test_wasm_trap_message_null_out(self): + msg = wasm_name_new_from_string("a fake trap") + trap = wasm_trap_new(self._wasm_store, msg) + wasm_trap_message(trap, create_null_pointer(wasm_message_t)) + wasm_trap_delete(trap) + + # test those APIs in advance: + # wasm_trap_origin + # wasm_trap_trace + # wasm_frame_delete + # wasm_frame_copy + # wasm_frame_module_offset + # wasm_frame_instance + # wasm_frame_func_index + # wasm_frame_func_offset + + def test_wasm_foreign_new_pos(self): + foreign = wasm_foreign_new(self._wasm_store) + + self.assertIsNotNone(foreign) + self.assertIsNotNullPointer(foreign) + + wasm_foreign_delete(foreign) + + def test_wasm_foreign_new_neg(self): + foreign = wasm_foreign_new(create_null_pointer(wasm_store_t)) + + self.assertIsNotNone(foreign) + self.assertIsNullPointer(foreign) + + wasm_foreign_delete(foreign) + + def test_wasm_foreign_delete_pos(self): + foreign = wasm_foreign_new(self._wasm_store) + wasm_foreign_delete(foreign) + + def test_wasm_foreign_delete_neg(self): + wasm_foreign_delete(create_null_pointer(wasm_foreign_t)) + + # wasm_egnine_new()/wasm_engine_delete() + # wasm_store_new()/wasm_store_delete() + # used in setUpClass() and tearDownClass + + def test_wasm_module_new_pos(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + + self.assertIsNotNone(module) + self.assertIsNotNullPointer(module) + + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_module_new_neg(self): + module = wasm_module_new(self._wasm_store, create_null_pointer(wasm_byte_vec_t)) + + self.assertIsNotNone(module) + self.assertIsNullPointer(module) + + wasm_module_delete(module) + + def test_wasm_module_delete_pos(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_module_delete_neg(self): + module = wasm_module_new(self._wasm_store, create_null_pointer(wasm_byte_vec_t)) + wasm_module_delete(module) + + def test_wasm_module_validate_pos(self): + binary = load_module_file(MODULE_BINARY) + validation = wasm_module_validate(self._wasm_store, binary) + + self.assertTrue(validation) + + wasm_byte_vec_delete(binary) + + def test_wasm_module_validate_neg(self): + tmp = (1024).to_bytes(2, byteorder="big") + binary = load_module_file(tmp) + validation = wasm_module_validate(self._wasm_store, binary) + + self.assertFalse(validation) + + wasm_byte_vec_delete(binary) + + def test_wasm_module_imports_pos(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + imports = wasm_importtype_vec_t() + wasm_module_imports(module, imports) + + imports_list = wasm_vec_to_list(imports) + self.assertEqual(len(imports_list), 2) + + func_type = wasm_functype_new_1_1( + wasm_valtype_new(WASM_F32), + wasm_valtype_new(WASM_F64), + ) + ext_type = wasm_functype_as_externtype(func_type) + self.assertEqual( + dereference(wasm_importtype_type(imports_list[0])), dereference(ext_type) + ) + + wasm_externtype_delete(ext_type) + wasm_importtype_vec_delete(imports) + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_module_imports_null_module(self): + imports = wasm_importtype_vec_t() + wasm_module_imports(create_null_pointer(wasm_module_t), imports) + + self.assertEqual(imports.size, 0) + + wasm_importtype_vec_delete(imports) + + def test_wasm_module_imports_null_out(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + wasm_module_imports(module, create_null_pointer(wasm_importtype_vec_t)) + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_module_exports_pos(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + exports = wasm_exporttype_vec_t() + wasm_module_exports(module, exports) + + exports_list = wasm_vec_to_list(exports) + self.assertEqual(len(exports_list), 2) + + glbl_type = wasm_globaltype_new(wasm_valtype_new(WASM_F32), True) + ext_type = wasm_globaltype_as_externtype(glbl_type) + self.assertEqual( + dereference(wasm_exporttype_type(exports_list[1])), dereference(ext_type) + ) + + wasm_exporttype_vec_delete(exports) + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_module_exports_null_module(self): + exports = wasm_exporttype_vec_t() + wasm_module_exports(create_null_pointer(wasm_module_t), exports) + + self.assertEqual(exports.size, 0) + + wasm_exporttype_vec_delete(exports) + + def test_wasm_module_exports_null_out(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + wasm_module_exports(module, create_null_pointer(wasm_exporttype_vec_t)) + wasm_byte_vec_delete(binary) + wasm_module_delete(module) + + def test_wasm_instance_new_pos_empty_imports(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + imports = wasm_extern_vec_t() + wasm_extern_vec_new_empty(imports) + instance = wasm_instance_new( + self._wasm_store, module, imports, create_null_pointer(wasm_trap_t) + ) + + wasm_instance_delete(instance) + wasm_module_delete(module) + + def test_wasm_instance_new_pos(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + + ft = wasm_functype_new_1_1( + wasm_valtype_new(WASM_F32), + wasm_valtype_new(WASM_F64), + ) + func = wasm_func_new(self._wasm_store, ft, callback) + + gt = wasm_globaltype_new(wasm_valtype_new(WASM_I32), True) + init = wasm_i32_val(100) + gb = wasm_global_new(self._wasm_store, gt, init) + + imports = wasm_extern_vec_t() + data = list_to_carray( + c.POINTER(wasm_extern_t), + wasm_func_as_extern(func), + wasm_global_as_extern(gb), + ) + wasm_extern_vec_new(imports, 2, data) + + instance = wasm_instance_new( + self._wasm_store, module, imports, create_null_pointer(wasm_trap_t) + ) + + self.assertIsNotNone(instance) + + wasm_instance_delete(instance) + wasm_module_delete(module) + + def test_wasm_instance_new_neg_null_imports(self): + binary = load_module_file(MODULE_BINARY) + module = wasm_module_new(self._wasm_store, binary) + instance = wasm_instance_new( + self._wasm_store, + module, + create_null_pointer(wasm_extern_vec_t), + create_null_pointer(wasm_trap_t), + ) + + wasm_instance_delete(instance) + wasm_module_delete(module) + + # test those APIs in advanced: + # wasm_instance_delete + # wasm_instance_exports + + def test_wasm_func_new_pos(self): + vt1 = wasm_valtype_new(WASM_F32) + vt2 = wasm_valtype_new(WASM_FUNCREF) + ft = wasm_functype_new_1_1(vt1, vt2) + func = wasm_func_new(self._wasm_store, ft, callback) + + self.assertIsNotNone(func) + self.assertIsNotNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_new_null_type(self): + func = wasm_func_new( + self._wasm_store, create_null_pointer(wasm_functype_t), callback + ) + + self.assertIsNotNone(func) + self.assertIsNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_new_null_callback(self): + vt1 = wasm_valtype_new(WASM_F32) + vt2 = wasm_valtype_new(WASM_FUNCREF) + ft = wasm_functype_new_1_1(vt1, vt2) + func = wasm_func_new(self._wasm_store, ft, wasm_func_callback_t()) + + self.assertIsNotNone(func) + self.assertIsNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_new_with_env_pos(self): + ft = wasm_functype_new_3_1( + wasm_valtype_new(WASM_I32), + wasm_valtype_new(WASM_F32), + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_I64), + ) + func = wasm_func_new_with_env( + self._wasm_store, + ft, + callback_with_env, + c.c_void_p(0), + wasm_finalizer(0), + ) + + self.assertIsNotNone(func) + self.assertIsNotNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_new_with_env_null_type(self): + func = wasm_func_new_with_env( + self._wasm_store, + create_null_pointer(wasm_functype_t), + callback_with_env, + c.c_void_p(0), + wasm_finalizer(0), + ) + + self.assertIsNotNone(func) + self.assertIsNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_new_with_env_null_callback(self): + ft = wasm_functype_new_3_1( + wasm_valtype_new(WASM_I32), + wasm_valtype_new(WASM_F32), + wasm_valtype_new(WASM_I64), + wasm_valtype_new(WASM_I64), + ) + func = wasm_func_new_with_env( + self._wasm_store, + ft, + wasm_func_callback_with_env_t(), + c.c_void_p(0), + wasm_finalizer(0), + ) + + self.assertIsNotNone(func) + self.assertIsNullPointer(func) + + wasm_func_delete(func) + + def test_wasm_func_delete_pos(self): + ft = wasm_functype_new_0_0() + func = wasm_func_new(self._wasm_store, ft, callback) + wasm_func_delete(func) + + def test_wasm_func_delete_neg(self): + wasm_func_delete(create_null_pointer(wasm_func_t)) + + def test_wasm_func_type_pos(self): + ft = wasm_functype_new_2_0( + wasm_valtype_new(WASM_F32), + wasm_valtype_new(WASM_FUNCREF), + ) + func = wasm_func_new(self._wasm_store, ft, callback) + ft_ret = wasm_func_type(func) + + self.assertEqual( + dereference(ft), + dereference(ft_ret), + ) + + wasm_functype_delete(ft_ret) + wasm_func_delete(func) + + def test_wasm_func_type_neg(self): + ft_ret = wasm_func_type(create_null_pointer(wasm_func_t)) + wasm_functype_delete(ft_ret) + + def test_wasm_func_copy_pos(self): + vt1 = wasm_valtype_new(WASM_F32) + ft = wasm_functype_new_0_1(vt1) + func1 = wasm_func_new(self._wasm_store, ft, callback) + func2 = wasm_func_copy(func1) + + self.assertEqual( + dereference(wasm_func_type(func1)), dereference(wasm_func_type(func2)) + ) + + wasm_func_delete(func2) + wasm_func_delete(func1) + + def test_wasm_func_copy_neg(self): + func1 = wasm_func_new( + self._wasm_store, create_null_pointer(wasm_functype_t), callback + ) + func2 = wasm_func_copy(func1) + + wasm_func_delete(func2) + wasm_func_delete(func1) + + # test wasm_func_call in advanced + + def test_wasm_global_new_pos(self): + vt = wasm_valtype_new(WASM_F32) + gt = wasm_globaltype_new(vt, False) + v = wasm_f32_val(3.14) + g = wasm_global_new(self._wasm_store, gt, v) + + self.assertIsNotNone(g) + self.assertIsNotNullPointer(g) + + wasm_globaltype_delete(gt) + wasm_global_delete(g) + + def test_wasm_global_new_null_type(self): + v = wasm_f32_val(3.14) + g = wasm_global_new(self._wasm_store, create_null_pointer(wasm_globaltype_t), v) + + self.assertIsNotNone(g) + self.assertIsNullPointer(g) + + wasm_global_delete(g) + + def test_wasm_global_new_null_init(self): + vt = wasm_valtype_new(WASM_F32) + gt = wasm_globaltype_new(vt, False) + g = wasm_global_new(self._wasm_store, gt, create_null_pointer(wasm_val_t)) + + self.assertIsNotNone(g) + self.assertIsNullPointer(g) + + wasm_globaltype_delete(gt) + wasm_global_delete(g) + + def test_wasm_global_delete_pos(self): + vt = wasm_valtype_new(WASM_I32) + gt = wasm_globaltype_new(vt, True) + v = wasm_i32_val(3) + g = wasm_global_new(self._wasm_store, gt, v) + wasm_globaltype_delete(gt) + wasm_global_delete(g) + + def test_wasm_global_delete_neg(self): + wasm_global_delete(create_null_pointer(wasm_global_t)) + + def test_wasm_global_type_pos(self): + vt = wasm_valtype_new(WASM_I64) + gt = wasm_globaltype_new(vt, False) + v = wasm_i32_val(3) + g = wasm_global_new(self._wasm_store, gt, v) + gt_ret = wasm_global_type(g) + + self.assertEqual(dereference(gt), dereference(gt_ret)) + + wasm_globaltype_delete(gt) + wasm_globaltype_delete(gt_ret) + wasm_global_delete(g) + + def test_wasm_global_type_neg(self): + gt = wasm_global_type(create_null_pointer(wasm_global_t)) + wasm_globaltype_delete(gt) + + # test wasm_global_get and wasm_global_set in advanced + + def test_wasm_table_new_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limits = wasm_limits_new(10, 15) + tt = wasm_tabletype_new(vt, limits) + t = wasm_table_new(self._wasm_store, tt, create_null_pointer(wasm_ref_t)) + + self.assertIsNotNone(t) + self.assertIsNotNullPointer(t) + + wasm_table_delete(t) + + def test_wasm_table_new_null_type(self): + t = wasm_table_new( + self._wasm_store, + create_null_pointer(wasm_tabletype_t), + create_null_pointer(wasm_ref_t), + ) + + self.assertIsNotNone(t) + self.assertIsNullPointer(t) + + wasm_table_delete(t) + + def test_wasm_table_delete_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limits = wasm_limits_new(10, 15) + tt = wasm_tabletype_new(vt, limits) + t = wasm_table_new(self._wasm_store, tt, create_null_pointer(wasm_ref_t)) + wasm_table_delete(t) + + def test_wasm_table_delete_neg(self): + wasm_table_delete(create_null_pointer(wasm_table_t)) + + def test_wasm_table_type_pos(self): + vt = wasm_valtype_new(WASM_FUNCREF) + limits = wasm_limits_new(1, 2) + tt = wasm_tabletype_new(vt, limits) + t = wasm_table_new(self._wasm_store, tt, create_null_pointer(wasm_ref_t)) + tt_ret = wasm_table_type(t) + + self.assertEqual( + dereference(tt), + dereference(tt_ret), + ) + + wasm_table_delete(t) + + def test_wasm_table_type_neg(self): + t = wasm_table_new( + self._wasm_store, + create_null_pointer(wasm_tabletype_t), + create_null_pointer(wasm_ref_t), + ) + tt_ret = wasm_table_type(t) + wasm_table_delete(t) + + # test wasm_table_size, wasm_table_get, wasm_table_set in advanced + + def test_wasm_memory_new_pos(self): + limits = wasm_limits_new(10, 12) + mt = wasm_memorytype_new(limits) + m = wasm_memory_new(self._wasm_store, mt) + + self.assertIsNotNullPointer(m) + + wasm_memory_delete(m) + + def test_wasm_memory_new_null_type(self): + m = wasm_memory_new(self._wasm_store, create_null_pointer(wasm_memorytype_t)) + + self.assertIsNullPointer(m) + + wasm_memory_delete(m) + + def test_wasm_memory_delete_pos(self): + limits = wasm_limits_new(10, 21) + mt = wasm_memorytype_new(limits) + m = wasm_memory_new(self._wasm_store, mt) + wasm_memory_delete(m) + + def test_wasm_memory_delete_neg(self): + wasm_memory_delete(create_null_pointer(wasm_memory_t)) + + def test_wasm_memory_type_pos(self): + limits = wasm_limits_new(10, 21) + mt = wasm_memorytype_new(limits) + m = wasm_memory_new(self._wasm_store, mt) + mt_ret = wasm_memory_type(m) + + self.assertEqual(dereference(mt), dereference(mt_ret)) + + wasm_memory_delete(m) + + def test_wasm_memory_type_neg(self): + mt = wasm_memory_type(create_null_pointer(wasm_memory_t)) + + self.assertIsNullPointer(mt) + wasm_memorytype_delete(mt) + + # test wasm_memory_size, wasm_memory_data, wasm_memory_data_size in advanced + + def test_wasm_extern_delete_pos(self): + vt = wasm_valtype_new(WASM_I64) + gt = wasm_globaltype_new(vt, False) + v = wasm_i64_val(128) + glb = wasm_global_new(self._wasm_store, gt, v) + etrn = wasm_global_as_extern(glb) + wasm_extern_delete(etrn) + + def test_wasm_extern_delete_neg(self): + etrn = wasm_global_as_extern(create_null_pointer(wasm_global_t)) + wasm_extern_delete(etrn) + + def test_wasm_extern_type_pos(self): + vt = wasm_valtype_new(WASM_I64) + gt = wasm_globaltype_new(vt, False) + v = wasm_i64_val(128) + glb = wasm_global_new(self._wasm_store, gt, v) + etrn = wasm_global_as_extern(glb) + + tp = wasm_extern_type(etrn) + gt_ret = wasm_externtype_as_globaltype(tp) + self.assertEqual( + dereference(gt), + dereference(gt_ret), + ) + wasm_extern_delete(etrn) + + def test_wasm_extern_type_neg(self): + wasm_extern_type(create_null_pointer(wasm_extern_t)) + + def test_wasm_extern_kind_pos(self): + ft = wasm_functype_new_0_0() + func = wasm_func_new(self._wasm_store, ft, callback) + etrn = wasm_func_as_extern(func) + kind = wasm_extern_kind(etrn) + + self.assertEqual(WASM_EXTERN_FUNC, kind) + + wasm_extern_delete(etrn) + + def test_wasm_extern_kind_neg(self): + wasm_extern_kind(create_null_pointer(wasm_extern_t)) + + @classmethod + def tearDownClass(cls): + wasm_store_delete(cls._wasm_store) + wasm_engine_delete(cls._wasm_engine) + + +if __name__ == "__main__": + unittest.main() diff --git a/language-bindings/python/utils/bindgen.py b/language-bindings/python/utils/bindgen.py new file mode 100644 index 00000000..6371ca65 --- /dev/null +++ b/language-bindings/python/utils/bindgen.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +# pylint: disable=missing-module-docstring + +""" +- Need to run *download_wamr.py* firstly. +- Parse *./wasm-micro-runtime/core/iwasm/include/wasm_c_api.h* and generate + *wamr/binding.py* +""" +import os +import pathlib +import shutil +import sys + +from pycparser import c_ast, parse_file + +WASM_C_API_HEADER = "core/iwasm/include/wasm_c_api.h" +BINDING_PATH = "wamr/binding.py" +# 4 spaces as default indent +INDENT = " " + +IGNORE_SYMOLS = ( + "wasm_engine_new_with_args", + "wasm_valkind_is_num", + "wasm_valkind_is_ref", + "wasm_valtype_is_num", + "wasm_valtype_is_ref", + "wasm_valtype_new_i32", + "wasm_valtype_new_i64", + "wasm_valtype_new_f32", + "wasm_valtype_new_f64", + "wasm_valtype_new_anyref", + "wasm_valtype_new_funcref", + "wasm_functype_new_0_0", + "wasm_functype_new_0_0", + "wasm_functype_new_1_0", + "wasm_functype_new_2_0", + "wasm_functype_new_3_0", + "wasm_functype_new_0_1", + "wasm_functype_new_1_1", + "wasm_functype_new_2_1", + "wasm_functype_new_3_1", + "wasm_functype_new_0_2", + "wasm_functype_new_1_2", + "wasm_functype_new_2_2", + "wasm_functype_new_3_2", + "wasm_val_init_ptr", + "wasm_val_ptr", + "wasm_val_t", + "wasm_ref_t", + "wasm_name_new_from_string", + "wasm_name_new_from_string_nt", +) + + +class Visitor(c_ast.NodeVisitor): + def __init__(self): + self.type_map = { + "_Bool": "c_bool", + "byte_t": "c_ubyte", + "char": "c_char", + "errno_t": "c_int", + "int": "c_int", + "long": "c_long", + "size_t": "c_size_t", + "uint32_t": "c_uint32", + "uint8_t": "c_uint8", + "void": "None", + } + self.ret = ( + "# -*- coding: utf-8 -*-\n" + "#!/usr/bin/env python3\n" + "#\n" + "# Copyright (C) 2019 Intel Corporation. All rights reserved.\n" + "# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n" + "#\n" + "#It is a generated file. DO NOT EDIT.\n" + "#\n" + "from ctypes import *\n" + "\n" + "from .ffi import dereference, libiwasm, wasm_ref_t, wasm_val_t\n" + "\n" + "\n" + ) + + def get_type_name(self, c_type): + if isinstance(c_type, c_ast.TypeDecl): + return self.get_type_name(c_type.type) + elif isinstance(c_type, c_ast.PtrDecl): + pointed_type = self.get_type_name(c_type.type) + + if isinstance(c_type.type, c_ast.FuncDecl): + # CFUCNTYPE is a pointer of function + return pointed_type + + if "None" == pointed_type: + return "c_void_p" + + return f"POINTER({pointed_type})" + + elif isinstance(c_type, c_ast.ArrayDecl): + return f"POINTER({self.get_type_name(c_type.type)})" + elif isinstance(c_type, c_ast.IdentifierType): + if len(c_type.names) > 1: + raise RuntimeError(f"unexpected type with a long names: {c_type}") + + type_name = c_type.names[0] + + if type_name.startswith("wasm_"): + return type_name + + if not type_name in self.type_map: + raise RuntimeError(f"a new type should be in type_map: {type_name}") + + return self.type_map.get(type_name) + elif isinstance(c_type, c_ast.Union): + if not c_type.name: + raise RuntimeError(f"found an anonymous union {c_type}") + + return c_type.name + elif isinstance(c_type, c_ast.Struct): + if not c_type.name: + raise RuntimeError(f"found an anonymous union {c_type}") + + return c_type.name + elif isinstance(c_type, c_ast.FuncDecl): + content = "CFUNCTYPE(" + if isinstance(c_type.type, c_ast.PtrDecl): + # there is a bug in CFUNCTYPE if the result type is a pointer + content += "c_void_p" + else: + content += f"{self.get_type_name(c_type.type)}" + content += f",{self.get_type_name(c_type.args)}" if c_type.args else "" + content += ")" + return content + elif isinstance(c_type, c_ast.Decl): + return self.get_type_name(c_type.type) + elif isinstance(c_type, c_ast.ParamList): + content = ",".join( + [self.get_type_name(param.type) for param in c_type.params] + ) + return content + else: + raise RuntimeError(f"unexpected type: {c_type.show()}") + + def visit_Struct(self, node): + # pylint: disable=invalid-name + def gen_fields(info, indent): + content = "" + for k, v in info.items(): + content += f'{indent}("{k}", {v}),\n' + return content[:-1] + + def gen_equal(info, indent): + content = f"{indent}return" + for k, v in info.items(): + # not compare pointer value in __eq__ + if v.startswith("POINTER") or v.startswith("c_void_p"): + continue + + content += f" self.{k} == other.{k} and" + return content[:-4] + + def gen_repr(info, indent): + content = f'{indent}return f"{{{{' + for k, _ in info.items(): + content += f"{k}={{self.{k}}}, " + content = content[:-2] + '}}"' + return content + + def gen_vector_repr(info, indent): + content = f'{indent}ret = ""\n' + content += f"{indent}for i in range(self.num_elems):\n" + + if 1 == info["data"].count("POINTER"): + # pointer + content += f"{2*indent}ret += str(self.data[i])\n" + else: + # pointer of pointer + content += f"{2*indent}ret += str(dereference(self.data[i]))\n" + + content += f'{2*indent}ret += " "\n' + content += f"{indent}return ret\n" + return content + + if not node.name or not node.name.lower().startswith("wasm"): + return + + if node.name in IGNORE_SYMOLS: + return + + name = node.name + + info = {} + if node.decls: + for decl in node.decls: + info[decl.name] = self.get_type_name(decl.type) + + if info: + self.ret += ( + f"class {name}(Structure):\n" + f"{INDENT}_fields_ = [\n" + f"{gen_fields(info, INDENT*2)}\n" + f"{INDENT}]\n" + f"\n" + f"{INDENT}def __eq__(self, other):\n" + f"{INDENT*2}if not isinstance(other, {name}):\n" + f"{INDENT*3}return False\n" + f"{gen_equal(info, INDENT*2)}\n" + f"\n" + f"{INDENT}def __repr__(self):\n" + ) + self.ret += ( + f"{gen_vector_repr(info, INDENT*2)}\n" + if name.endswith("_vec_t") + else f"{gen_repr(info, INDENT*2)}\n" + ) + self.ret += "\n" + + else: + self.ret += f"class {name}(Structure):\n{INDENT}pass\n" + + self.ret += "\n" + + def visit_Union(self, node): + # pylint: disable=invalid-name + print(f"Union: {node.show()}") + + def visit_Typedef(self, node): + # pylint: disable=invalid-name + # system defined + if not node.name: + return + + if not node.name.startswith("wasm_"): + return + + if node.name in IGNORE_SYMOLS: + return + + self.visit(node.type) + + if node.name == self.get_type_name(node.type): + return + else: + self.ret += f"{node.name} = {self.get_type_name(node.type)}\n" + self.ret += "\n" + + def visit_FuncDecl(self, node): + # pylint: disable=invalid-name + restype = self.get_type_name(node.type) + + if isinstance(node.type, c_ast.TypeDecl): + func_name = node.type.declname + elif isinstance(node.type, c_ast.PtrDecl): + func_name = node.type.type.declname + else: + raise RuntimeError(f"unexpected type in FuncDecl: {type}") + + if not func_name.startswith("wasm_") or func_name.endswith("_t"): + return + + if func_name in IGNORE_SYMOLS: + return + + params_len = 0 + for arg in node.args.params: + # ignore void but not void* + if isinstance(arg.type, c_ast.TypeDecl): + type_name = self.get_type_name(arg.type) + if "None" == type_name: + continue + + params_len += 1 + + args = ( + "" if not params_len else ",".join([f"arg{i}" for i in range(params_len)]) + ) + argtypes = f"[{self.get_type_name(node.args)}]" if params_len else "None" + + self.ret += ( + f"def {func_name}({args}):\n" + f"{INDENT}_{func_name} = libiwasm.{func_name}\n" + f"{INDENT}_{func_name}.restype = {restype}\n" + f"{INDENT}_{func_name}.argtypes = {argtypes}\n" + f"{INDENT}return _{func_name}({args})\n" + ) + self.ret += "\n" + + def visit_Enum(self, node): + # pylint: disable=invalid-name + elem_value = 0 + # generate enum elementes directly as consts with values + for i, elem in enumerate(node.values.enumerators): + self.ret += f"{elem.name}" + + if elem.value: + elem_value = int(elem.value.value) + else: + if 0 == i: + elem_value = 0 + else: + elem_value += 1 + + self.ret += f" = {elem_value}\n" + + self.ret += "\n" + + +def preflight_check(workspace): + wamr_repo = workspace.joinpath("wasm-micro-runtime") + file_check_list = [ + wamr_repo.exists(), + wamr_repo.joinpath(WASM_C_API_HEADER).exists(), + ] + + if not all(file_check_list): + print( + "please run utils/download_wamr.py to download the repo, or re-download the repo" + ) + return False + + if not shutil.which("gcc"): + print("please install gcc") + return False + + return True + + +def do_parse(workspace): + filename = workspace.joinpath(WASM_C_API_HEADER) + filename = str(filename) + + ast = parse_file( + filename, + use_cpp=True, + cpp_path="gcc", + cpp_args=[ + "-E", + "-D__attribute__(x)=", + "-D__asm__(x)=", + "-D__asm(x)=", + "-D__builtin_va_list=int", + "-D__extension__=", + "-D__inline__=", + "-D__restrict=", + "-D__restrict__=", + "-D_Static_assert(x, y)=", + "-D__signed=", + "-D__volatile__(x)=", + "-Dstatic_assert(x, y)=", + ], + ) + + ast_visitor = Visitor() + ast_visitor.visit(ast) + return ast_visitor.ret + + +def main(): + current_file = pathlib.Path(__file__) + if current_file.is_symlink(): + current_file = pathlib.Path(os.readlink(current_file)) + + current_dir = current_file.parent.resolve() + root_dir = current_dir.joinpath("..").resolve() + + if not preflight_check(root_dir): + return False + + wamr_repo = root_dir.joinpath("wasm-micro-runtime") + binding_file_path = root_dir.joinpath(BINDING_PATH) + with open(binding_file_path, "wt", encoding="utf-8") as binding_file: + binding_file.write(do_parse(wamr_repo)) + + return True + + +if __name__ == "__main__": + sys.exit(0 if main() else 1) diff --git a/language-bindings/python/wamr/__init__.py b/language-bindings/python/wamr/__init__.py new file mode 100644 index 00000000..8d7404ad --- /dev/null +++ b/language-bindings/python/wamr/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +__all__ = ["ffi"] diff --git a/language-bindings/python/wamr/binding.py b/language-bindings/python/wamr/binding.py new file mode 100644 index 00000000..dd7adadf --- /dev/null +++ b/language-bindings/python/wamr/binding.py @@ -0,0 +1,2020 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#It is a generated file. DO NOT EDIT. +# +from ctypes import * + +from .ffi import dereference, libiwasm, wasm_ref_t, wasm_val_t + + +wasm_byte_t = c_ubyte + +class wasm_byte_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(wasm_byte_t)), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_byte_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(self.data[i]) + ret += " " + return ret + + + +def wasm_byte_vec_new_empty(arg0): + _wasm_byte_vec_new_empty = libiwasm.wasm_byte_vec_new_empty + _wasm_byte_vec_new_empty.restype = None + _wasm_byte_vec_new_empty.argtypes = [POINTER(wasm_byte_vec_t)] + return _wasm_byte_vec_new_empty(arg0) + +def wasm_byte_vec_new_uninitialized(arg0,arg1): + _wasm_byte_vec_new_uninitialized = libiwasm.wasm_byte_vec_new_uninitialized + _wasm_byte_vec_new_uninitialized.restype = None + _wasm_byte_vec_new_uninitialized.argtypes = [POINTER(wasm_byte_vec_t),c_size_t] + return _wasm_byte_vec_new_uninitialized(arg0,arg1) + +def wasm_byte_vec_new(arg0,arg1,arg2): + _wasm_byte_vec_new = libiwasm.wasm_byte_vec_new + _wasm_byte_vec_new.restype = None + _wasm_byte_vec_new.argtypes = [POINTER(wasm_byte_vec_t),c_size_t,POINTER(wasm_byte_t)] + return _wasm_byte_vec_new(arg0,arg1,arg2) + +def wasm_byte_vec_copy(arg0,arg1): + _wasm_byte_vec_copy = libiwasm.wasm_byte_vec_copy + _wasm_byte_vec_copy.restype = None + _wasm_byte_vec_copy.argtypes = [POINTER(wasm_byte_vec_t),POINTER(wasm_byte_vec_t)] + return _wasm_byte_vec_copy(arg0,arg1) + +def wasm_byte_vec_delete(arg0): + _wasm_byte_vec_delete = libiwasm.wasm_byte_vec_delete + _wasm_byte_vec_delete.restype = None + _wasm_byte_vec_delete.argtypes = [POINTER(wasm_byte_vec_t)] + return _wasm_byte_vec_delete(arg0) + +wasm_name_t = wasm_byte_vec_t + +class wasm_config_t(Structure): + pass + +def wasm_config_delete(arg0): + _wasm_config_delete = libiwasm.wasm_config_delete + _wasm_config_delete.restype = None + _wasm_config_delete.argtypes = [POINTER(wasm_config_t)] + return _wasm_config_delete(arg0) + +def wasm_config_new(): + _wasm_config_new = libiwasm.wasm_config_new + _wasm_config_new.restype = POINTER(wasm_config_t) + _wasm_config_new.argtypes = None + return _wasm_config_new() + +class wasm_engine_t(Structure): + pass + +def wasm_engine_delete(arg0): + _wasm_engine_delete = libiwasm.wasm_engine_delete + _wasm_engine_delete.restype = None + _wasm_engine_delete.argtypes = [POINTER(wasm_engine_t)] + return _wasm_engine_delete(arg0) + +def wasm_engine_new(): + _wasm_engine_new = libiwasm.wasm_engine_new + _wasm_engine_new.restype = POINTER(wasm_engine_t) + _wasm_engine_new.argtypes = None + return _wasm_engine_new() + +def wasm_engine_new_with_config(arg0): + _wasm_engine_new_with_config = libiwasm.wasm_engine_new_with_config + _wasm_engine_new_with_config.restype = POINTER(wasm_engine_t) + _wasm_engine_new_with_config.argtypes = [POINTER(wasm_config_t)] + return _wasm_engine_new_with_config(arg0) + +class wasm_store_t(Structure): + pass + +def wasm_store_delete(arg0): + _wasm_store_delete = libiwasm.wasm_store_delete + _wasm_store_delete.restype = None + _wasm_store_delete.argtypes = [POINTER(wasm_store_t)] + return _wasm_store_delete(arg0) + +def wasm_store_new(arg0): + _wasm_store_new = libiwasm.wasm_store_new + _wasm_store_new.restype = POINTER(wasm_store_t) + _wasm_store_new.argtypes = [POINTER(wasm_engine_t)] + return _wasm_store_new(arg0) + +wasm_mutability_t = c_uint8 + +WASM_CONST = 0 +WASM_VAR = 1 + +class wasm_limits_t(Structure): + _fields_ = [ + ("min", c_uint32), + ("max", c_uint32), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_limits_t): + return False + return self.min == other.min and self.max == other.max + + def __repr__(self): + return f"{{min={self.min}, max={self.max}}}" + + +class wasm_valtype_t(Structure): + pass + +def wasm_valtype_delete(arg0): + _wasm_valtype_delete = libiwasm.wasm_valtype_delete + _wasm_valtype_delete.restype = None + _wasm_valtype_delete.argtypes = [POINTER(wasm_valtype_t)] + return _wasm_valtype_delete(arg0) + +class wasm_valtype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_valtype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_valtype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_valtype_vec_new_empty(arg0): + _wasm_valtype_vec_new_empty = libiwasm.wasm_valtype_vec_new_empty + _wasm_valtype_vec_new_empty.restype = None + _wasm_valtype_vec_new_empty.argtypes = [POINTER(wasm_valtype_vec_t)] + return _wasm_valtype_vec_new_empty(arg0) + +def wasm_valtype_vec_new_uninitialized(arg0,arg1): + _wasm_valtype_vec_new_uninitialized = libiwasm.wasm_valtype_vec_new_uninitialized + _wasm_valtype_vec_new_uninitialized.restype = None + _wasm_valtype_vec_new_uninitialized.argtypes = [POINTER(wasm_valtype_vec_t),c_size_t] + return _wasm_valtype_vec_new_uninitialized(arg0,arg1) + +def wasm_valtype_vec_new(arg0,arg1,arg2): + _wasm_valtype_vec_new = libiwasm.wasm_valtype_vec_new + _wasm_valtype_vec_new.restype = None + _wasm_valtype_vec_new.argtypes = [POINTER(wasm_valtype_vec_t),c_size_t,POINTER(POINTER(wasm_valtype_t))] + return _wasm_valtype_vec_new(arg0,arg1,arg2) + +def wasm_valtype_vec_copy(arg0,arg1): + _wasm_valtype_vec_copy = libiwasm.wasm_valtype_vec_copy + _wasm_valtype_vec_copy.restype = None + _wasm_valtype_vec_copy.argtypes = [POINTER(wasm_valtype_vec_t),POINTER(wasm_valtype_vec_t)] + return _wasm_valtype_vec_copy(arg0,arg1) + +def wasm_valtype_vec_delete(arg0): + _wasm_valtype_vec_delete = libiwasm.wasm_valtype_vec_delete + _wasm_valtype_vec_delete.restype = None + _wasm_valtype_vec_delete.argtypes = [POINTER(wasm_valtype_vec_t)] + return _wasm_valtype_vec_delete(arg0) + +def wasm_valtype_copy(arg0): + _wasm_valtype_copy = libiwasm.wasm_valtype_copy + _wasm_valtype_copy.restype = POINTER(wasm_valtype_t) + _wasm_valtype_copy.argtypes = [POINTER(wasm_valtype_t)] + return _wasm_valtype_copy(arg0) + +wasm_valkind_t = c_uint8 + +WASM_I32 = 0 +WASM_I64 = 1 +WASM_F32 = 2 +WASM_F64 = 3 +WASM_ANYREF = 128 +WASM_FUNCREF = 129 + +def wasm_valtype_new(arg0): + _wasm_valtype_new = libiwasm.wasm_valtype_new + _wasm_valtype_new.restype = POINTER(wasm_valtype_t) + _wasm_valtype_new.argtypes = [wasm_valkind_t] + return _wasm_valtype_new(arg0) + +def wasm_valtype_kind(arg0): + _wasm_valtype_kind = libiwasm.wasm_valtype_kind + _wasm_valtype_kind.restype = wasm_valkind_t + _wasm_valtype_kind.argtypes = [POINTER(wasm_valtype_t)] + return _wasm_valtype_kind(arg0) + +class wasm_functype_t(Structure): + pass + +def wasm_functype_delete(arg0): + _wasm_functype_delete = libiwasm.wasm_functype_delete + _wasm_functype_delete.restype = None + _wasm_functype_delete.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_delete(arg0) + +class wasm_functype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_functype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_functype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_functype_vec_new_empty(arg0): + _wasm_functype_vec_new_empty = libiwasm.wasm_functype_vec_new_empty + _wasm_functype_vec_new_empty.restype = None + _wasm_functype_vec_new_empty.argtypes = [POINTER(wasm_functype_vec_t)] + return _wasm_functype_vec_new_empty(arg0) + +def wasm_functype_vec_new_uninitialized(arg0,arg1): + _wasm_functype_vec_new_uninitialized = libiwasm.wasm_functype_vec_new_uninitialized + _wasm_functype_vec_new_uninitialized.restype = None + _wasm_functype_vec_new_uninitialized.argtypes = [POINTER(wasm_functype_vec_t),c_size_t] + return _wasm_functype_vec_new_uninitialized(arg0,arg1) + +def wasm_functype_vec_new(arg0,arg1,arg2): + _wasm_functype_vec_new = libiwasm.wasm_functype_vec_new + _wasm_functype_vec_new.restype = None + _wasm_functype_vec_new.argtypes = [POINTER(wasm_functype_vec_t),c_size_t,POINTER(POINTER(wasm_functype_t))] + return _wasm_functype_vec_new(arg0,arg1,arg2) + +def wasm_functype_vec_copy(arg0,arg1): + _wasm_functype_vec_copy = libiwasm.wasm_functype_vec_copy + _wasm_functype_vec_copy.restype = None + _wasm_functype_vec_copy.argtypes = [POINTER(wasm_functype_vec_t),POINTER(wasm_functype_vec_t)] + return _wasm_functype_vec_copy(arg0,arg1) + +def wasm_functype_vec_delete(arg0): + _wasm_functype_vec_delete = libiwasm.wasm_functype_vec_delete + _wasm_functype_vec_delete.restype = None + _wasm_functype_vec_delete.argtypes = [POINTER(wasm_functype_vec_t)] + return _wasm_functype_vec_delete(arg0) + +def wasm_functype_copy(arg0): + _wasm_functype_copy = libiwasm.wasm_functype_copy + _wasm_functype_copy.restype = POINTER(wasm_functype_t) + _wasm_functype_copy.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_copy(arg0) + +def wasm_functype_new(arg0,arg1): + _wasm_functype_new = libiwasm.wasm_functype_new + _wasm_functype_new.restype = POINTER(wasm_functype_t) + _wasm_functype_new.argtypes = [POINTER(wasm_valtype_vec_t),POINTER(wasm_valtype_vec_t)] + return _wasm_functype_new(arg0,arg1) + +def wasm_functype_params(arg0): + _wasm_functype_params = libiwasm.wasm_functype_params + _wasm_functype_params.restype = POINTER(wasm_valtype_vec_t) + _wasm_functype_params.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_params(arg0) + +def wasm_functype_results(arg0): + _wasm_functype_results = libiwasm.wasm_functype_results + _wasm_functype_results.restype = POINTER(wasm_valtype_vec_t) + _wasm_functype_results.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_results(arg0) + +class wasm_globaltype_t(Structure): + pass + +def wasm_globaltype_delete(arg0): + _wasm_globaltype_delete = libiwasm.wasm_globaltype_delete + _wasm_globaltype_delete.restype = None + _wasm_globaltype_delete.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_delete(arg0) + +class wasm_globaltype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_globaltype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_globaltype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_globaltype_vec_new_empty(arg0): + _wasm_globaltype_vec_new_empty = libiwasm.wasm_globaltype_vec_new_empty + _wasm_globaltype_vec_new_empty.restype = None + _wasm_globaltype_vec_new_empty.argtypes = [POINTER(wasm_globaltype_vec_t)] + return _wasm_globaltype_vec_new_empty(arg0) + +def wasm_globaltype_vec_new_uninitialized(arg0,arg1): + _wasm_globaltype_vec_new_uninitialized = libiwasm.wasm_globaltype_vec_new_uninitialized + _wasm_globaltype_vec_new_uninitialized.restype = None + _wasm_globaltype_vec_new_uninitialized.argtypes = [POINTER(wasm_globaltype_vec_t),c_size_t] + return _wasm_globaltype_vec_new_uninitialized(arg0,arg1) + +def wasm_globaltype_vec_new(arg0,arg1,arg2): + _wasm_globaltype_vec_new = libiwasm.wasm_globaltype_vec_new + _wasm_globaltype_vec_new.restype = None + _wasm_globaltype_vec_new.argtypes = [POINTER(wasm_globaltype_vec_t),c_size_t,POINTER(POINTER(wasm_globaltype_t))] + return _wasm_globaltype_vec_new(arg0,arg1,arg2) + +def wasm_globaltype_vec_copy(arg0,arg1): + _wasm_globaltype_vec_copy = libiwasm.wasm_globaltype_vec_copy + _wasm_globaltype_vec_copy.restype = None + _wasm_globaltype_vec_copy.argtypes = [POINTER(wasm_globaltype_vec_t),POINTER(wasm_globaltype_vec_t)] + return _wasm_globaltype_vec_copy(arg0,arg1) + +def wasm_globaltype_vec_delete(arg0): + _wasm_globaltype_vec_delete = libiwasm.wasm_globaltype_vec_delete + _wasm_globaltype_vec_delete.restype = None + _wasm_globaltype_vec_delete.argtypes = [POINTER(wasm_globaltype_vec_t)] + return _wasm_globaltype_vec_delete(arg0) + +def wasm_globaltype_copy(arg0): + _wasm_globaltype_copy = libiwasm.wasm_globaltype_copy + _wasm_globaltype_copy.restype = POINTER(wasm_globaltype_t) + _wasm_globaltype_copy.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_copy(arg0) + +def wasm_globaltype_new(arg0,arg1): + _wasm_globaltype_new = libiwasm.wasm_globaltype_new + _wasm_globaltype_new.restype = POINTER(wasm_globaltype_t) + _wasm_globaltype_new.argtypes = [POINTER(wasm_valtype_t),wasm_mutability_t] + return _wasm_globaltype_new(arg0,arg1) + +def wasm_globaltype_content(arg0): + _wasm_globaltype_content = libiwasm.wasm_globaltype_content + _wasm_globaltype_content.restype = POINTER(wasm_valtype_t) + _wasm_globaltype_content.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_content(arg0) + +def wasm_globaltype_mutability(arg0): + _wasm_globaltype_mutability = libiwasm.wasm_globaltype_mutability + _wasm_globaltype_mutability.restype = wasm_mutability_t + _wasm_globaltype_mutability.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_mutability(arg0) + +class wasm_tabletype_t(Structure): + pass + +def wasm_tabletype_delete(arg0): + _wasm_tabletype_delete = libiwasm.wasm_tabletype_delete + _wasm_tabletype_delete.restype = None + _wasm_tabletype_delete.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_delete(arg0) + +class wasm_tabletype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_tabletype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_tabletype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_tabletype_vec_new_empty(arg0): + _wasm_tabletype_vec_new_empty = libiwasm.wasm_tabletype_vec_new_empty + _wasm_tabletype_vec_new_empty.restype = None + _wasm_tabletype_vec_new_empty.argtypes = [POINTER(wasm_tabletype_vec_t)] + return _wasm_tabletype_vec_new_empty(arg0) + +def wasm_tabletype_vec_new_uninitialized(arg0,arg1): + _wasm_tabletype_vec_new_uninitialized = libiwasm.wasm_tabletype_vec_new_uninitialized + _wasm_tabletype_vec_new_uninitialized.restype = None + _wasm_tabletype_vec_new_uninitialized.argtypes = [POINTER(wasm_tabletype_vec_t),c_size_t] + return _wasm_tabletype_vec_new_uninitialized(arg0,arg1) + +def wasm_tabletype_vec_new(arg0,arg1,arg2): + _wasm_tabletype_vec_new = libiwasm.wasm_tabletype_vec_new + _wasm_tabletype_vec_new.restype = None + _wasm_tabletype_vec_new.argtypes = [POINTER(wasm_tabletype_vec_t),c_size_t,POINTER(POINTER(wasm_tabletype_t))] + return _wasm_tabletype_vec_new(arg0,arg1,arg2) + +def wasm_tabletype_vec_copy(arg0,arg1): + _wasm_tabletype_vec_copy = libiwasm.wasm_tabletype_vec_copy + _wasm_tabletype_vec_copy.restype = None + _wasm_tabletype_vec_copy.argtypes = [POINTER(wasm_tabletype_vec_t),POINTER(wasm_tabletype_vec_t)] + return _wasm_tabletype_vec_copy(arg0,arg1) + +def wasm_tabletype_vec_delete(arg0): + _wasm_tabletype_vec_delete = libiwasm.wasm_tabletype_vec_delete + _wasm_tabletype_vec_delete.restype = None + _wasm_tabletype_vec_delete.argtypes = [POINTER(wasm_tabletype_vec_t)] + return _wasm_tabletype_vec_delete(arg0) + +def wasm_tabletype_copy(arg0): + _wasm_tabletype_copy = libiwasm.wasm_tabletype_copy + _wasm_tabletype_copy.restype = POINTER(wasm_tabletype_t) + _wasm_tabletype_copy.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_copy(arg0) + +def wasm_tabletype_new(arg0,arg1): + _wasm_tabletype_new = libiwasm.wasm_tabletype_new + _wasm_tabletype_new.restype = POINTER(wasm_tabletype_t) + _wasm_tabletype_new.argtypes = [POINTER(wasm_valtype_t),POINTER(wasm_limits_t)] + return _wasm_tabletype_new(arg0,arg1) + +def wasm_tabletype_element(arg0): + _wasm_tabletype_element = libiwasm.wasm_tabletype_element + _wasm_tabletype_element.restype = POINTER(wasm_valtype_t) + _wasm_tabletype_element.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_element(arg0) + +def wasm_tabletype_limits(arg0): + _wasm_tabletype_limits = libiwasm.wasm_tabletype_limits + _wasm_tabletype_limits.restype = POINTER(wasm_limits_t) + _wasm_tabletype_limits.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_limits(arg0) + +class wasm_memorytype_t(Structure): + pass + +def wasm_memorytype_delete(arg0): + _wasm_memorytype_delete = libiwasm.wasm_memorytype_delete + _wasm_memorytype_delete.restype = None + _wasm_memorytype_delete.argtypes = [POINTER(wasm_memorytype_t)] + return _wasm_memorytype_delete(arg0) + +class wasm_memorytype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_memorytype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_memorytype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_memorytype_vec_new_empty(arg0): + _wasm_memorytype_vec_new_empty = libiwasm.wasm_memorytype_vec_new_empty + _wasm_memorytype_vec_new_empty.restype = None + _wasm_memorytype_vec_new_empty.argtypes = [POINTER(wasm_memorytype_vec_t)] + return _wasm_memorytype_vec_new_empty(arg0) + +def wasm_memorytype_vec_new_uninitialized(arg0,arg1): + _wasm_memorytype_vec_new_uninitialized = libiwasm.wasm_memorytype_vec_new_uninitialized + _wasm_memorytype_vec_new_uninitialized.restype = None + _wasm_memorytype_vec_new_uninitialized.argtypes = [POINTER(wasm_memorytype_vec_t),c_size_t] + return _wasm_memorytype_vec_new_uninitialized(arg0,arg1) + +def wasm_memorytype_vec_new(arg0,arg1,arg2): + _wasm_memorytype_vec_new = libiwasm.wasm_memorytype_vec_new + _wasm_memorytype_vec_new.restype = None + _wasm_memorytype_vec_new.argtypes = [POINTER(wasm_memorytype_vec_t),c_size_t,POINTER(POINTER(wasm_memorytype_t))] + return _wasm_memorytype_vec_new(arg0,arg1,arg2) + +def wasm_memorytype_vec_copy(arg0,arg1): + _wasm_memorytype_vec_copy = libiwasm.wasm_memorytype_vec_copy + _wasm_memorytype_vec_copy.restype = None + _wasm_memorytype_vec_copy.argtypes = [POINTER(wasm_memorytype_vec_t),POINTER(wasm_memorytype_vec_t)] + return _wasm_memorytype_vec_copy(arg0,arg1) + +def wasm_memorytype_vec_delete(arg0): + _wasm_memorytype_vec_delete = libiwasm.wasm_memorytype_vec_delete + _wasm_memorytype_vec_delete.restype = None + _wasm_memorytype_vec_delete.argtypes = [POINTER(wasm_memorytype_vec_t)] + return _wasm_memorytype_vec_delete(arg0) + +def wasm_memorytype_copy(arg0): + _wasm_memorytype_copy = libiwasm.wasm_memorytype_copy + _wasm_memorytype_copy.restype = POINTER(wasm_memorytype_t) + _wasm_memorytype_copy.argtypes = [POINTER(wasm_memorytype_t)] + return _wasm_memorytype_copy(arg0) + +def wasm_memorytype_new(arg0): + _wasm_memorytype_new = libiwasm.wasm_memorytype_new + _wasm_memorytype_new.restype = POINTER(wasm_memorytype_t) + _wasm_memorytype_new.argtypes = [POINTER(wasm_limits_t)] + return _wasm_memorytype_new(arg0) + +def wasm_memorytype_limits(arg0): + _wasm_memorytype_limits = libiwasm.wasm_memorytype_limits + _wasm_memorytype_limits.restype = POINTER(wasm_limits_t) + _wasm_memorytype_limits.argtypes = [POINTER(wasm_memorytype_t)] + return _wasm_memorytype_limits(arg0) + +class wasm_externtype_t(Structure): + pass + +def wasm_externtype_delete(arg0): + _wasm_externtype_delete = libiwasm.wasm_externtype_delete + _wasm_externtype_delete.restype = None + _wasm_externtype_delete.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_delete(arg0) + +class wasm_externtype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_externtype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_externtype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_externtype_vec_new_empty(arg0): + _wasm_externtype_vec_new_empty = libiwasm.wasm_externtype_vec_new_empty + _wasm_externtype_vec_new_empty.restype = None + _wasm_externtype_vec_new_empty.argtypes = [POINTER(wasm_externtype_vec_t)] + return _wasm_externtype_vec_new_empty(arg0) + +def wasm_externtype_vec_new_uninitialized(arg0,arg1): + _wasm_externtype_vec_new_uninitialized = libiwasm.wasm_externtype_vec_new_uninitialized + _wasm_externtype_vec_new_uninitialized.restype = None + _wasm_externtype_vec_new_uninitialized.argtypes = [POINTER(wasm_externtype_vec_t),c_size_t] + return _wasm_externtype_vec_new_uninitialized(arg0,arg1) + +def wasm_externtype_vec_new(arg0,arg1,arg2): + _wasm_externtype_vec_new = libiwasm.wasm_externtype_vec_new + _wasm_externtype_vec_new.restype = None + _wasm_externtype_vec_new.argtypes = [POINTER(wasm_externtype_vec_t),c_size_t,POINTER(POINTER(wasm_externtype_t))] + return _wasm_externtype_vec_new(arg0,arg1,arg2) + +def wasm_externtype_vec_copy(arg0,arg1): + _wasm_externtype_vec_copy = libiwasm.wasm_externtype_vec_copy + _wasm_externtype_vec_copy.restype = None + _wasm_externtype_vec_copy.argtypes = [POINTER(wasm_externtype_vec_t),POINTER(wasm_externtype_vec_t)] + return _wasm_externtype_vec_copy(arg0,arg1) + +def wasm_externtype_vec_delete(arg0): + _wasm_externtype_vec_delete = libiwasm.wasm_externtype_vec_delete + _wasm_externtype_vec_delete.restype = None + _wasm_externtype_vec_delete.argtypes = [POINTER(wasm_externtype_vec_t)] + return _wasm_externtype_vec_delete(arg0) + +def wasm_externtype_copy(arg0): + _wasm_externtype_copy = libiwasm.wasm_externtype_copy + _wasm_externtype_copy.restype = POINTER(wasm_externtype_t) + _wasm_externtype_copy.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_copy(arg0) + +wasm_externkind_t = c_uint8 + +WASM_EXTERN_FUNC = 0 +WASM_EXTERN_GLOBAL = 1 +WASM_EXTERN_TABLE = 2 +WASM_EXTERN_MEMORY = 3 + +def wasm_externtype_kind(arg0): + _wasm_externtype_kind = libiwasm.wasm_externtype_kind + _wasm_externtype_kind.restype = wasm_externkind_t + _wasm_externtype_kind.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_kind(arg0) + +def wasm_functype_as_externtype(arg0): + _wasm_functype_as_externtype = libiwasm.wasm_functype_as_externtype + _wasm_functype_as_externtype.restype = POINTER(wasm_externtype_t) + _wasm_functype_as_externtype.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_as_externtype(arg0) + +def wasm_globaltype_as_externtype(arg0): + _wasm_globaltype_as_externtype = libiwasm.wasm_globaltype_as_externtype + _wasm_globaltype_as_externtype.restype = POINTER(wasm_externtype_t) + _wasm_globaltype_as_externtype.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_as_externtype(arg0) + +def wasm_tabletype_as_externtype(arg0): + _wasm_tabletype_as_externtype = libiwasm.wasm_tabletype_as_externtype + _wasm_tabletype_as_externtype.restype = POINTER(wasm_externtype_t) + _wasm_tabletype_as_externtype.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_as_externtype(arg0) + +def wasm_memorytype_as_externtype(arg0): + _wasm_memorytype_as_externtype = libiwasm.wasm_memorytype_as_externtype + _wasm_memorytype_as_externtype.restype = POINTER(wasm_externtype_t) + _wasm_memorytype_as_externtype.argtypes = [POINTER(wasm_memorytype_t)] + return _wasm_memorytype_as_externtype(arg0) + +def wasm_externtype_as_functype(arg0): + _wasm_externtype_as_functype = libiwasm.wasm_externtype_as_functype + _wasm_externtype_as_functype.restype = POINTER(wasm_functype_t) + _wasm_externtype_as_functype.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_functype(arg0) + +def wasm_externtype_as_globaltype(arg0): + _wasm_externtype_as_globaltype = libiwasm.wasm_externtype_as_globaltype + _wasm_externtype_as_globaltype.restype = POINTER(wasm_globaltype_t) + _wasm_externtype_as_globaltype.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_globaltype(arg0) + +def wasm_externtype_as_tabletype(arg0): + _wasm_externtype_as_tabletype = libiwasm.wasm_externtype_as_tabletype + _wasm_externtype_as_tabletype.restype = POINTER(wasm_tabletype_t) + _wasm_externtype_as_tabletype.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_tabletype(arg0) + +def wasm_externtype_as_memorytype(arg0): + _wasm_externtype_as_memorytype = libiwasm.wasm_externtype_as_memorytype + _wasm_externtype_as_memorytype.restype = POINTER(wasm_memorytype_t) + _wasm_externtype_as_memorytype.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_memorytype(arg0) + +def wasm_functype_as_externtype_const(arg0): + _wasm_functype_as_externtype_const = libiwasm.wasm_functype_as_externtype_const + _wasm_functype_as_externtype_const.restype = POINTER(wasm_externtype_t) + _wasm_functype_as_externtype_const.argtypes = [POINTER(wasm_functype_t)] + return _wasm_functype_as_externtype_const(arg0) + +def wasm_globaltype_as_externtype_const(arg0): + _wasm_globaltype_as_externtype_const = libiwasm.wasm_globaltype_as_externtype_const + _wasm_globaltype_as_externtype_const.restype = POINTER(wasm_externtype_t) + _wasm_globaltype_as_externtype_const.argtypes = [POINTER(wasm_globaltype_t)] + return _wasm_globaltype_as_externtype_const(arg0) + +def wasm_tabletype_as_externtype_const(arg0): + _wasm_tabletype_as_externtype_const = libiwasm.wasm_tabletype_as_externtype_const + _wasm_tabletype_as_externtype_const.restype = POINTER(wasm_externtype_t) + _wasm_tabletype_as_externtype_const.argtypes = [POINTER(wasm_tabletype_t)] + return _wasm_tabletype_as_externtype_const(arg0) + +def wasm_memorytype_as_externtype_const(arg0): + _wasm_memorytype_as_externtype_const = libiwasm.wasm_memorytype_as_externtype_const + _wasm_memorytype_as_externtype_const.restype = POINTER(wasm_externtype_t) + _wasm_memorytype_as_externtype_const.argtypes = [POINTER(wasm_memorytype_t)] + return _wasm_memorytype_as_externtype_const(arg0) + +def wasm_externtype_as_functype_const(arg0): + _wasm_externtype_as_functype_const = libiwasm.wasm_externtype_as_functype_const + _wasm_externtype_as_functype_const.restype = POINTER(wasm_functype_t) + _wasm_externtype_as_functype_const.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_functype_const(arg0) + +def wasm_externtype_as_globaltype_const(arg0): + _wasm_externtype_as_globaltype_const = libiwasm.wasm_externtype_as_globaltype_const + _wasm_externtype_as_globaltype_const.restype = POINTER(wasm_globaltype_t) + _wasm_externtype_as_globaltype_const.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_globaltype_const(arg0) + +def wasm_externtype_as_tabletype_const(arg0): + _wasm_externtype_as_tabletype_const = libiwasm.wasm_externtype_as_tabletype_const + _wasm_externtype_as_tabletype_const.restype = POINTER(wasm_tabletype_t) + _wasm_externtype_as_tabletype_const.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_tabletype_const(arg0) + +def wasm_externtype_as_memorytype_const(arg0): + _wasm_externtype_as_memorytype_const = libiwasm.wasm_externtype_as_memorytype_const + _wasm_externtype_as_memorytype_const.restype = POINTER(wasm_memorytype_t) + _wasm_externtype_as_memorytype_const.argtypes = [POINTER(wasm_externtype_t)] + return _wasm_externtype_as_memorytype_const(arg0) + +class wasm_importtype_t(Structure): + pass + +def wasm_importtype_delete(arg0): + _wasm_importtype_delete = libiwasm.wasm_importtype_delete + _wasm_importtype_delete.restype = None + _wasm_importtype_delete.argtypes = [POINTER(wasm_importtype_t)] + return _wasm_importtype_delete(arg0) + +class wasm_importtype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_importtype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_importtype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_importtype_vec_new_empty(arg0): + _wasm_importtype_vec_new_empty = libiwasm.wasm_importtype_vec_new_empty + _wasm_importtype_vec_new_empty.restype = None + _wasm_importtype_vec_new_empty.argtypes = [POINTER(wasm_importtype_vec_t)] + return _wasm_importtype_vec_new_empty(arg0) + +def wasm_importtype_vec_new_uninitialized(arg0,arg1): + _wasm_importtype_vec_new_uninitialized = libiwasm.wasm_importtype_vec_new_uninitialized + _wasm_importtype_vec_new_uninitialized.restype = None + _wasm_importtype_vec_new_uninitialized.argtypes = [POINTER(wasm_importtype_vec_t),c_size_t] + return _wasm_importtype_vec_new_uninitialized(arg0,arg1) + +def wasm_importtype_vec_new(arg0,arg1,arg2): + _wasm_importtype_vec_new = libiwasm.wasm_importtype_vec_new + _wasm_importtype_vec_new.restype = None + _wasm_importtype_vec_new.argtypes = [POINTER(wasm_importtype_vec_t),c_size_t,POINTER(POINTER(wasm_importtype_t))] + return _wasm_importtype_vec_new(arg0,arg1,arg2) + +def wasm_importtype_vec_copy(arg0,arg1): + _wasm_importtype_vec_copy = libiwasm.wasm_importtype_vec_copy + _wasm_importtype_vec_copy.restype = None + _wasm_importtype_vec_copy.argtypes = [POINTER(wasm_importtype_vec_t),POINTER(wasm_importtype_vec_t)] + return _wasm_importtype_vec_copy(arg0,arg1) + +def wasm_importtype_vec_delete(arg0): + _wasm_importtype_vec_delete = libiwasm.wasm_importtype_vec_delete + _wasm_importtype_vec_delete.restype = None + _wasm_importtype_vec_delete.argtypes = [POINTER(wasm_importtype_vec_t)] + return _wasm_importtype_vec_delete(arg0) + +def wasm_importtype_copy(arg0): + _wasm_importtype_copy = libiwasm.wasm_importtype_copy + _wasm_importtype_copy.restype = POINTER(wasm_importtype_t) + _wasm_importtype_copy.argtypes = [POINTER(wasm_importtype_t)] + return _wasm_importtype_copy(arg0) + +def wasm_importtype_new(arg0,arg1,arg2): + _wasm_importtype_new = libiwasm.wasm_importtype_new + _wasm_importtype_new.restype = POINTER(wasm_importtype_t) + _wasm_importtype_new.argtypes = [POINTER(wasm_name_t),POINTER(wasm_name_t),POINTER(wasm_externtype_t)] + return _wasm_importtype_new(arg0,arg1,arg2) + +def wasm_importtype_module(arg0): + _wasm_importtype_module = libiwasm.wasm_importtype_module + _wasm_importtype_module.restype = POINTER(wasm_name_t) + _wasm_importtype_module.argtypes = [POINTER(wasm_importtype_t)] + return _wasm_importtype_module(arg0) + +def wasm_importtype_name(arg0): + _wasm_importtype_name = libiwasm.wasm_importtype_name + _wasm_importtype_name.restype = POINTER(wasm_name_t) + _wasm_importtype_name.argtypes = [POINTER(wasm_importtype_t)] + return _wasm_importtype_name(arg0) + +def wasm_importtype_type(arg0): + _wasm_importtype_type = libiwasm.wasm_importtype_type + _wasm_importtype_type.restype = POINTER(wasm_externtype_t) + _wasm_importtype_type.argtypes = [POINTER(wasm_importtype_t)] + return _wasm_importtype_type(arg0) + +class wasm_exporttype_t(Structure): + pass + +def wasm_exporttype_delete(arg0): + _wasm_exporttype_delete = libiwasm.wasm_exporttype_delete + _wasm_exporttype_delete.restype = None + _wasm_exporttype_delete.argtypes = [POINTER(wasm_exporttype_t)] + return _wasm_exporttype_delete(arg0) + +class wasm_exporttype_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_exporttype_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_exporttype_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_exporttype_vec_new_empty(arg0): + _wasm_exporttype_vec_new_empty = libiwasm.wasm_exporttype_vec_new_empty + _wasm_exporttype_vec_new_empty.restype = None + _wasm_exporttype_vec_new_empty.argtypes = [POINTER(wasm_exporttype_vec_t)] + return _wasm_exporttype_vec_new_empty(arg0) + +def wasm_exporttype_vec_new_uninitialized(arg0,arg1): + _wasm_exporttype_vec_new_uninitialized = libiwasm.wasm_exporttype_vec_new_uninitialized + _wasm_exporttype_vec_new_uninitialized.restype = None + _wasm_exporttype_vec_new_uninitialized.argtypes = [POINTER(wasm_exporttype_vec_t),c_size_t] + return _wasm_exporttype_vec_new_uninitialized(arg0,arg1) + +def wasm_exporttype_vec_new(arg0,arg1,arg2): + _wasm_exporttype_vec_new = libiwasm.wasm_exporttype_vec_new + _wasm_exporttype_vec_new.restype = None + _wasm_exporttype_vec_new.argtypes = [POINTER(wasm_exporttype_vec_t),c_size_t,POINTER(POINTER(wasm_exporttype_t))] + return _wasm_exporttype_vec_new(arg0,arg1,arg2) + +def wasm_exporttype_vec_copy(arg0,arg1): + _wasm_exporttype_vec_copy = libiwasm.wasm_exporttype_vec_copy + _wasm_exporttype_vec_copy.restype = None + _wasm_exporttype_vec_copy.argtypes = [POINTER(wasm_exporttype_vec_t),POINTER(wasm_exporttype_vec_t)] + return _wasm_exporttype_vec_copy(arg0,arg1) + +def wasm_exporttype_vec_delete(arg0): + _wasm_exporttype_vec_delete = libiwasm.wasm_exporttype_vec_delete + _wasm_exporttype_vec_delete.restype = None + _wasm_exporttype_vec_delete.argtypes = [POINTER(wasm_exporttype_vec_t)] + return _wasm_exporttype_vec_delete(arg0) + +def wasm_exporttype_copy(arg0): + _wasm_exporttype_copy = libiwasm.wasm_exporttype_copy + _wasm_exporttype_copy.restype = POINTER(wasm_exporttype_t) + _wasm_exporttype_copy.argtypes = [POINTER(wasm_exporttype_t)] + return _wasm_exporttype_copy(arg0) + +def wasm_exporttype_new(arg0,arg1): + _wasm_exporttype_new = libiwasm.wasm_exporttype_new + _wasm_exporttype_new.restype = POINTER(wasm_exporttype_t) + _wasm_exporttype_new.argtypes = [POINTER(wasm_name_t),POINTER(wasm_externtype_t)] + return _wasm_exporttype_new(arg0,arg1) + +def wasm_exporttype_name(arg0): + _wasm_exporttype_name = libiwasm.wasm_exporttype_name + _wasm_exporttype_name.restype = POINTER(wasm_name_t) + _wasm_exporttype_name.argtypes = [POINTER(wasm_exporttype_t)] + return _wasm_exporttype_name(arg0) + +def wasm_exporttype_type(arg0): + _wasm_exporttype_type = libiwasm.wasm_exporttype_type + _wasm_exporttype_type.restype = POINTER(wasm_externtype_t) + _wasm_exporttype_type.argtypes = [POINTER(wasm_exporttype_t)] + return _wasm_exporttype_type(arg0) + +def wasm_val_delete(arg0): + _wasm_val_delete = libiwasm.wasm_val_delete + _wasm_val_delete.restype = None + _wasm_val_delete.argtypes = [POINTER(wasm_val_t)] + return _wasm_val_delete(arg0) + +def wasm_val_copy(arg0,arg1): + _wasm_val_copy = libiwasm.wasm_val_copy + _wasm_val_copy.restype = None + _wasm_val_copy.argtypes = [POINTER(wasm_val_t),POINTER(wasm_val_t)] + return _wasm_val_copy(arg0,arg1) + +class wasm_val_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(wasm_val_t)), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_val_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(self.data[i]) + ret += " " + return ret + + + +def wasm_val_vec_new_empty(arg0): + _wasm_val_vec_new_empty = libiwasm.wasm_val_vec_new_empty + _wasm_val_vec_new_empty.restype = None + _wasm_val_vec_new_empty.argtypes = [POINTER(wasm_val_vec_t)] + return _wasm_val_vec_new_empty(arg0) + +def wasm_val_vec_new_uninitialized(arg0,arg1): + _wasm_val_vec_new_uninitialized = libiwasm.wasm_val_vec_new_uninitialized + _wasm_val_vec_new_uninitialized.restype = None + _wasm_val_vec_new_uninitialized.argtypes = [POINTER(wasm_val_vec_t),c_size_t] + return _wasm_val_vec_new_uninitialized(arg0,arg1) + +def wasm_val_vec_new(arg0,arg1,arg2): + _wasm_val_vec_new = libiwasm.wasm_val_vec_new + _wasm_val_vec_new.restype = None + _wasm_val_vec_new.argtypes = [POINTER(wasm_val_vec_t),c_size_t,POINTER(wasm_val_t)] + return _wasm_val_vec_new(arg0,arg1,arg2) + +def wasm_val_vec_copy(arg0,arg1): + _wasm_val_vec_copy = libiwasm.wasm_val_vec_copy + _wasm_val_vec_copy.restype = None + _wasm_val_vec_copy.argtypes = [POINTER(wasm_val_vec_t),POINTER(wasm_val_vec_t)] + return _wasm_val_vec_copy(arg0,arg1) + +def wasm_val_vec_delete(arg0): + _wasm_val_vec_delete = libiwasm.wasm_val_vec_delete + _wasm_val_vec_delete.restype = None + _wasm_val_vec_delete.argtypes = [POINTER(wasm_val_vec_t)] + return _wasm_val_vec_delete(arg0) + +def wasm_ref_delete(arg0): + _wasm_ref_delete = libiwasm.wasm_ref_delete + _wasm_ref_delete.restype = None + _wasm_ref_delete.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_delete(arg0) + +def wasm_ref_copy(arg0): + _wasm_ref_copy = libiwasm.wasm_ref_copy + _wasm_ref_copy.restype = POINTER(wasm_ref_t) + _wasm_ref_copy.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_copy(arg0) + +def wasm_ref_same(arg0,arg1): + _wasm_ref_same = libiwasm.wasm_ref_same + _wasm_ref_same.restype = c_bool + _wasm_ref_same.argtypes = [POINTER(wasm_ref_t),POINTER(wasm_ref_t)] + return _wasm_ref_same(arg0,arg1) + +def wasm_ref_get_host_info(arg0): + _wasm_ref_get_host_info = libiwasm.wasm_ref_get_host_info + _wasm_ref_get_host_info.restype = c_void_p + _wasm_ref_get_host_info.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_get_host_info(arg0) + +def wasm_ref_set_host_info(arg0,arg1): + _wasm_ref_set_host_info = libiwasm.wasm_ref_set_host_info + _wasm_ref_set_host_info.restype = None + _wasm_ref_set_host_info.argtypes = [POINTER(wasm_ref_t),c_void_p] + return _wasm_ref_set_host_info(arg0,arg1) + +def wasm_ref_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_ref_set_host_info_with_finalizer = libiwasm.wasm_ref_set_host_info_with_finalizer + _wasm_ref_set_host_info_with_finalizer.restype = None + _wasm_ref_set_host_info_with_finalizer.argtypes = [POINTER(wasm_ref_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_ref_set_host_info_with_finalizer(arg0,arg1,arg2) + +class wasm_frame_t(Structure): + pass + +def wasm_frame_delete(arg0): + _wasm_frame_delete = libiwasm.wasm_frame_delete + _wasm_frame_delete.restype = None + _wasm_frame_delete.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_delete(arg0) + +class wasm_frame_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_frame_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_frame_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_frame_vec_new_empty(arg0): + _wasm_frame_vec_new_empty = libiwasm.wasm_frame_vec_new_empty + _wasm_frame_vec_new_empty.restype = None + _wasm_frame_vec_new_empty.argtypes = [POINTER(wasm_frame_vec_t)] + return _wasm_frame_vec_new_empty(arg0) + +def wasm_frame_vec_new_uninitialized(arg0,arg1): + _wasm_frame_vec_new_uninitialized = libiwasm.wasm_frame_vec_new_uninitialized + _wasm_frame_vec_new_uninitialized.restype = None + _wasm_frame_vec_new_uninitialized.argtypes = [POINTER(wasm_frame_vec_t),c_size_t] + return _wasm_frame_vec_new_uninitialized(arg0,arg1) + +def wasm_frame_vec_new(arg0,arg1,arg2): + _wasm_frame_vec_new = libiwasm.wasm_frame_vec_new + _wasm_frame_vec_new.restype = None + _wasm_frame_vec_new.argtypes = [POINTER(wasm_frame_vec_t),c_size_t,POINTER(POINTER(wasm_frame_t))] + return _wasm_frame_vec_new(arg0,arg1,arg2) + +def wasm_frame_vec_copy(arg0,arg1): + _wasm_frame_vec_copy = libiwasm.wasm_frame_vec_copy + _wasm_frame_vec_copy.restype = None + _wasm_frame_vec_copy.argtypes = [POINTER(wasm_frame_vec_t),POINTER(wasm_frame_vec_t)] + return _wasm_frame_vec_copy(arg0,arg1) + +def wasm_frame_vec_delete(arg0): + _wasm_frame_vec_delete = libiwasm.wasm_frame_vec_delete + _wasm_frame_vec_delete.restype = None + _wasm_frame_vec_delete.argtypes = [POINTER(wasm_frame_vec_t)] + return _wasm_frame_vec_delete(arg0) + +def wasm_frame_copy(arg0): + _wasm_frame_copy = libiwasm.wasm_frame_copy + _wasm_frame_copy.restype = POINTER(wasm_frame_t) + _wasm_frame_copy.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_copy(arg0) + +def wasm_frame_instance(arg0): + _wasm_frame_instance = libiwasm.wasm_frame_instance + _wasm_frame_instance.restype = POINTER(wasm_instance_t) + _wasm_frame_instance.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_instance(arg0) + +def wasm_frame_func_index(arg0): + _wasm_frame_func_index = libiwasm.wasm_frame_func_index + _wasm_frame_func_index.restype = c_uint32 + _wasm_frame_func_index.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_func_index(arg0) + +def wasm_frame_func_offset(arg0): + _wasm_frame_func_offset = libiwasm.wasm_frame_func_offset + _wasm_frame_func_offset.restype = c_size_t + _wasm_frame_func_offset.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_func_offset(arg0) + +def wasm_frame_module_offset(arg0): + _wasm_frame_module_offset = libiwasm.wasm_frame_module_offset + _wasm_frame_module_offset.restype = c_size_t + _wasm_frame_module_offset.argtypes = [POINTER(wasm_frame_t)] + return _wasm_frame_module_offset(arg0) + +wasm_message_t = wasm_name_t + +class wasm_trap_t(Structure): + pass + +def wasm_trap_delete(arg0): + _wasm_trap_delete = libiwasm.wasm_trap_delete + _wasm_trap_delete.restype = None + _wasm_trap_delete.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_delete(arg0) + +def wasm_trap_copy(arg0): + _wasm_trap_copy = libiwasm.wasm_trap_copy + _wasm_trap_copy.restype = POINTER(wasm_trap_t) + _wasm_trap_copy.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_copy(arg0) + +def wasm_trap_same(arg0,arg1): + _wasm_trap_same = libiwasm.wasm_trap_same + _wasm_trap_same.restype = c_bool + _wasm_trap_same.argtypes = [POINTER(wasm_trap_t),POINTER(wasm_trap_t)] + return _wasm_trap_same(arg0,arg1) + +def wasm_trap_get_host_info(arg0): + _wasm_trap_get_host_info = libiwasm.wasm_trap_get_host_info + _wasm_trap_get_host_info.restype = c_void_p + _wasm_trap_get_host_info.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_get_host_info(arg0) + +def wasm_trap_set_host_info(arg0,arg1): + _wasm_trap_set_host_info = libiwasm.wasm_trap_set_host_info + _wasm_trap_set_host_info.restype = None + _wasm_trap_set_host_info.argtypes = [POINTER(wasm_trap_t),c_void_p] + return _wasm_trap_set_host_info(arg0,arg1) + +def wasm_trap_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_trap_set_host_info_with_finalizer = libiwasm.wasm_trap_set_host_info_with_finalizer + _wasm_trap_set_host_info_with_finalizer.restype = None + _wasm_trap_set_host_info_with_finalizer.argtypes = [POINTER(wasm_trap_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_trap_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_trap_as_ref(arg0): + _wasm_trap_as_ref = libiwasm.wasm_trap_as_ref + _wasm_trap_as_ref.restype = POINTER(wasm_ref_t) + _wasm_trap_as_ref.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_as_ref(arg0) + +def wasm_ref_as_trap(arg0): + _wasm_ref_as_trap = libiwasm.wasm_ref_as_trap + _wasm_ref_as_trap.restype = POINTER(wasm_trap_t) + _wasm_ref_as_trap.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_trap(arg0) + +def wasm_trap_as_ref_const(arg0): + _wasm_trap_as_ref_const = libiwasm.wasm_trap_as_ref_const + _wasm_trap_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_trap_as_ref_const.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_as_ref_const(arg0) + +def wasm_ref_as_trap_const(arg0): + _wasm_ref_as_trap_const = libiwasm.wasm_ref_as_trap_const + _wasm_ref_as_trap_const.restype = POINTER(wasm_trap_t) + _wasm_ref_as_trap_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_trap_const(arg0) + +def wasm_trap_new(arg0,arg1): + _wasm_trap_new = libiwasm.wasm_trap_new + _wasm_trap_new.restype = POINTER(wasm_trap_t) + _wasm_trap_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_message_t)] + return _wasm_trap_new(arg0,arg1) + +def wasm_trap_message(arg0,arg1): + _wasm_trap_message = libiwasm.wasm_trap_message + _wasm_trap_message.restype = None + _wasm_trap_message.argtypes = [POINTER(wasm_trap_t),POINTER(wasm_message_t)] + return _wasm_trap_message(arg0,arg1) + +def wasm_trap_origin(arg0): + _wasm_trap_origin = libiwasm.wasm_trap_origin + _wasm_trap_origin.restype = POINTER(wasm_frame_t) + _wasm_trap_origin.argtypes = [POINTER(wasm_trap_t)] + return _wasm_trap_origin(arg0) + +def wasm_trap_trace(arg0,arg1): + _wasm_trap_trace = libiwasm.wasm_trap_trace + _wasm_trap_trace.restype = None + _wasm_trap_trace.argtypes = [POINTER(wasm_trap_t),POINTER(wasm_frame_vec_t)] + return _wasm_trap_trace(arg0,arg1) + +class wasm_foreign_t(Structure): + pass + +def wasm_foreign_delete(arg0): + _wasm_foreign_delete = libiwasm.wasm_foreign_delete + _wasm_foreign_delete.restype = None + _wasm_foreign_delete.argtypes = [POINTER(wasm_foreign_t)] + return _wasm_foreign_delete(arg0) + +def wasm_foreign_copy(arg0): + _wasm_foreign_copy = libiwasm.wasm_foreign_copy + _wasm_foreign_copy.restype = POINTER(wasm_foreign_t) + _wasm_foreign_copy.argtypes = [POINTER(wasm_foreign_t)] + return _wasm_foreign_copy(arg0) + +def wasm_foreign_same(arg0,arg1): + _wasm_foreign_same = libiwasm.wasm_foreign_same + _wasm_foreign_same.restype = c_bool + _wasm_foreign_same.argtypes = [POINTER(wasm_foreign_t),POINTER(wasm_foreign_t)] + return _wasm_foreign_same(arg0,arg1) + +def wasm_foreign_get_host_info(arg0): + _wasm_foreign_get_host_info = libiwasm.wasm_foreign_get_host_info + _wasm_foreign_get_host_info.restype = c_void_p + _wasm_foreign_get_host_info.argtypes = [POINTER(wasm_foreign_t)] + return _wasm_foreign_get_host_info(arg0) + +def wasm_foreign_set_host_info(arg0,arg1): + _wasm_foreign_set_host_info = libiwasm.wasm_foreign_set_host_info + _wasm_foreign_set_host_info.restype = None + _wasm_foreign_set_host_info.argtypes = [POINTER(wasm_foreign_t),c_void_p] + return _wasm_foreign_set_host_info(arg0,arg1) + +def wasm_foreign_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_foreign_set_host_info_with_finalizer = libiwasm.wasm_foreign_set_host_info_with_finalizer + _wasm_foreign_set_host_info_with_finalizer.restype = None + _wasm_foreign_set_host_info_with_finalizer.argtypes = [POINTER(wasm_foreign_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_foreign_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_foreign_as_ref(arg0): + _wasm_foreign_as_ref = libiwasm.wasm_foreign_as_ref + _wasm_foreign_as_ref.restype = POINTER(wasm_ref_t) + _wasm_foreign_as_ref.argtypes = [POINTER(wasm_foreign_t)] + return _wasm_foreign_as_ref(arg0) + +def wasm_ref_as_foreign(arg0): + _wasm_ref_as_foreign = libiwasm.wasm_ref_as_foreign + _wasm_ref_as_foreign.restype = POINTER(wasm_foreign_t) + _wasm_ref_as_foreign.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_foreign(arg0) + +def wasm_foreign_as_ref_const(arg0): + _wasm_foreign_as_ref_const = libiwasm.wasm_foreign_as_ref_const + _wasm_foreign_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_foreign_as_ref_const.argtypes = [POINTER(wasm_foreign_t)] + return _wasm_foreign_as_ref_const(arg0) + +def wasm_ref_as_foreign_const(arg0): + _wasm_ref_as_foreign_const = libiwasm.wasm_ref_as_foreign_const + _wasm_ref_as_foreign_const.restype = POINTER(wasm_foreign_t) + _wasm_ref_as_foreign_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_foreign_const(arg0) + +def wasm_foreign_new(arg0): + _wasm_foreign_new = libiwasm.wasm_foreign_new + _wasm_foreign_new.restype = POINTER(wasm_foreign_t) + _wasm_foreign_new.argtypes = [POINTER(wasm_store_t)] + return _wasm_foreign_new(arg0) + +class WASMModuleCommon(Structure): + pass + +class WASMModuleCommon(Structure): + pass + +wasm_module_t = POINTER(WASMModuleCommon) + +def wasm_module_new(arg0,arg1): + _wasm_module_new = libiwasm.wasm_module_new + _wasm_module_new.restype = POINTER(wasm_module_t) + _wasm_module_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_byte_vec_t)] + return _wasm_module_new(arg0,arg1) + +def wasm_module_delete(arg0): + _wasm_module_delete = libiwasm.wasm_module_delete + _wasm_module_delete.restype = None + _wasm_module_delete.argtypes = [POINTER(wasm_module_t)] + return _wasm_module_delete(arg0) + +def wasm_module_validate(arg0,arg1): + _wasm_module_validate = libiwasm.wasm_module_validate + _wasm_module_validate.restype = c_bool + _wasm_module_validate.argtypes = [POINTER(wasm_store_t),POINTER(wasm_byte_vec_t)] + return _wasm_module_validate(arg0,arg1) + +def wasm_module_imports(arg0,arg1): + _wasm_module_imports = libiwasm.wasm_module_imports + _wasm_module_imports.restype = None + _wasm_module_imports.argtypes = [POINTER(wasm_module_t),POINTER(wasm_importtype_vec_t)] + return _wasm_module_imports(arg0,arg1) + +def wasm_module_exports(arg0,arg1): + _wasm_module_exports = libiwasm.wasm_module_exports + _wasm_module_exports.restype = None + _wasm_module_exports.argtypes = [POINTER(wasm_module_t),POINTER(wasm_exporttype_vec_t)] + return _wasm_module_exports(arg0,arg1) + +def wasm_module_serialize(arg0,arg1): + _wasm_module_serialize = libiwasm.wasm_module_serialize + _wasm_module_serialize.restype = None + _wasm_module_serialize.argtypes = [POINTER(wasm_module_t),POINTER(wasm_byte_vec_t)] + return _wasm_module_serialize(arg0,arg1) + +def wasm_module_deserialize(arg0,arg1): + _wasm_module_deserialize = libiwasm.wasm_module_deserialize + _wasm_module_deserialize.restype = POINTER(wasm_module_t) + _wasm_module_deserialize.argtypes = [POINTER(wasm_store_t),POINTER(wasm_byte_vec_t)] + return _wasm_module_deserialize(arg0,arg1) + +class wasm_func_t(Structure): + pass + +def wasm_func_delete(arg0): + _wasm_func_delete = libiwasm.wasm_func_delete + _wasm_func_delete.restype = None + _wasm_func_delete.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_delete(arg0) + +def wasm_func_copy(arg0): + _wasm_func_copy = libiwasm.wasm_func_copy + _wasm_func_copy.restype = POINTER(wasm_func_t) + _wasm_func_copy.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_copy(arg0) + +def wasm_func_same(arg0,arg1): + _wasm_func_same = libiwasm.wasm_func_same + _wasm_func_same.restype = c_bool + _wasm_func_same.argtypes = [POINTER(wasm_func_t),POINTER(wasm_func_t)] + return _wasm_func_same(arg0,arg1) + +def wasm_func_get_host_info(arg0): + _wasm_func_get_host_info = libiwasm.wasm_func_get_host_info + _wasm_func_get_host_info.restype = c_void_p + _wasm_func_get_host_info.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_get_host_info(arg0) + +def wasm_func_set_host_info(arg0,arg1): + _wasm_func_set_host_info = libiwasm.wasm_func_set_host_info + _wasm_func_set_host_info.restype = None + _wasm_func_set_host_info.argtypes = [POINTER(wasm_func_t),c_void_p] + return _wasm_func_set_host_info(arg0,arg1) + +def wasm_func_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_func_set_host_info_with_finalizer = libiwasm.wasm_func_set_host_info_with_finalizer + _wasm_func_set_host_info_with_finalizer.restype = None + _wasm_func_set_host_info_with_finalizer.argtypes = [POINTER(wasm_func_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_func_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_func_as_ref(arg0): + _wasm_func_as_ref = libiwasm.wasm_func_as_ref + _wasm_func_as_ref.restype = POINTER(wasm_ref_t) + _wasm_func_as_ref.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_as_ref(arg0) + +def wasm_ref_as_func(arg0): + _wasm_ref_as_func = libiwasm.wasm_ref_as_func + _wasm_ref_as_func.restype = POINTER(wasm_func_t) + _wasm_ref_as_func.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_func(arg0) + +def wasm_func_as_ref_const(arg0): + _wasm_func_as_ref_const = libiwasm.wasm_func_as_ref_const + _wasm_func_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_func_as_ref_const.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_as_ref_const(arg0) + +def wasm_ref_as_func_const(arg0): + _wasm_ref_as_func_const = libiwasm.wasm_ref_as_func_const + _wasm_ref_as_func_const.restype = POINTER(wasm_func_t) + _wasm_ref_as_func_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_func_const(arg0) + +wasm_func_callback_t = CFUNCTYPE(c_void_p,POINTER(wasm_val_vec_t),POINTER(wasm_val_vec_t)) + +wasm_func_callback_with_env_t = CFUNCTYPE(c_void_p,c_void_p,POINTER(wasm_val_vec_t),POINTER(wasm_val_vec_t)) + +def wasm_func_new(arg0,arg1,arg2): + _wasm_func_new = libiwasm.wasm_func_new + _wasm_func_new.restype = POINTER(wasm_func_t) + _wasm_func_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_functype_t),wasm_func_callback_t] + return _wasm_func_new(arg0,arg1,arg2) + +def wasm_func_new_with_env(arg0,arg1,arg2,arg3,arg4): + _wasm_func_new_with_env = libiwasm.wasm_func_new_with_env + _wasm_func_new_with_env.restype = POINTER(wasm_func_t) + _wasm_func_new_with_env.argtypes = [POINTER(wasm_store_t),POINTER(wasm_functype_t),wasm_func_callback_with_env_t,c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_func_new_with_env(arg0,arg1,arg2,arg3,arg4) + +def wasm_func_type(arg0): + _wasm_func_type = libiwasm.wasm_func_type + _wasm_func_type.restype = POINTER(wasm_functype_t) + _wasm_func_type.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_type(arg0) + +def wasm_func_param_arity(arg0): + _wasm_func_param_arity = libiwasm.wasm_func_param_arity + _wasm_func_param_arity.restype = c_size_t + _wasm_func_param_arity.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_param_arity(arg0) + +def wasm_func_result_arity(arg0): + _wasm_func_result_arity = libiwasm.wasm_func_result_arity + _wasm_func_result_arity.restype = c_size_t + _wasm_func_result_arity.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_result_arity(arg0) + +def wasm_func_call(arg0,arg1,arg2): + _wasm_func_call = libiwasm.wasm_func_call + _wasm_func_call.restype = POINTER(wasm_trap_t) + _wasm_func_call.argtypes = [POINTER(wasm_func_t),POINTER(wasm_val_vec_t),POINTER(wasm_val_vec_t)] + return _wasm_func_call(arg0,arg1,arg2) + +class wasm_global_t(Structure): + pass + +def wasm_global_delete(arg0): + _wasm_global_delete = libiwasm.wasm_global_delete + _wasm_global_delete.restype = None + _wasm_global_delete.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_delete(arg0) + +def wasm_global_copy(arg0): + _wasm_global_copy = libiwasm.wasm_global_copy + _wasm_global_copy.restype = POINTER(wasm_global_t) + _wasm_global_copy.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_copy(arg0) + +def wasm_global_same(arg0,arg1): + _wasm_global_same = libiwasm.wasm_global_same + _wasm_global_same.restype = c_bool + _wasm_global_same.argtypes = [POINTER(wasm_global_t),POINTER(wasm_global_t)] + return _wasm_global_same(arg0,arg1) + +def wasm_global_get_host_info(arg0): + _wasm_global_get_host_info = libiwasm.wasm_global_get_host_info + _wasm_global_get_host_info.restype = c_void_p + _wasm_global_get_host_info.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_get_host_info(arg0) + +def wasm_global_set_host_info(arg0,arg1): + _wasm_global_set_host_info = libiwasm.wasm_global_set_host_info + _wasm_global_set_host_info.restype = None + _wasm_global_set_host_info.argtypes = [POINTER(wasm_global_t),c_void_p] + return _wasm_global_set_host_info(arg0,arg1) + +def wasm_global_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_global_set_host_info_with_finalizer = libiwasm.wasm_global_set_host_info_with_finalizer + _wasm_global_set_host_info_with_finalizer.restype = None + _wasm_global_set_host_info_with_finalizer.argtypes = [POINTER(wasm_global_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_global_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_global_as_ref(arg0): + _wasm_global_as_ref = libiwasm.wasm_global_as_ref + _wasm_global_as_ref.restype = POINTER(wasm_ref_t) + _wasm_global_as_ref.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_as_ref(arg0) + +def wasm_ref_as_global(arg0): + _wasm_ref_as_global = libiwasm.wasm_ref_as_global + _wasm_ref_as_global.restype = POINTER(wasm_global_t) + _wasm_ref_as_global.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_global(arg0) + +def wasm_global_as_ref_const(arg0): + _wasm_global_as_ref_const = libiwasm.wasm_global_as_ref_const + _wasm_global_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_global_as_ref_const.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_as_ref_const(arg0) + +def wasm_ref_as_global_const(arg0): + _wasm_ref_as_global_const = libiwasm.wasm_ref_as_global_const + _wasm_ref_as_global_const.restype = POINTER(wasm_global_t) + _wasm_ref_as_global_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_global_const(arg0) + +def wasm_global_new(arg0,arg1,arg2): + _wasm_global_new = libiwasm.wasm_global_new + _wasm_global_new.restype = POINTER(wasm_global_t) + _wasm_global_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_globaltype_t),POINTER(wasm_val_t)] + return _wasm_global_new(arg0,arg1,arg2) + +def wasm_global_type(arg0): + _wasm_global_type = libiwasm.wasm_global_type + _wasm_global_type.restype = POINTER(wasm_globaltype_t) + _wasm_global_type.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_type(arg0) + +def wasm_global_get(arg0,arg1): + _wasm_global_get = libiwasm.wasm_global_get + _wasm_global_get.restype = None + _wasm_global_get.argtypes = [POINTER(wasm_global_t),POINTER(wasm_val_t)] + return _wasm_global_get(arg0,arg1) + +def wasm_global_set(arg0,arg1): + _wasm_global_set = libiwasm.wasm_global_set + _wasm_global_set.restype = None + _wasm_global_set.argtypes = [POINTER(wasm_global_t),POINTER(wasm_val_t)] + return _wasm_global_set(arg0,arg1) + +class wasm_table_t(Structure): + pass + +def wasm_table_delete(arg0): + _wasm_table_delete = libiwasm.wasm_table_delete + _wasm_table_delete.restype = None + _wasm_table_delete.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_delete(arg0) + +def wasm_table_copy(arg0): + _wasm_table_copy = libiwasm.wasm_table_copy + _wasm_table_copy.restype = POINTER(wasm_table_t) + _wasm_table_copy.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_copy(arg0) + +def wasm_table_same(arg0,arg1): + _wasm_table_same = libiwasm.wasm_table_same + _wasm_table_same.restype = c_bool + _wasm_table_same.argtypes = [POINTER(wasm_table_t),POINTER(wasm_table_t)] + return _wasm_table_same(arg0,arg1) + +def wasm_table_get_host_info(arg0): + _wasm_table_get_host_info = libiwasm.wasm_table_get_host_info + _wasm_table_get_host_info.restype = c_void_p + _wasm_table_get_host_info.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_get_host_info(arg0) + +def wasm_table_set_host_info(arg0,arg1): + _wasm_table_set_host_info = libiwasm.wasm_table_set_host_info + _wasm_table_set_host_info.restype = None + _wasm_table_set_host_info.argtypes = [POINTER(wasm_table_t),c_void_p] + return _wasm_table_set_host_info(arg0,arg1) + +def wasm_table_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_table_set_host_info_with_finalizer = libiwasm.wasm_table_set_host_info_with_finalizer + _wasm_table_set_host_info_with_finalizer.restype = None + _wasm_table_set_host_info_with_finalizer.argtypes = [POINTER(wasm_table_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_table_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_table_as_ref(arg0): + _wasm_table_as_ref = libiwasm.wasm_table_as_ref + _wasm_table_as_ref.restype = POINTER(wasm_ref_t) + _wasm_table_as_ref.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_as_ref(arg0) + +def wasm_ref_as_table(arg0): + _wasm_ref_as_table = libiwasm.wasm_ref_as_table + _wasm_ref_as_table.restype = POINTER(wasm_table_t) + _wasm_ref_as_table.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_table(arg0) + +def wasm_table_as_ref_const(arg0): + _wasm_table_as_ref_const = libiwasm.wasm_table_as_ref_const + _wasm_table_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_table_as_ref_const.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_as_ref_const(arg0) + +def wasm_ref_as_table_const(arg0): + _wasm_ref_as_table_const = libiwasm.wasm_ref_as_table_const + _wasm_ref_as_table_const.restype = POINTER(wasm_table_t) + _wasm_ref_as_table_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_table_const(arg0) + +wasm_table_size_t = c_uint32 + +def wasm_table_new(arg0,arg1,arg2): + _wasm_table_new = libiwasm.wasm_table_new + _wasm_table_new.restype = POINTER(wasm_table_t) + _wasm_table_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_tabletype_t),POINTER(wasm_ref_t)] + return _wasm_table_new(arg0,arg1,arg2) + +def wasm_table_type(arg0): + _wasm_table_type = libiwasm.wasm_table_type + _wasm_table_type.restype = POINTER(wasm_tabletype_t) + _wasm_table_type.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_type(arg0) + +def wasm_table_get(arg0,arg1): + _wasm_table_get = libiwasm.wasm_table_get + _wasm_table_get.restype = POINTER(wasm_ref_t) + _wasm_table_get.argtypes = [POINTER(wasm_table_t),wasm_table_size_t] + return _wasm_table_get(arg0,arg1) + +def wasm_table_set(arg0,arg1,arg2): + _wasm_table_set = libiwasm.wasm_table_set + _wasm_table_set.restype = c_bool + _wasm_table_set.argtypes = [POINTER(wasm_table_t),wasm_table_size_t,POINTER(wasm_ref_t)] + return _wasm_table_set(arg0,arg1,arg2) + +def wasm_table_size(arg0): + _wasm_table_size = libiwasm.wasm_table_size + _wasm_table_size.restype = wasm_table_size_t + _wasm_table_size.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_size(arg0) + +def wasm_table_grow(arg0,arg1,arg2): + _wasm_table_grow = libiwasm.wasm_table_grow + _wasm_table_grow.restype = c_bool + _wasm_table_grow.argtypes = [POINTER(wasm_table_t),wasm_table_size_t,POINTER(wasm_ref_t)] + return _wasm_table_grow(arg0,arg1,arg2) + +class wasm_memory_t(Structure): + pass + +def wasm_memory_delete(arg0): + _wasm_memory_delete = libiwasm.wasm_memory_delete + _wasm_memory_delete.restype = None + _wasm_memory_delete.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_delete(arg0) + +def wasm_memory_copy(arg0): + _wasm_memory_copy = libiwasm.wasm_memory_copy + _wasm_memory_copy.restype = POINTER(wasm_memory_t) + _wasm_memory_copy.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_copy(arg0) + +def wasm_memory_same(arg0,arg1): + _wasm_memory_same = libiwasm.wasm_memory_same + _wasm_memory_same.restype = c_bool + _wasm_memory_same.argtypes = [POINTER(wasm_memory_t),POINTER(wasm_memory_t)] + return _wasm_memory_same(arg0,arg1) + +def wasm_memory_get_host_info(arg0): + _wasm_memory_get_host_info = libiwasm.wasm_memory_get_host_info + _wasm_memory_get_host_info.restype = c_void_p + _wasm_memory_get_host_info.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_get_host_info(arg0) + +def wasm_memory_set_host_info(arg0,arg1): + _wasm_memory_set_host_info = libiwasm.wasm_memory_set_host_info + _wasm_memory_set_host_info.restype = None + _wasm_memory_set_host_info.argtypes = [POINTER(wasm_memory_t),c_void_p] + return _wasm_memory_set_host_info(arg0,arg1) + +def wasm_memory_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_memory_set_host_info_with_finalizer = libiwasm.wasm_memory_set_host_info_with_finalizer + _wasm_memory_set_host_info_with_finalizer.restype = None + _wasm_memory_set_host_info_with_finalizer.argtypes = [POINTER(wasm_memory_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_memory_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_memory_as_ref(arg0): + _wasm_memory_as_ref = libiwasm.wasm_memory_as_ref + _wasm_memory_as_ref.restype = POINTER(wasm_ref_t) + _wasm_memory_as_ref.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_as_ref(arg0) + +def wasm_ref_as_memory(arg0): + _wasm_ref_as_memory = libiwasm.wasm_ref_as_memory + _wasm_ref_as_memory.restype = POINTER(wasm_memory_t) + _wasm_ref_as_memory.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_memory(arg0) + +def wasm_memory_as_ref_const(arg0): + _wasm_memory_as_ref_const = libiwasm.wasm_memory_as_ref_const + _wasm_memory_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_memory_as_ref_const.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_as_ref_const(arg0) + +def wasm_ref_as_memory_const(arg0): + _wasm_ref_as_memory_const = libiwasm.wasm_ref_as_memory_const + _wasm_ref_as_memory_const.restype = POINTER(wasm_memory_t) + _wasm_ref_as_memory_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_memory_const(arg0) + +wasm_memory_pages_t = c_uint32 + +def wasm_memory_new(arg0,arg1): + _wasm_memory_new = libiwasm.wasm_memory_new + _wasm_memory_new.restype = POINTER(wasm_memory_t) + _wasm_memory_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_memorytype_t)] + return _wasm_memory_new(arg0,arg1) + +def wasm_memory_type(arg0): + _wasm_memory_type = libiwasm.wasm_memory_type + _wasm_memory_type.restype = POINTER(wasm_memorytype_t) + _wasm_memory_type.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_type(arg0) + +def wasm_memory_data(arg0): + _wasm_memory_data = libiwasm.wasm_memory_data + _wasm_memory_data.restype = POINTER(c_ubyte) + _wasm_memory_data.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_data(arg0) + +def wasm_memory_data_size(arg0): + _wasm_memory_data_size = libiwasm.wasm_memory_data_size + _wasm_memory_data_size.restype = c_size_t + _wasm_memory_data_size.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_data_size(arg0) + +def wasm_memory_size(arg0): + _wasm_memory_size = libiwasm.wasm_memory_size + _wasm_memory_size.restype = wasm_memory_pages_t + _wasm_memory_size.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_size(arg0) + +def wasm_memory_grow(arg0,arg1): + _wasm_memory_grow = libiwasm.wasm_memory_grow + _wasm_memory_grow.restype = c_bool + _wasm_memory_grow.argtypes = [POINTER(wasm_memory_t),wasm_memory_pages_t] + return _wasm_memory_grow(arg0,arg1) + +class wasm_extern_t(Structure): + pass + +def wasm_extern_delete(arg0): + _wasm_extern_delete = libiwasm.wasm_extern_delete + _wasm_extern_delete.restype = None + _wasm_extern_delete.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_delete(arg0) + +def wasm_extern_copy(arg0): + _wasm_extern_copy = libiwasm.wasm_extern_copy + _wasm_extern_copy.restype = POINTER(wasm_extern_t) + _wasm_extern_copy.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_copy(arg0) + +def wasm_extern_same(arg0,arg1): + _wasm_extern_same = libiwasm.wasm_extern_same + _wasm_extern_same.restype = c_bool + _wasm_extern_same.argtypes = [POINTER(wasm_extern_t),POINTER(wasm_extern_t)] + return _wasm_extern_same(arg0,arg1) + +def wasm_extern_get_host_info(arg0): + _wasm_extern_get_host_info = libiwasm.wasm_extern_get_host_info + _wasm_extern_get_host_info.restype = c_void_p + _wasm_extern_get_host_info.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_get_host_info(arg0) + +def wasm_extern_set_host_info(arg0,arg1): + _wasm_extern_set_host_info = libiwasm.wasm_extern_set_host_info + _wasm_extern_set_host_info.restype = None + _wasm_extern_set_host_info.argtypes = [POINTER(wasm_extern_t),c_void_p] + return _wasm_extern_set_host_info(arg0,arg1) + +def wasm_extern_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_extern_set_host_info_with_finalizer = libiwasm.wasm_extern_set_host_info_with_finalizer + _wasm_extern_set_host_info_with_finalizer.restype = None + _wasm_extern_set_host_info_with_finalizer.argtypes = [POINTER(wasm_extern_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_extern_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_extern_as_ref(arg0): + _wasm_extern_as_ref = libiwasm.wasm_extern_as_ref + _wasm_extern_as_ref.restype = POINTER(wasm_ref_t) + _wasm_extern_as_ref.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_ref(arg0) + +def wasm_ref_as_extern(arg0): + _wasm_ref_as_extern = libiwasm.wasm_ref_as_extern + _wasm_ref_as_extern.restype = POINTER(wasm_extern_t) + _wasm_ref_as_extern.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_extern(arg0) + +def wasm_extern_as_ref_const(arg0): + _wasm_extern_as_ref_const = libiwasm.wasm_extern_as_ref_const + _wasm_extern_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_extern_as_ref_const.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_ref_const(arg0) + +def wasm_ref_as_extern_const(arg0): + _wasm_ref_as_extern_const = libiwasm.wasm_ref_as_extern_const + _wasm_ref_as_extern_const.restype = POINTER(wasm_extern_t) + _wasm_ref_as_extern_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_extern_const(arg0) + +class wasm_extern_vec_t(Structure): + _fields_ = [ + ("size", c_size_t), + ("data", POINTER(POINTER(wasm_extern_t))), + ("num_elems", c_size_t), + ("size_of_elem", c_size_t), + ("lock", c_void_p), + ] + + def __eq__(self, other): + if not isinstance(other, wasm_extern_vec_t): + return False + return self.size == other.size and self.num_elems == other.num_elems and self.size_of_elem == other.size_of_elem + + def __repr__(self): + ret = "" + for i in range(self.num_elems): + ret += str(dereference(self.data[i])) + ret += " " + return ret + + + +def wasm_extern_vec_new_empty(arg0): + _wasm_extern_vec_new_empty = libiwasm.wasm_extern_vec_new_empty + _wasm_extern_vec_new_empty.restype = None + _wasm_extern_vec_new_empty.argtypes = [POINTER(wasm_extern_vec_t)] + return _wasm_extern_vec_new_empty(arg0) + +def wasm_extern_vec_new_uninitialized(arg0,arg1): + _wasm_extern_vec_new_uninitialized = libiwasm.wasm_extern_vec_new_uninitialized + _wasm_extern_vec_new_uninitialized.restype = None + _wasm_extern_vec_new_uninitialized.argtypes = [POINTER(wasm_extern_vec_t),c_size_t] + return _wasm_extern_vec_new_uninitialized(arg0,arg1) + +def wasm_extern_vec_new(arg0,arg1,arg2): + _wasm_extern_vec_new = libiwasm.wasm_extern_vec_new + _wasm_extern_vec_new.restype = None + _wasm_extern_vec_new.argtypes = [POINTER(wasm_extern_vec_t),c_size_t,POINTER(POINTER(wasm_extern_t))] + return _wasm_extern_vec_new(arg0,arg1,arg2) + +def wasm_extern_vec_copy(arg0,arg1): + _wasm_extern_vec_copy = libiwasm.wasm_extern_vec_copy + _wasm_extern_vec_copy.restype = None + _wasm_extern_vec_copy.argtypes = [POINTER(wasm_extern_vec_t),POINTER(wasm_extern_vec_t)] + return _wasm_extern_vec_copy(arg0,arg1) + +def wasm_extern_vec_delete(arg0): + _wasm_extern_vec_delete = libiwasm.wasm_extern_vec_delete + _wasm_extern_vec_delete.restype = None + _wasm_extern_vec_delete.argtypes = [POINTER(wasm_extern_vec_t)] + return _wasm_extern_vec_delete(arg0) + +def wasm_extern_kind(arg0): + _wasm_extern_kind = libiwasm.wasm_extern_kind + _wasm_extern_kind.restype = wasm_externkind_t + _wasm_extern_kind.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_kind(arg0) + +def wasm_extern_type(arg0): + _wasm_extern_type = libiwasm.wasm_extern_type + _wasm_extern_type.restype = POINTER(wasm_externtype_t) + _wasm_extern_type.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_type(arg0) + +def wasm_func_as_extern(arg0): + _wasm_func_as_extern = libiwasm.wasm_func_as_extern + _wasm_func_as_extern.restype = POINTER(wasm_extern_t) + _wasm_func_as_extern.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_as_extern(arg0) + +def wasm_global_as_extern(arg0): + _wasm_global_as_extern = libiwasm.wasm_global_as_extern + _wasm_global_as_extern.restype = POINTER(wasm_extern_t) + _wasm_global_as_extern.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_as_extern(arg0) + +def wasm_table_as_extern(arg0): + _wasm_table_as_extern = libiwasm.wasm_table_as_extern + _wasm_table_as_extern.restype = POINTER(wasm_extern_t) + _wasm_table_as_extern.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_as_extern(arg0) + +def wasm_memory_as_extern(arg0): + _wasm_memory_as_extern = libiwasm.wasm_memory_as_extern + _wasm_memory_as_extern.restype = POINTER(wasm_extern_t) + _wasm_memory_as_extern.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_as_extern(arg0) + +def wasm_extern_as_func(arg0): + _wasm_extern_as_func = libiwasm.wasm_extern_as_func + _wasm_extern_as_func.restype = POINTER(wasm_func_t) + _wasm_extern_as_func.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_func(arg0) + +def wasm_extern_as_global(arg0): + _wasm_extern_as_global = libiwasm.wasm_extern_as_global + _wasm_extern_as_global.restype = POINTER(wasm_global_t) + _wasm_extern_as_global.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_global(arg0) + +def wasm_extern_as_table(arg0): + _wasm_extern_as_table = libiwasm.wasm_extern_as_table + _wasm_extern_as_table.restype = POINTER(wasm_table_t) + _wasm_extern_as_table.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_table(arg0) + +def wasm_extern_as_memory(arg0): + _wasm_extern_as_memory = libiwasm.wasm_extern_as_memory + _wasm_extern_as_memory.restype = POINTER(wasm_memory_t) + _wasm_extern_as_memory.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_memory(arg0) + +def wasm_func_as_extern_const(arg0): + _wasm_func_as_extern_const = libiwasm.wasm_func_as_extern_const + _wasm_func_as_extern_const.restype = POINTER(wasm_extern_t) + _wasm_func_as_extern_const.argtypes = [POINTER(wasm_func_t)] + return _wasm_func_as_extern_const(arg0) + +def wasm_global_as_extern_const(arg0): + _wasm_global_as_extern_const = libiwasm.wasm_global_as_extern_const + _wasm_global_as_extern_const.restype = POINTER(wasm_extern_t) + _wasm_global_as_extern_const.argtypes = [POINTER(wasm_global_t)] + return _wasm_global_as_extern_const(arg0) + +def wasm_table_as_extern_const(arg0): + _wasm_table_as_extern_const = libiwasm.wasm_table_as_extern_const + _wasm_table_as_extern_const.restype = POINTER(wasm_extern_t) + _wasm_table_as_extern_const.argtypes = [POINTER(wasm_table_t)] + return _wasm_table_as_extern_const(arg0) + +def wasm_memory_as_extern_const(arg0): + _wasm_memory_as_extern_const = libiwasm.wasm_memory_as_extern_const + _wasm_memory_as_extern_const.restype = POINTER(wasm_extern_t) + _wasm_memory_as_extern_const.argtypes = [POINTER(wasm_memory_t)] + return _wasm_memory_as_extern_const(arg0) + +def wasm_extern_as_func_const(arg0): + _wasm_extern_as_func_const = libiwasm.wasm_extern_as_func_const + _wasm_extern_as_func_const.restype = POINTER(wasm_func_t) + _wasm_extern_as_func_const.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_func_const(arg0) + +def wasm_extern_as_global_const(arg0): + _wasm_extern_as_global_const = libiwasm.wasm_extern_as_global_const + _wasm_extern_as_global_const.restype = POINTER(wasm_global_t) + _wasm_extern_as_global_const.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_global_const(arg0) + +def wasm_extern_as_table_const(arg0): + _wasm_extern_as_table_const = libiwasm.wasm_extern_as_table_const + _wasm_extern_as_table_const.restype = POINTER(wasm_table_t) + _wasm_extern_as_table_const.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_table_const(arg0) + +def wasm_extern_as_memory_const(arg0): + _wasm_extern_as_memory_const = libiwasm.wasm_extern_as_memory_const + _wasm_extern_as_memory_const.restype = POINTER(wasm_memory_t) + _wasm_extern_as_memory_const.argtypes = [POINTER(wasm_extern_t)] + return _wasm_extern_as_memory_const(arg0) + +class wasm_instance_t(Structure): + pass + +def wasm_instance_delete(arg0): + _wasm_instance_delete = libiwasm.wasm_instance_delete + _wasm_instance_delete.restype = None + _wasm_instance_delete.argtypes = [POINTER(wasm_instance_t)] + return _wasm_instance_delete(arg0) + +def wasm_instance_copy(arg0): + _wasm_instance_copy = libiwasm.wasm_instance_copy + _wasm_instance_copy.restype = POINTER(wasm_instance_t) + _wasm_instance_copy.argtypes = [POINTER(wasm_instance_t)] + return _wasm_instance_copy(arg0) + +def wasm_instance_same(arg0,arg1): + _wasm_instance_same = libiwasm.wasm_instance_same + _wasm_instance_same.restype = c_bool + _wasm_instance_same.argtypes = [POINTER(wasm_instance_t),POINTER(wasm_instance_t)] + return _wasm_instance_same(arg0,arg1) + +def wasm_instance_get_host_info(arg0): + _wasm_instance_get_host_info = libiwasm.wasm_instance_get_host_info + _wasm_instance_get_host_info.restype = c_void_p + _wasm_instance_get_host_info.argtypes = [POINTER(wasm_instance_t)] + return _wasm_instance_get_host_info(arg0) + +def wasm_instance_set_host_info(arg0,arg1): + _wasm_instance_set_host_info = libiwasm.wasm_instance_set_host_info + _wasm_instance_set_host_info.restype = None + _wasm_instance_set_host_info.argtypes = [POINTER(wasm_instance_t),c_void_p] + return _wasm_instance_set_host_info(arg0,arg1) + +def wasm_instance_set_host_info_with_finalizer(arg0,arg1,arg2): + _wasm_instance_set_host_info_with_finalizer = libiwasm.wasm_instance_set_host_info_with_finalizer + _wasm_instance_set_host_info_with_finalizer.restype = None + _wasm_instance_set_host_info_with_finalizer.argtypes = [POINTER(wasm_instance_t),c_void_p,CFUNCTYPE(None,c_void_p)] + return _wasm_instance_set_host_info_with_finalizer(arg0,arg1,arg2) + +def wasm_instance_as_ref(arg0): + _wasm_instance_as_ref = libiwasm.wasm_instance_as_ref + _wasm_instance_as_ref.restype = POINTER(wasm_ref_t) + _wasm_instance_as_ref.argtypes = [POINTER(wasm_instance_t)] + return _wasm_instance_as_ref(arg0) + +def wasm_ref_as_instance(arg0): + _wasm_ref_as_instance = libiwasm.wasm_ref_as_instance + _wasm_ref_as_instance.restype = POINTER(wasm_instance_t) + _wasm_ref_as_instance.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_instance(arg0) + +def wasm_instance_as_ref_const(arg0): + _wasm_instance_as_ref_const = libiwasm.wasm_instance_as_ref_const + _wasm_instance_as_ref_const.restype = POINTER(wasm_ref_t) + _wasm_instance_as_ref_const.argtypes = [POINTER(wasm_instance_t)] + return _wasm_instance_as_ref_const(arg0) + +def wasm_ref_as_instance_const(arg0): + _wasm_ref_as_instance_const = libiwasm.wasm_ref_as_instance_const + _wasm_ref_as_instance_const.restype = POINTER(wasm_instance_t) + _wasm_ref_as_instance_const.argtypes = [POINTER(wasm_ref_t)] + return _wasm_ref_as_instance_const(arg0) + +def wasm_instance_new(arg0,arg1,arg2,arg3): + _wasm_instance_new = libiwasm.wasm_instance_new + _wasm_instance_new.restype = POINTER(wasm_instance_t) + _wasm_instance_new.argtypes = [POINTER(wasm_store_t),POINTER(wasm_module_t),POINTER(wasm_extern_vec_t),POINTER(POINTER(wasm_trap_t))] + return _wasm_instance_new(arg0,arg1,arg2,arg3) + +def wasm_instance_new_with_args(arg0,arg1,arg2,arg3,arg4,arg5): + _wasm_instance_new_with_args = libiwasm.wasm_instance_new_with_args + _wasm_instance_new_with_args.restype = POINTER(wasm_instance_t) + _wasm_instance_new_with_args.argtypes = [POINTER(wasm_store_t),POINTER(wasm_module_t),POINTER(wasm_extern_vec_t),POINTER(POINTER(wasm_trap_t)),c_uint32,c_uint32] + return _wasm_instance_new_with_args(arg0,arg1,arg2,arg3,arg4,arg5) + +def wasm_instance_exports(arg0,arg1): + _wasm_instance_exports = libiwasm.wasm_instance_exports + _wasm_instance_exports.restype = None + _wasm_instance_exports.argtypes = [POINTER(wasm_instance_t),POINTER(wasm_extern_vec_t)] + return _wasm_instance_exports(arg0,arg1) diff --git a/language-bindings/python/wamr/ffi.py b/language-bindings/python/wamr/ffi.py new file mode 100644 index 00000000..a29b607c --- /dev/null +++ b/language-bindings/python/wamr/ffi.py @@ -0,0 +1,642 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +# pylint: disable=missing-module-docstring + +import ctypes as c +import os +from pathlib import Path +import sys + +# +# Prologue. Dependencies of binding +# + +# how to open the library file of WAMR + +if sys.platform == "linux": + BUILDING_DIR = "product-mini/platforms/linux/build" + LIBRARY_NAME = "libiwasm.so" +elif sys.platform == "win32": + BUILDING_DIR = "product-mini/platforms/windows/build" + LIBRARY_NAME = "iwasm.dll" +elif sys.platform == "darwin": + BUILDING_DIR = "product-mini/platforms/darwin/build" + LIBRARY_NAME = "libiwasm.dylib" +else: + raise RuntimeError(f"unsupported platform `{sys.platform}`") + +# FIXME: should load libiwasm.so from current system library path +current_file = Path(__file__) +if current_file.is_symlink(): + current_file = Path(os.readlink(current_file)) +current_dir = current_file.parent.resolve() +root_dir = current_dir.parent.parent.parent.parent.resolve() +wamr_dir = root_dir.joinpath("wasm-micro-runtime").resolve() +if not wamr_dir.exists(): + raise RuntimeError(f"not found the repo of wasm-micro-runtime under {root_dir}") + +libpath = wamr_dir.joinpath(BUILDING_DIR).joinpath(LIBRARY_NAME).resolve() +if not libpath.exists(): + raise RuntimeError(f"not found precompiled wamr library at {libpath}") + +print(f"loading WAMR library from {libpath} ...") +libiwasm = c.cdll.LoadLibrary(libpath) + + +class wasm_ref_t(c.Structure): + # pylint: disable=invalid-name + pass + + +class wasm_val_union(c.Union): + # pylint: disable=invalid-name + _fields_ = [ + ("i32", c.c_int32), + ("i64", c.c_int64), + ("f32", c.c_float), + ("f64", c.c_double), + ("ref", c.POINTER(wasm_ref_t)), + ] + + +class wasm_val_t(c.Structure): + # pylint: disable=invalid-name + _fields_ = [ + ("kind", c.c_uint8), + ("of", wasm_val_union), + ] + + +def dereference(p): + # pylint: disable=protected-access + if not isinstance(p, c._Pointer): + raise RuntimeError("not a pointer") + return p.contents + + +# HELPERs +def create_null_pointer(struct_type): + return c.POINTER(struct_type)() + + +def is_null_pointer(c_pointer): + # pylint: disable=protected-access + if isinstance(c_pointer, c._Pointer): + return False if c_pointer else True + else: + raise RuntimeError("not a pointer") + + +def wasm_vec_to_list(vec): + """ + Converts a vector or a POINTER(vector) to a list + vector of type pointers -> list of type pointers + """ + known_vec_type = [ + wasm_byte_vec_t, + wasm_valtype_vec_t, + wasm_functype_vec_t, + wasm_globaltype_vec_t, + wasm_tabletype_vec_t, + wasm_memorytype_vec_t, + wasm_externtype_vec_t, + wasm_importtype_vec_t, + wasm_exporttype_vec_t, + wasm_val_vec_t, + wasm_frame_vec_t, + wasm_extern_vec_t, + ] + known_vec_pointer_type = [POINTER(type) for type in known_vec_type] + + if any([isinstance(vec, type) for type in known_vec_pointer_type]): + vec = dereference(vec) + return [vec.data[i] for i in range(vec.num_elems)] + elif any([isinstance(vec, type) for type in known_vec_type]): + return [vec.data[i] for i in range(vec.num_elems)] + else: + raise RuntimeError("not a known vector type") + + +def list_to_carray(elem_type, *args): + """ + Converts a python list into a C array + """ + data = (elem_type * len(args))(*args) + return data + + +def load_module_file(wasm_content): + binary = wasm_byte_vec_t() + wasm_byte_vec_new_uninitialized(binary, len(wasm_content)) + # has to use malloced memory. + c.memmove(binary.data, wasm_content, len(wasm_content)) + binary.num_elems = len(wasm_content) + return binary + + +# +# Enhancment of binding +# + +from .binding import * + +# Built-in functions for Structure + + +wasm_finalizer = CFUNCTYPE(None, c_void_p) + + +def __repr_wasm_limits_t(self): + return f"{self.min:#x} {self.max:#x}" + + +# overwrite +wasm_limits_t.__repr__ = __repr_wasm_limits_t + + +def __compare_wasm_valtype_t(self, other): + if not isinstance(other, wasm_valtype_t): + return False + + return wasm_valtype_kind(byref(self)) == wasm_valtype_kind(byref(other)) + + +def __repr_wasm_valtype_t(self): + val_kind = wasm_valtype_kind(byref(self)) + if WASM_I32 == val_kind: + return "i32" + elif WASM_I64 == val_kind: + return "i64" + elif WASM_F32 == val_kind: + return "f32" + elif WASM_F64 == val_kind: + return "f64" + elif WASM_FUNCREF == val_kind: + return "funcref" + else: + return "anyref" + + +wasm_valtype_t.__eq__ = __compare_wasm_valtype_t +wasm_valtype_t.__repr__ = __repr_wasm_valtype_t + + +def __compare_wasm_byte_vec_t(self, other): + if not isinstance(other, wasm_byte_vec_t): + return False + + if self.num_elems != other.num_elems: + return False + + self_data = bytes(self.data[: self.num_elems]) + other_data = bytes(other.data[: other.num_elems]) + return self_data.decode() == other_data.decode() + + +def __repr_wasm_byte_vec_t(self): + data = bytes(self.data[: self.num_elems]) + return data.decode() if self.size else "" + + +wasm_byte_vec_t.__eq__ = __compare_wasm_byte_vec_t +wasm_byte_vec_t.__repr__ = __repr_wasm_byte_vec_t + + +def __compare_wasm_functype_t(self, other): + if not isinstance(other, wasm_functype_t): + return False + + params1 = dereference(wasm_functype_params(byref(self))) + params2 = dereference(wasm_functype_params(byref(other))) + results1 = dereference(wasm_functype_results(byref(self))) + results2 = dereference(wasm_functype_results(byref(other))) + return params1 == params2 and results1 == results2 + + +def __repr_wasm_functype_t(self): + params = dereference(wasm_functype_params(byref(self))) + results = dereference(wasm_functype_results(byref(self))) + params = f" (params {params})" if params.size else "" + results = f" (results {results})" if results.size else "" + return f"(func{params}{results})" + + +wasm_functype_t.__eq__ = __compare_wasm_functype_t +wasm_functype_t.__repr__ = __repr_wasm_functype_t + + +def __compare_wasm_globaltype_t(self, other): + if not isinstance(other, wasm_globaltype_t): + return False + + content1 = dereference(wasm_globaltype_content(byref(self))) + content2 = dereference(wasm_globaltype_content(byref(other))) + mutability1 = wasm_globaltype_mutability(byref(self)) + mutability2 = wasm_globaltype_mutability(byref(other)) + return content1 == content2 and mutability1 == mutability2 + + +def __repr_wasm_globaltype_t(self): + mutability = f"{wasm_globaltype_mutability(byref(self))}" + content = f"{dereference(wasm_globaltype_content(byref(self)))}" + return f"(global{' mut ' if mutability else ' '}{content})" + + +wasm_globaltype_t.__eq__ = __compare_wasm_globaltype_t +wasm_globaltype_t.__repr__ = __repr_wasm_globaltype_t + + +def __compare_wasm_tabletype_t(self, other): + if not isinstance(other, wasm_tabletype_t): + return False + + element1 = dereference(wasm_tabletype_element(byref(self))) + element2 = dereference(wasm_tabletype_element(byref(other))) + limits1 = dereference(wasm_tabletype_limits(byref(self))) + limits2 = dereference(wasm_tabletype_limits(byref(other))) + return element1 == element2 and limits1 == limits2 + + +def __repr_wasm_tabletype_t(self): + element = dereference(wasm_tabletype_element(byref(self))) + limit = dereference(wasm_tabletype_limits(byref(self))) + return f"(table {limit} {element})" + + +wasm_tabletype_t.__eq__ = __compare_wasm_tabletype_t +wasm_tabletype_t.__repr__ = __repr_wasm_tabletype_t + + +def __compare_wasm_memorytype_t(self, other): + if not isinstance(other, wasm_memorytype_t): + return False + + limits1 = dereference(wasm_memorytype_limits(byref(self))) + limits2 = dereference(wasm_memorytype_limits(byref(other))) + return limits1 == limits2 + + +def __repr_wasm_memorytype_t(self): + limit = dereference(wasm_memorytype_limits(byref(self))) + return f"(memory {limit})" + + +wasm_memorytype_t.__eq__ = __compare_wasm_memorytype_t +wasm_memorytype_t.__repr__ = __repr_wasm_memorytype_t + + +def __compare_wasm_externtype_t(self, other): + if not isinstance(other, wasm_externtype_t): + return False + + if wasm_externtype_kind(byref(self)) != wasm_externtype_kind(byref(other)): + return False + + extern_kind = wasm_externtype_kind(byref(self)) + if WASM_EXTERN_FUNC == extern_kind: + return dereference(wasm_externtype_as_functype(self)) == dereference( + wasm_externtype_as_functype(other) + ) + elif WASM_EXTERN_GLOBAL == extern_kind: + return dereference(wasm_externtype_as_globaltype(self)) == dereference( + wasm_externtype_as_globaltype(other) + ) + elif WASM_EXTERN_MEMORY == extern_kind: + return dereference(wasm_externtype_as_memorytype(self)) == dereference( + wasm_externtype_as_memorytype(other) + ) + elif WASM_EXTERN_TABLE == extern_kind: + return dereference(wasm_externtype_as_tabletype(self)) == dereference( + wasm_externtype_as_tabletype(other) + ) + else: + raise RuntimeError("not a valid wasm_externtype_t") + + +def __repr_wasm_externtype_t(self): + extern_kind = wasm_externtype_kind(byref(self)) + if WASM_EXTERN_FUNC == extern_kind: + return str(dereference(wasm_externtype_as_functype(byref(self)))) + elif WASM_EXTERN_GLOBAL == extern_kind: + return str(dereference(wasm_externtype_as_globaltype(byref(self)))) + elif WASM_EXTERN_MEMORY == extern_kind: + return str(dereference(wasm_externtype_as_memorytype(byref(self)))) + elif WASM_EXTERN_TABLE == extern_kind: + return str(dereference(wasm_externtype_as_tabletype(byref(self)))) + else: + raise RuntimeError("not a valid wasm_externtype_t") + + +wasm_externtype_t.__eq__ = __compare_wasm_externtype_t +wasm_externtype_t.__repr__ = __repr_wasm_externtype_t + + +def __compare_wasm_importtype_t(self, other): + if not isinstance(other, wasm_importtype_t): + return False + + if dereference(wasm_importtype_module(self)) != dereference( + wasm_importtype_module(other) + ): + return False + + if dereference(wasm_importtype_name(self)) != dereference( + wasm_importtype_name(other) + ): + return False + + self_type = dereference(wasm_importtype_type(byref(self))) + other_type = dereference(wasm_importtype_type(byref(other))) + return self_type == other_type + + +def __repr_wasm_importtype_t(self): + module = wasm_importtype_module(byref(self)) + name = wasm_importtype_name(byref(self)) + extern_type = wasm_importtype_type(byref(self)) + return f'(import "{dereference(module)}" "{dereference(name)}" {dereference(extern_type)})' + + +wasm_importtype_t.__eq__ = __compare_wasm_importtype_t +wasm_importtype_t.__repr__ = __repr_wasm_importtype_t + + +def __compare_wasm_exporttype_t(self, other): + if not isinstance(other, wasm_exporttype_t): + return False + + self_name = dereference(wasm_exporttype_name(byref(self))) + other_name = dereference(wasm_exporttype_name(byref(other))) + if self_name != other_name: + return False + + self_type = dereference(wasm_exporttype_type(byref(self))) + other_type = dereference(wasm_exporttype_type(byref(other))) + return self_type == other_type + + +def __repr_wasm_exporttype_t(self): + name = wasm_exporttype_name(byref(self)) + extern_type = wasm_exporttype_type(byref(self)) + return f'(export "{dereference(name)}" {dereference(extern_type)})' + + +wasm_exporttype_t.__eq__ = __compare_wasm_exporttype_t +wasm_exporttype_t.__repr__ = __repr_wasm_exporttype_t + + +def __compare_wasm_val_t(self, other): + if not isinstance(other, wasm_val_t): + return False + + if self.kind != other.kind: + return False + + if WASM_I32 == self.kind: + return self.of.i32 == other.of.i32 + elif WASM_I64 == self.kind: + return self.of.i64 == other.of.i64 + elif WASM_F32 == self.kind: + return self.of.f32 == other.of.f32 + elif WASM_F64 == self.kind: + return self.of.f64 == other.of.f63 + elif WASM_ANYREF == self.kind: + raise RuntimeError("FIXME") + else: + raise RuntimeError("not a valid val kind") + + +def __repr_wasm_val_t(self): + if WASM_I32 == self.kind: + return f"i32 {self.of.i32}" + elif WASM_I64 == self.kind: + return f"i64 {self.of.i64}" + elif WASM_F32 == self.kind: + return f"f32 {self.of.f32}" + elif WASM_F64 == self.kind: + return f"f64 {self.of.f64}" + elif WASM_ANYREF == self.kind: + return f"anyref {self.of.ref}" + else: + raise RuntimeError("not a valid val kind") + + +wasm_val_t.__repr__ = __repr_wasm_val_t +wasm_val_t.__eq__ = __compare_wasm_val_t + + +def __repr_wasm_trap_t(self): + message = wasm_message_t() + wasm_trap_message(self, message) + return f'(trap "{str(message)}")' + + +wasm_trap_t.__repr__ = __repr_wasm_trap_t + + +def __repr_wasm_frame_t(self): + instance = wasm_frame_instance(self) + module_offset = wasm_frame_module_offset(self) + func_index = wasm_frame_func_index(self) + func_offset = wasm_frame_func_offset(self) + return f"> module:{module_offset:#x} => func#{func_index:#x}.{func_offset:#x}" + + +wasm_frame_t.__repr__ = __repr_wasm_frame_t + + +def __repr_wasm_module_t(self): + imports = wasm_importtype_vec_t() + wasm_module_imports(self, imports) + + exports = wasm_exporttype_vec_t() + wasm_module_exports(self, exports) + + ret = "(module" + ret += str(imports).replace("(import", "\n (import") + ret += str(exports).replace("(export", "\n (export") + ret += "\n)" + return ret + + +wasm_module_t.__repr__ = __repr_wasm_module_t + + +def __repr_wasm_instance_t(self): + exports = wasm_extern_vec_t() + wasm_instance_exports(self, exports) + + ret = "(instance" + ret += str(exports).replace("(export", "\n (export") + ret += "\n)" + return ret + + +wasm_instance_t.__repr__ = __repr_wasm_instance_t + + +def __repr_wasm_func_t(self): + ft = wasm_func_type(self) + return f"{str(dereference(ft))[:-1]} ... )" + + +wasm_func_t.__repr__ = __repr_wasm_func_t + + +def __repr_wasm_global_t(self): + gt = wasm_global_type(self) + return f"{str(dereference(gt))[:-1]} ... )" + + +wasm_global_t.__repr__ = __repr_wasm_global_t + + +def __repr_wasm_table_t(self): + tt = wasm_table_type(self) + return f"{str(dereference(tt))[:-1]} ... )" + + +wasm_table_t.__repr__ = __repr_wasm_table_t + + +def __repr_wasm_memory_t(self): + mt = wasm_memory_type(self) + return f"{str(dereference(mt))[:-1]} ... )" + + +wasm_memory_t.__repr__ = __repr_wasm_memory_t + + +def __repr_wasm_extern_t(self): + ext_type = wasm_extern_type(self) + ext_kind = wasm_extern_kind(self) + + ret = "(export " + if WASM_EXTERN_FUNC == ext_kind: + ft = wasm_externtype_as_functype(ext_type) + ret += str(dereference(ft)) + elif WASM_EXTERN_GLOBAL == ext_kind: + gt = wasm_externtype_as_globaltype(ext_type) + ret += str(dereference(gt)) + elif WASM_EXTERN_MEMORY == ext_kind: + mt = wasm_externtype_as_memorytype(ext_type) + ret += str(dereference(mt)) + elif WASM_EXTERN_TABLE == ext_kind: + tt = wasm_externtype_as_tabletype(ext_type) + ret += str(dereference(tt)) + else: + raise RuntimeError("not a valid extern kind") + ret += ")" + return ret + + +wasm_extern_t.__repr__ = __repr_wasm_extern_t + + +# Function Types construction short-hands +def wasm_name_new_from_string(s): + name = wasm_name_t() + data = ((c.c_ubyte) * len(s)).from_buffer_copy(s.encode()) + wasm_byte_vec_new(byref(name), len(s), data) + return name + + +def __wasm_functype_new(param_list, result_list): + def __list_to_wasm_valtype_vec(l): + vec = wasm_valtype_vec_t() + + if not l: + wasm_valtype_vec_new_empty(byref(vec)) + else: + data_type = POINTER(wasm_valtype_t) * len(l) + data = data_type() + for i in range(len(l)): + data[i] = l[i] + wasm_valtype_vec_new(byref(vec), len(l), data) + + return vec + + params = __list_to_wasm_valtype_vec(param_list) + results = __list_to_wasm_valtype_vec(result_list) + return wasm_functype_new(byref(params), byref(results)) + + +def wasm_functype_new_0_0(): + return __wasm_functype_new([], []) + + +def wasm_functype_new_1_0(p1): + return __wasm_functype_new([p1], []) + + +def wasm_functype_new_2_0(p1, p2): + return __wasm_functype_new([p1, p2], []) + + +def wasm_functype_new_3_0(p1, p2, p3): + return __wasm_functype_new([p1, p2, p3], []) + + +def wasm_functype_new_0_1(r1): + return __wasm_functype_new([], [r1]) + + +def wasm_functype_new_1_1(p1, r1): + return __wasm_functype_new([p1], [r1]) + + +def wasm_functype_new_2_1(p1, p2, r1): + return __wasm_functype_new([p1, p2], [r1]) + + +def wasm_functype_new_3_1(p1, p2, p3, r1): + return __wasm_functype_new([p1, p2, p3], [r1]) + + +def wasm_limits_new(min, max): + limit = wasm_limits_t() + limit.min = min + limit.max = max + return c.pointer(limit) + + +def wasm_i32_val(i): + v = wasm_val_t() + v.kind = WASM_I32 + v.of.i32 = i + return v + + +def wasm_i64_val(i): + v = wasm_val_t() + v.kind = WASM_I64 + v.of.i64 = i + return v + + +def wasm_f32_val(z): + v = wasm_val_t() + v.kind = WASM_F32 + v.of.f32 = z + return v + + +def wasm_f64_val(z): + v = wasm_val_t() + v.kind = WASM_F64 + v.of.f64 = z + return v + + +def wasm_func_cb_decl(func): + return wasm_func_callback_t(func) + + +def wasm_func_with_env_cb_decl(func): + return wasm_func_callback_with_env_t(func)