Skip to content

Latest commit

 

History

History
415 lines (330 loc) · 11.5 KB

CHANGELOG.md

File metadata and controls

415 lines (330 loc) · 11.5 KB

Changelog

All notable changes to this project will be documented in this file.

Table of Contents

1.1.0 - 2022-01-05

Added

  • Exports can now be iterated over.
  • Host functions can now type-hint results with None and tuples.
  • Added int64 and float32/float64 views of memory.
  • Imports can now be specified using a dict instead of an ImportObject.

Changed

  • Wasmer has been updated to version 2.1.0.
  • Python exceptions can now be thrown across Wasm calls.

Fixed

  • Memory view lengths are now returned correctly.
  • Unsigned values that fit in u32/u64 no 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

Changed

  • 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

Added

  • New Buffer class to read memory fast (#125 by @Hywan)

    To get the memory buffer, use the Memory.buffer getter. A Buffer implements 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 than instance.memory.int8_view(). memoryview(instance.memory.buffer) is 14x faster than instance.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.globals API (#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_names is used to list all the custom section names.

    Module.custom_section is used to read the value of a specific custom section. If the custom section does not exist, None is returned.

    assert Module(wasm_bytes).custom_section('hello') == b'World!'
  • Add the Module.imports getter to list all imports, and introduce the ImportKind enum (#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.exports getter to list all exports, and introduce the ExportKind enum (#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)

Changed

Security

  • Bump spin from 0.5.0 to 0.5.2 (#72]

0.3.0 - 2019-07-16

Added

  • Add the Memory.grow method (#56 by @Hywan)

  • 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.serialize and Module.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 Module class, with Module.validate and Module.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)

Changed

Fixes

0.2.0 - 2019-04-16