All notable changes to this project will be documented in this file.
- Added support for Python 3.11 (#696)
- Added support for Python 3.10 (#680)
- Improvements to the documentation (e880e25)
- Updated to the latest version of Maturin (0.14.17) to fix failing Windows builds (#715)
- Fixed compatibility issues with Python 3.11 (#696)
- Fixed compatibility issues with Python 3.10 (#680)
- Fixed typos in the documentation (#639, #681)
1.1.0 - 2022-01-05
Exportscan now be iterated over.- Host functions can now type-hint results with
Noneand tuples. - Added
int64andfloat32/float64views of memory. - Imports can now be specified using a
dictinstead of anImportObject.
- Wasmer has been updated to version 2.1.0.
- Python exceptions can now be thrown across Wasm calls.
- Memory view lengths are now returned correctly.
- Unsigned values that fit in
u32/u64no longer cause overflow errors when passed in/out of Wasm. - Indexing a memory view with a slice now always returns a list of values.
- Indexing a memory view with a slice can use steps.
- Indexing a memory view with an empty slice no longer returns an error.
1.0.0 - 2021-01-18
-
The whole API changed to better match Wasmer and Wasm C API
from wasmer import engine, wat2wasm, Module, Store, Instance from wasmer_compiler_cranelift import Compiler # Create an Engine jit = engine.JIT(Compiler) # Create a store. store = Store(jit) # Let's compile the Wasm module. module = Module(store, wasm_bytes) # Create an empty import object. import_object = {} # Let's instantiate the Wasm module. instance = Instance(module, import_object)
Please refer to the examples and documentation to learn more about the changes.
0.4.1 - 2020-02-02
-
New
Bufferclass to read memory fast (#125 by @Hywan)To get the memory buffer, use the
Memory.buffergetter. ABufferimplements the Python Buffer Protocol. The goal is to get faster reading operations than the existing memory views API.bytearray(instance.memory.buffer)is 15x faster thaninstance.memory.int8_view().memoryview(instance.memory.buffer)is 14x faster thaninstance.memory.int8_view().# Get the memory buffer. buffer = Instance(wasm_bytes).memory.buffer # Use the buffer with `memoryview` memory_view = memoryview(buffer) # Use the buffer with `byte_array` byte_array = bytearray(buffer) # Enjoy the byte array API! assert byte_array[3:9].decode() == 'Wasmer'
-
Support exported globals through the
Instance.globalsAPI (#120 by @Hywan)instance = Instance(wasm_bytes) x = instance.globals.x assert x.value == 7 assert x.mutable == True x.value = 153 assert x.value == 153
-
Implement a WebAssembly custom section query API (#118 by @Hywan)
Module.custom_section_namesis used to list all the custom section names.Module.custom_sectionis used to read the value of a specific custom section. If the custom section does not exist,Noneis returned.assert Module(wasm_bytes).custom_section('hello') == b'World!'
-
Add the
Module.importsgetter to list all imports, and introduce theImportKindenum (#117 by @Hywan)assert Module(wasm_bytes).imports == [ { 'kind': ImportKind.FUNCTION, 'namespace': 'ns', 'name': 'f1', }, { 'kind': ImportKind.FUNCTION, 'namespace': 'ns', 'name': 'f2', }, { 'kind': ImportKind.MEMORY, 'namespace': 'ns', 'name': 'm1', # Additional pairs specific to `MEMORY` 'minimum_pages': 3, 'maximum_pages': 4, }, { 'kind': ImportKind.GLOBAL, 'namespace': 'ns', 'name': 'g1', # Additional pairs specific to `GLOBAL` 'mutable': False, 'type': 'f32' }, { 'kind': ImportKind.TABLE, 'namespace': 'ns', 'name': 't1', # Additional pairs specific to `TABLE` 'minimum_elements': 1, 'maximum_elements': 2, 'element_type': 'anyfunc', } ]
-
Add the
Module.exportsgetter to list all exports, and introduce theExportKindenum (#115 and #116 by @Hywan)assert Module(wasm_bytes).exports == [ { 'name': 'memory', 'kind': ExportKind.MEMORY, }, { 'name': '__heap_base', 'kind': ExportKind.GLOBAL, }, { 'name': '__data_end', 'kind': ExportKind.GLOBAL, }, { 'name': 'sum', 'kind': ExportKind.FUNCTION, }, ]
-
Support modules without an exported memory (#114 by @Hywan)
instance = Instance(wasm_bytes) # Now the `memory` getter can return `None` assert instance.memory == None
-
Add Rust trait to allow inspection of exported functions (#71 by @Mec-iS)
instance = Instance(wasm_bytes) assert isinstance(instance.exports.sum.getfullargspec, str) assert isinstance(instance.exports.sum.getargs, str)
-
Memory views support slice assignment (#63 by @Hywan).
memory = instance.memory.uint8_view() memory[0:4] = b"abcd"
The slice is bound to the memory view length. The slice accepts start, stop, and step parameters, so it is possible to write
view[0:5:2]for instance. There is a huge difference with list slice assignment in Python: Elements in memory cannot be moved, so the assignment only overwrite elements.// With regular Python list a = [1, 2, 3, 4, 5] a[1:3] = [10, 11, 12] assert a == [1, 10, 11, 12, 4, 5] // With WebAssembly memory views view[0:5] = [1, 2, 3, 4, 5] view[1:3] = [10, 11, 12] assert view[0:5] == [1, 10, 11, 4, 5]
It is 10 times faster than a regular loop to write data in memory.
Read the pull request to learn more.
-
Make wasmer silently available anywhere with
wasmer-any(#62 by @syrusakbary)
- Improve documentation of
Memory(#127 by @Hywan) - Add a C to WebAssembly example in the documentation (#122 by @Hywan)
- Explain new features (#119 by @Hywan)
- Migrate to Github Actions for the CI (#97, #98 #99 and #101 by @Hywan)
- Update Wasmer from 0.6.0 to 0.14 (#70, #80, #88, #95, #113 and #132 by @Hywan)
- Update Pyo3 from 0.8.2 to 0.8.4 (#93, #96)
- Bump
spinfrom 0.5.0 to 0.5.2 (#72]
0.3.0 - 2019-07-16
-
Bound slice to the size of the memory view —allow to write
memory_view[0:]with no error— (#54 by @Hywan) -
Add
wasmer.__core_version__to get the runtime [Wasmer] version (#51 by @Hywan) -
Support module serialization with
Module.serializeandModule.deserialize(#48 by @Hywan)from wasmer import Module # Get the Wasm bytes. wasm_bytes = open('my_program.wasm', 'rb').read() # Compile the bytes into a Wasm module. module1 = Module(wasm_bytes) # Serialize the module. serialized_module = module1.serialize() # Let's forget about the module for this example. del module1 # Deserialize the module. module2 = Module.deserialize(serialized_module) # Instantiate and use it. result = module2.instantiate().exports.sum(1, 2)
-
Introduce the
Moduleclass, withModule.validateandModule.instantiate(#47 by @Hywan)from wasmer import Module # Get the Wasm bytes. wasm_bytes = open('my_program.wasm', 'rb').read() # Compile the Wasm bytes into a Wasm module. module = Module(wasm_bytes) # Instantiate the Wasm module. instance = module.instantiate() # Call a function on it. result = instance.exports.sum(1, 2) print(result) # 3
-
Add
wasmer.__version__to get the extension version (#27 by @Mec-iS)
- Handle exported functions that return nothing, aka void functions (#38 by @Hywan)
- More Python idiomatic examples (#55 by @Hywan)
- Add the
greetexample (#43 by @Hywan) - Improve code documentation (#36 by @Mec-iS)
- Fix typos (#25 by @Hywan)
- Fix comments in examples (#19 by @Hywan)
- Setup Bors (#35 by @Hywan)
- Add Github templates (#31 by @Hywan)
- Rename
just rusttojust build(#30 by @Hywan) - Update Wasmer to 0.5.5 (#59 by @Hywan)
- Update Wasmer to 0.4.2 (#42 by @Hywan)
- Update Wasmer to 0.4.0 (#26 by @Hywan)