Skip to content

Commit

Permalink
Add support for the module linking proposal
Browse files Browse the repository at this point in the history
This updates the Python extension with the API support added in
bytecodealliance/wasmtime#2472. Most of the changes here were pretty
straightforward!
  • Loading branch information
alexcrichton committed Dec 3, 2020
1 parent 784122b commit b39356c
Show file tree
Hide file tree
Showing 13 changed files with 533 additions and 44 deletions.
19 changes: 19 additions & 0 deletions tests/test_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ def test_multiple_exports(self):
assert(isinstance(instance.exports[1], Func))
assert(isinstance(instance.exports[2], Global))

def test_instance_type(self):
store = Store()
module = Module(store.engine, """
(module
(func (export "a"))
(func (export "b"))
(global (export "c") i32 (i32.const 0))
)
""")
ty = Instance(store, module, []).type
exports = ty.exports
self.assertEqual(len(exports), 3)
assert(isinstance(exports[0].type, FuncType))
assert(exports[0].name == 'a')
assert(isinstance(exports[1].type, FuncType))
assert(exports[1].name == 'b')
assert(isinstance(exports[2].type, GlobalType))
assert(exports[2].name == 'c')

def test_import_func(self):
store = Store()
module = Module(store.engine, """
Expand Down
37 changes: 37 additions & 0 deletions tests/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,43 @@ def test_exports(self):
self.assertEqual(ty.limits, Limits(1, None))
self.assertEqual(ty.element, ValType.funcref())

def test_type(self):
store = Store()
module = Module(store.engine, """
(module
(import "" "" (func))
(import "a" "bcd" (global i32))
(import "" "x" (table 1 funcref))
(func (export "a") (param i32 f32) (result f64)
f64.const 0)
(global (export "") (mut i32) (i32.const 1))
(memory (export "mem") 1)
(table (export "table") 1 funcref)
)
""")
ty = module.type
imports = ty.imports
exports = ty.exports
assert(imports[0].module == '')
assert(imports[0].name == '')
assert(isinstance(imports[0].type, FuncType))
assert(imports[1].module == 'a')
assert(imports[1].name == 'bcd')
assert(isinstance(imports[1].type, GlobalType))
assert(imports[2].module == '')
assert(imports[2].name == 'x')
assert(isinstance(imports[2].type, TableType))

assert(exports[0].name == 'a')
assert(isinstance(exports[0].type, FuncType))
assert(exports[1].name == '')
assert(isinstance(exports[1].type, GlobalType))
assert(exports[2].name == 'mem')
assert(isinstance(exports[2].type, MemoryType))
assert(exports[3].name == 'table')
assert(isinstance(exports[3].type, TableType))

def test_serialize(self):
store = Store()
module = Module(store.engine, '(module)')
Expand Down
55 changes: 55 additions & 0 deletions tests/test_module_linking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import unittest

from wasmtime import *


class TestModuleLinking(unittest.TestCase):
def store(self):
config = Config()
config.wasm_module_linking = True
return Store(Engine(config))

def test_import_string_optional(self):
store = self.store()
module = Module(store.engine, """
(module
(import "" (func))
)
""")
assert(module.type.imports[0].module == '')
assert(module.type.imports[0].name is None)

def test_module_import(self):
store = self.store()
module1 = Module(store.engine, """
(module (import "" (module)))
""")
module2 = Module(store.engine, "(module)")
Instance(store, module1, [module2])

def test_module_export(self):
store = self.store()
module = Module(store.engine, """
(module (module (export "")))
""")
i = Instance(store, module, [])
assert(isinstance(i.exports[0], Module))

def test_instance_import(self):
store = self.store()
module = Module(store.engine, """
(module (import "" (instance)))
""")
instance = Instance(store, Module(store.engine, "(module)"), [])
Instance(store, module, [instance])

def test_instance_export(self):
store = self.store()
instance = Module(store.engine, """
(module
(module $m)
(instance (export "") (instantiate $m))
)
""")
i = Instance(store, instance, [])
assert(isinstance(i.exports[0], Instance))
6 changes: 3 additions & 3 deletions tests/test_trap.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ def test_frames(self):
self.assertEqual(str(trap), """\
wasm trap: unreachable
wasm backtrace:
0: 0x2d - module!bar
1: 0x28 - module!foo
2: 0x23 - module!<wasm function 0>
0: 0x2d - module!bar
1: 0x28 - module!foo
2: 0x23 - module!<wasm function 0>
""")

def test_frames_no_module(self):
Expand Down
2 changes: 1 addition & 1 deletion wasmtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ._engine import Engine
from ._store import Store
from ._types import FuncType, GlobalType, MemoryType, TableType
from ._types import ValType, Limits, ImportType, ExportType
from ._types import ValType, Limits, ImportType, ExportType, ModuleType, InstanceType
from ._wat2wasm import wat2wasm
from ._module import Module
from ._value import Val, IntoVal
Expand Down
222 changes: 222 additions & 0 deletions wasmtime/_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,12 @@ def wasmtime_config_wasm_bulk_memory_set(arg0: Any, arg1: Any) -> None:
def wasmtime_config_wasm_multi_value_set(arg0: Any, arg1: Any) -> None:
return _wasmtime_config_wasm_multi_value_set(arg0, arg1) # type: ignore

_wasmtime_config_wasm_module_linking_set = dll.wasmtime_config_wasm_module_linking_set
_wasmtime_config_wasm_module_linking_set.restype = None
_wasmtime_config_wasm_module_linking_set.argtypes = [POINTER(wasm_config_t), c_bool]
def wasmtime_config_wasm_module_linking_set(arg0: Any, arg1: Any) -> None:
return _wasmtime_config_wasm_module_linking_set(arg0, arg1) # type: ignore

_wasmtime_config_strategy_set = dll.wasmtime_config_strategy_set
_wasmtime_config_strategy_set.restype = POINTER(wasmtime_error_t)
_wasmtime_config_strategy_set.argtypes = [POINTER(wasm_config_t), wasmtime_strategy_t]
Expand Down Expand Up @@ -2102,3 +2108,219 @@ def wasmtime_module_serialize(module: Any, ret: Any) -> pointer:
_wasmtime_module_deserialize.argtypes = [POINTER(wasm_engine_t), POINTER(wasm_byte_vec_t), POINTER(POINTER(wasm_module_t))]
def wasmtime_module_deserialize(engine: Any, serialized: Any, ret: Any) -> pointer:
return _wasmtime_module_deserialize(engine, serialized, ret) # type: ignore

class wasm_instancetype_t(Structure):
pass

_wasm_instancetype_delete = dll.wasm_instancetype_delete
_wasm_instancetype_delete.restype = None
_wasm_instancetype_delete.argtypes = [POINTER(wasm_instancetype_t)]
def wasm_instancetype_delete(arg0: Any) -> None:
return _wasm_instancetype_delete(arg0) # type: ignore

class wasm_instancetype_vec_t(Structure):
_fields_ = [
("size", c_size_t),
("data", POINTER(POINTER(wasm_instancetype_t))),
]

_wasm_instancetype_vec_new_empty = dll.wasm_instancetype_vec_new_empty
_wasm_instancetype_vec_new_empty.restype = None
_wasm_instancetype_vec_new_empty.argtypes = [POINTER(wasm_instancetype_vec_t)]
def wasm_instancetype_vec_new_empty(out: Any) -> None:
return _wasm_instancetype_vec_new_empty(out) # type: ignore

_wasm_instancetype_vec_new_uninitialized = dll.wasm_instancetype_vec_new_uninitialized
_wasm_instancetype_vec_new_uninitialized.restype = None
_wasm_instancetype_vec_new_uninitialized.argtypes = [POINTER(wasm_instancetype_vec_t), c_size_t]
def wasm_instancetype_vec_new_uninitialized(out: Any, arg1: Any) -> None:
return _wasm_instancetype_vec_new_uninitialized(out, arg1) # type: ignore

_wasm_instancetype_vec_new = dll.wasm_instancetype_vec_new
_wasm_instancetype_vec_new.restype = None
_wasm_instancetype_vec_new.argtypes = [POINTER(wasm_instancetype_vec_t), c_size_t, POINTER(POINTER(wasm_instancetype_t))]
def wasm_instancetype_vec_new(out: Any, arg1: Any, arg2: Any) -> None:
return _wasm_instancetype_vec_new(out, arg1, arg2) # type: ignore

_wasm_instancetype_vec_copy = dll.wasm_instancetype_vec_copy
_wasm_instancetype_vec_copy.restype = None
_wasm_instancetype_vec_copy.argtypes = [POINTER(wasm_instancetype_vec_t), POINTER(wasm_instancetype_vec_t)]
def wasm_instancetype_vec_copy(out: Any, arg1: Any) -> None:
return _wasm_instancetype_vec_copy(out, arg1) # type: ignore

_wasm_instancetype_vec_delete = dll.wasm_instancetype_vec_delete
_wasm_instancetype_vec_delete.restype = None
_wasm_instancetype_vec_delete.argtypes = [POINTER(wasm_instancetype_vec_t)]
def wasm_instancetype_vec_delete(arg0: Any) -> None:
return _wasm_instancetype_vec_delete(arg0) # type: ignore

_wasm_instancetype_copy = dll.wasm_instancetype_copy
_wasm_instancetype_copy.restype = POINTER(wasm_instancetype_t)
_wasm_instancetype_copy.argtypes = [POINTER(wasm_instancetype_t)]
def wasm_instancetype_copy(arg0: Any) -> pointer:
return _wasm_instancetype_copy(arg0) # type: ignore

_wasm_instancetype_exports = dll.wasm_instancetype_exports
_wasm_instancetype_exports.restype = None
_wasm_instancetype_exports.argtypes = [POINTER(wasm_instancetype_t), POINTER(wasm_exporttype_vec_t)]
def wasm_instancetype_exports(arg0: Any, out: Any) -> None:
return _wasm_instancetype_exports(arg0, out) # type: ignore

_wasm_instancetype_as_externtype = dll.wasm_instancetype_as_externtype
_wasm_instancetype_as_externtype.restype = POINTER(wasm_externtype_t)
_wasm_instancetype_as_externtype.argtypes = [POINTER(wasm_instancetype_t)]
def wasm_instancetype_as_externtype(arg0: Any) -> pointer:
return _wasm_instancetype_as_externtype(arg0) # type: ignore

_wasm_externtype_as_instancetype = dll.wasm_externtype_as_instancetype
_wasm_externtype_as_instancetype.restype = POINTER(wasm_instancetype_t)
_wasm_externtype_as_instancetype.argtypes = [POINTER(wasm_externtype_t)]
def wasm_externtype_as_instancetype(arg0: Any) -> pointer:
return _wasm_externtype_as_instancetype(arg0) # type: ignore

_wasm_instancetype_as_externtype_const = dll.wasm_instancetype_as_externtype_const
_wasm_instancetype_as_externtype_const.restype = POINTER(wasm_externtype_t)
_wasm_instancetype_as_externtype_const.argtypes = [POINTER(wasm_instancetype_t)]
def wasm_instancetype_as_externtype_const(arg0: Any) -> pointer:
return _wasm_instancetype_as_externtype_const(arg0) # type: ignore

_wasm_externtype_as_instancetype_const = dll.wasm_externtype_as_instancetype_const
_wasm_externtype_as_instancetype_const.restype = POINTER(wasm_instancetype_t)
_wasm_externtype_as_instancetype_const.argtypes = [POINTER(wasm_externtype_t)]
def wasm_externtype_as_instancetype_const(arg0: Any) -> pointer:
return _wasm_externtype_as_instancetype_const(arg0) # type: ignore

class wasm_moduletype_t(Structure):
pass

_wasm_moduletype_delete = dll.wasm_moduletype_delete
_wasm_moduletype_delete.restype = None
_wasm_moduletype_delete.argtypes = [POINTER(wasm_moduletype_t)]
def wasm_moduletype_delete(arg0: Any) -> None:
return _wasm_moduletype_delete(arg0) # type: ignore

class wasm_moduletype_vec_t(Structure):
_fields_ = [
("size", c_size_t),
("data", POINTER(POINTER(wasm_moduletype_t))),
]

_wasm_moduletype_vec_new_empty = dll.wasm_moduletype_vec_new_empty
_wasm_moduletype_vec_new_empty.restype = None
_wasm_moduletype_vec_new_empty.argtypes = [POINTER(wasm_moduletype_vec_t)]
def wasm_moduletype_vec_new_empty(out: Any) -> None:
return _wasm_moduletype_vec_new_empty(out) # type: ignore

_wasm_moduletype_vec_new_uninitialized = dll.wasm_moduletype_vec_new_uninitialized
_wasm_moduletype_vec_new_uninitialized.restype = None
_wasm_moduletype_vec_new_uninitialized.argtypes = [POINTER(wasm_moduletype_vec_t), c_size_t]
def wasm_moduletype_vec_new_uninitialized(out: Any, arg1: Any) -> None:
return _wasm_moduletype_vec_new_uninitialized(out, arg1) # type: ignore

_wasm_moduletype_vec_new = dll.wasm_moduletype_vec_new
_wasm_moduletype_vec_new.restype = None
_wasm_moduletype_vec_new.argtypes = [POINTER(wasm_moduletype_vec_t), c_size_t, POINTER(POINTER(wasm_moduletype_t))]
def wasm_moduletype_vec_new(out: Any, arg1: Any, arg2: Any) -> None:
return _wasm_moduletype_vec_new(out, arg1, arg2) # type: ignore

_wasm_moduletype_vec_copy = dll.wasm_moduletype_vec_copy
_wasm_moduletype_vec_copy.restype = None
_wasm_moduletype_vec_copy.argtypes = [POINTER(wasm_moduletype_vec_t), POINTER(wasm_moduletype_vec_t)]
def wasm_moduletype_vec_copy(out: Any, arg1: Any) -> None:
return _wasm_moduletype_vec_copy(out, arg1) # type: ignore

_wasm_moduletype_vec_delete = dll.wasm_moduletype_vec_delete
_wasm_moduletype_vec_delete.restype = None
_wasm_moduletype_vec_delete.argtypes = [POINTER(wasm_moduletype_vec_t)]
def wasm_moduletype_vec_delete(arg0: Any) -> None:
return _wasm_moduletype_vec_delete(arg0) # type: ignore

_wasm_moduletype_copy = dll.wasm_moduletype_copy
_wasm_moduletype_copy.restype = POINTER(wasm_moduletype_t)
_wasm_moduletype_copy.argtypes = [POINTER(wasm_moduletype_t)]
def wasm_moduletype_copy(arg0: Any) -> pointer:
return _wasm_moduletype_copy(arg0) # type: ignore

_wasm_moduletype_imports = dll.wasm_moduletype_imports
_wasm_moduletype_imports.restype = None
_wasm_moduletype_imports.argtypes = [POINTER(wasm_moduletype_t), POINTER(wasm_importtype_vec_t)]
def wasm_moduletype_imports(arg0: Any, out: Any) -> None:
return _wasm_moduletype_imports(arg0, out) # type: ignore

_wasm_moduletype_exports = dll.wasm_moduletype_exports
_wasm_moduletype_exports.restype = None
_wasm_moduletype_exports.argtypes = [POINTER(wasm_moduletype_t), POINTER(wasm_exporttype_vec_t)]
def wasm_moduletype_exports(arg0: Any, out: Any) -> None:
return _wasm_moduletype_exports(arg0, out) # type: ignore

_wasm_moduletype_as_externtype = dll.wasm_moduletype_as_externtype
_wasm_moduletype_as_externtype.restype = POINTER(wasm_externtype_t)
_wasm_moduletype_as_externtype.argtypes = [POINTER(wasm_moduletype_t)]
def wasm_moduletype_as_externtype(arg0: Any) -> pointer:
return _wasm_moduletype_as_externtype(arg0) # type: ignore

_wasm_externtype_as_moduletype = dll.wasm_externtype_as_moduletype
_wasm_externtype_as_moduletype.restype = POINTER(wasm_moduletype_t)
_wasm_externtype_as_moduletype.argtypes = [POINTER(wasm_externtype_t)]
def wasm_externtype_as_moduletype(arg0: Any) -> pointer:
return _wasm_externtype_as_moduletype(arg0) # type: ignore

_wasm_moduletype_as_externtype_const = dll.wasm_moduletype_as_externtype_const
_wasm_moduletype_as_externtype_const.restype = POINTER(wasm_externtype_t)
_wasm_moduletype_as_externtype_const.argtypes = [POINTER(wasm_moduletype_t)]
def wasm_moduletype_as_externtype_const(arg0: Any) -> pointer:
return _wasm_moduletype_as_externtype_const(arg0) # type: ignore

_wasm_externtype_as_moduletype_const = dll.wasm_externtype_as_moduletype_const
_wasm_externtype_as_moduletype_const.restype = POINTER(wasm_moduletype_t)
_wasm_externtype_as_moduletype_const.argtypes = [POINTER(wasm_externtype_t)]
def wasm_externtype_as_moduletype_const(arg0: Any) -> pointer:
return _wasm_externtype_as_moduletype_const(arg0) # type: ignore

_wasm_module_as_extern = dll.wasm_module_as_extern
_wasm_module_as_extern.restype = POINTER(wasm_extern_t)
_wasm_module_as_extern.argtypes = [POINTER(wasm_module_t)]
def wasm_module_as_extern(arg0: Any) -> pointer:
return _wasm_module_as_extern(arg0) # type: ignore

_wasm_extern_as_module = dll.wasm_extern_as_module
_wasm_extern_as_module.restype = POINTER(wasm_module_t)
_wasm_extern_as_module.argtypes = [POINTER(wasm_extern_t)]
def wasm_extern_as_module(arg0: Any) -> pointer:
return _wasm_extern_as_module(arg0) # type: ignore

_wasm_extern_as_module_const = dll.wasm_extern_as_module_const
_wasm_extern_as_module_const.restype = POINTER(wasm_module_t)
_wasm_extern_as_module_const.argtypes = [POINTER(wasm_extern_t)]
def wasm_extern_as_module_const(arg0: Any) -> pointer:
return _wasm_extern_as_module_const(arg0) # type: ignore

_wasm_instance_as_extern = dll.wasm_instance_as_extern
_wasm_instance_as_extern.restype = POINTER(wasm_extern_t)
_wasm_instance_as_extern.argtypes = [POINTER(wasm_instance_t)]
def wasm_instance_as_extern(arg0: Any) -> pointer:
return _wasm_instance_as_extern(arg0) # type: ignore

_wasm_extern_as_instance = dll.wasm_extern_as_instance
_wasm_extern_as_instance.restype = POINTER(wasm_instance_t)
_wasm_extern_as_instance.argtypes = [POINTER(wasm_extern_t)]
def wasm_extern_as_instance(arg0: Any) -> pointer:
return _wasm_extern_as_instance(arg0) # type: ignore

_wasm_extern_as_instance_const = dll.wasm_extern_as_instance_const
_wasm_extern_as_instance_const.restype = POINTER(wasm_instance_t)
_wasm_extern_as_instance_const.argtypes = [POINTER(wasm_extern_t)]
def wasm_extern_as_instance_const(arg0: Any) -> pointer:
return _wasm_extern_as_instance_const(arg0) # type: ignore

_wasm_instance_type = dll.wasm_instance_type
_wasm_instance_type.restype = POINTER(wasm_instancetype_t)
_wasm_instance_type.argtypes = [POINTER(wasm_instance_t)]
def wasm_instance_type(arg0: Any) -> pointer:
return _wasm_instance_type(arg0) # type: ignore

_wasm_module_type = dll.wasm_module_type
_wasm_module_type.restype = POINTER(wasm_moduletype_t)
_wasm_module_type.argtypes = [POINTER(wasm_module_t)]
def wasm_module_type(arg0: Any) -> pointer:
return _wasm_module_type(arg0) # type: ignore
12 changes: 12 additions & 0 deletions wasmtime/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ def wasm_multi_value(self, enable: bool) -> None:
raise TypeError('expected a bool')
ffi.wasmtime_config_wasm_multi_value_set(self._ptr, enable)

@setter_property
def wasm_module_linking(self, enable: bool) -> None:
"""
Configures whether the wasm [module linking proposal] is enabled.
[module linking proposal]: https://github.com/webassembly/module-linking
"""

if not isinstance(enable, bool):
raise TypeError('expected a bool')
ffi.wasmtime_config_wasm_module_linking_set(self._ptr, enable)

@setter_property
def strategy(self, strategy: str) -> None:
"""
Expand Down
Loading

0 comments on commit b39356c

Please sign in to comment.