Bläddra i källkod

Implement Python language binding (#1192) (#1195)

Implement the first version of Python language binding

Co-authored-by: liang.he <liang.he@intel.com>
Wenyong Huang 3 år sedan
förälder
incheckning
3d34a91f0b

+ 160 - 0
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/
+

+ 1 - 0
language-bindings/python/LICENSE

@@ -0,0 +1 @@
+../../LICENSE

+ 31 - 0
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.

+ 708 - 0
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 <class '_ctypes.PyCArrayType'>
+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.

BIN
language-bindings/python/docs/images/python_package_life_cycle.png


+ 12 - 0
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
+```

+ 3 - 0
language-bindings/python/pyproject.toml

@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools>=42"]
+build-backend = "setuptools.build_meta"

+ 5 - 0
language-bindings/python/requirements.txt

@@ -0,0 +1,5 @@
+black
+nose
+pycparser
+pylint
+

+ 4 - 0
language-bindings/python/samples/hello.wat

@@ -0,0 +1,4 @@
+(module
+  (func $hello (import "" "hello"))
+  (func (export "run") (call $hello))
+)

+ 41 - 0
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()

+ 93 - 0
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()

+ 30 - 0
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"],
+)

+ 7 - 0
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"]

+ 13 - 0
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

+ 525 - 0
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()

+ 1588 - 0
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()

+ 386 - 0
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)

+ 7 - 0
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"]

+ 2020 - 0
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)

+ 642 - 0
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)