Skip to content

Commit

Permalink
Add support for the module linking proposal (#47)
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 authored Dec 3, 2020
1 parent 784122b commit a7192c7
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 a7192c7

Please sign in to comment.