Esempio n. 1
0
def test_early_exit():
    store = Store()
    module = Module(
        store, """
        (module
          (type $run_t (func (param i32 i32) (result i32)))
          (type $early_exit_t (func (param) (result)))

          (import "env" "early_exit" (func $early_exit (type $early_exit_t)))

          (func $run (type $run_t) (param $x i32) (param $y i32) (result i32)
            (call $early_exit)
            (i32.add
                local.get $x
                local.get $y))

          (export "run" (func $run)))
        """)

    def early_exit():
        raise Exception('oops')

    import_object = ImportObject()
    import_object.register("env", {
        "early_exit": Function(store, early_exit),
    })
    instance = Instance(module, import_object)

    try:
        instance.exports.run(1, 2)
    except RuntimeError as err:
        assert 'oops' in str(err)
    else:
        assert False
Esempio n. 2
0
def test_import_memory():
    store = Store()
    module = Module(
        store, """
        (module
          (import "env" "memory" (memory $memory 1))
          (func (export "increment")
            i32.const 0
            i32.const 0
            i32.load    ;; load 0
            i32.const 1
            i32.add     ;; add 1
            i32.store   ;; store at 0
            ))
        """)

    memory = Memory(store, MemoryType(minimum=1))
    view = memory.uint8_view(offset=0)

    import_object = defaultdict(dict)
    import_object["env"]["memory"] = memory
    instance = Instance(module, import_object)

    assert view[0] == 0
    instance.exports.increment()
    assert view[0] == 1
    instance.exports.increment()
    assert view[0] == 2
Esempio n. 3
0
def run_code(wasm_code):

    # Define the engine that will drive everything.
    #
    # In this case, the engine is `wasmer.engine.JIT` which roughly
    # means that the executable code will live in memory.
    wasmer_engine = engine.JIT(Compiler)

    # Create a store, that holds the engine.
    store = Store(wasmer_engine)

    # Here we go.
    #
    # Let's compile the Wasm module. It is at this step that the Wasm text
    # is transformed into Wasm bytes (if necessary), and then compiled to
    # executable code by the compiler, which is then stored in memory by
    # the engine.
    module = Module(store, wasm_code)

    # Provide an "abort()" host function.
    import_object = host_functions(store)

    # Congrats, the Wasm module is compiled! Now let's execute it for the
    # sake of having a complete example.
    #
    # Let's instantiate the Wasm module.
    instance = Instance(module, import_object)

    # The Wasm module exports a function called `sum`.
    add = instance.exports.add
    results = add(1, 2)

    print(results)
def test_import_memory():
    store = Store()
    module = Module(
        store, """
        (module
          (import "env" "memory" (memory $memory 1))
          (func (export "increment")
            i32.const 0
            i32.const 0
            i32.load    ;; load 0
            i32.const 1
            i32.add     ;; add 1
            i32.store   ;; store at 0
            ))
        """)

    memory = Memory(store, MemoryType(1, shared=False))
    view = memory.uint8_view(offset=0)

    import_object = ImportObject()
    import_object.register("env", {"memory": memory})

    instance = Instance(module, import_object)

    assert view[0] == 0
    instance.exports.increment()
    assert view[0] == 1
    instance.exports.increment()
    assert view[0] == 2
Esempio n. 5
0
def test_get_index():
    memory = Instance(TEST_BYTES).memory.uint8_view()
    index = 7
    value = 42
    memory[index] = value

    assert memory[index] == value
def test_import_global():
    store = Store()
    module = Module(
        store, """
        (module
          (import "env" "global" (global $global (mut i32)))
          (func (export "read_g") (result i32)
            global.get $global)
          (func (export "write_g") (param i32)
            local.get 0
            global.set $global))
        """)

    global_ = Global(store, Value.i32(7), mutable=True)

    import_object = ImportObject()
    import_object.register("env", {"global": global_})

    instance = Instance(module, import_object)

    assert instance.exports.read_g() == 7
    global_.value = 153
    assert instance.exports.read_g() == 153
    instance.exports.write_g(11)
    assert global_.value == 11
Esempio n. 7
0
def test_return_multiple_values_from_host_function():
    store = Store()
    module = Module(
        store,
        """
        (module
          (type $swap_t (func (param i32 i64) (result i64 i32)))
          (type $test_t (func (param i32 i64) (result i64 i32)))

          (import "env" "swap" (func $swap (type $swap_t)))

          (func $test (type $test_t) (param $x i32) (param $y i64) (result i64 i32)
            local.get $x
            local.get $y
            call $swap)
          (export "test" (func $test)))
        """
    )

    def swap(x: 'i32', y: 'i64') -> ('i64', 'i32'):
        return (y, x)

    import_object = ImportObject()
    import_object.register(
        "env",
        {
            "swap": Function(store, swap),
        }
    )
    instance = Instance(module, import_object)

    assert instance.exports.test(41, 42) == (42, 41)
def run_test():
    with open(path, 'rb') as bytecode:
        wasm_bytes = bytecode.read()
        instance = Instance(wasm_bytes)

        # print exported functions
        print("Modules exported from Rust: ")
        print(instance.exports)

        # assign functions
        simple_add = instance.exports.simple_add
        fibo = instance.exports.fibo
        loop_str = instance.exports.loop_str
        rust_geo_convex_hull = instance.exports.rust_geo_convex_hull
        reverse_string = instance.exports.reverse_string

        # try a simple addition
        result = simple_add(12, 12)
        print("call simple_add(12, 12): ")
        print(result)

        test_str = b'Test sTRing'
        result = test_reverse(instance, reverse_string, test_str)

        print(f'Reversing {test_str} >>>')
        print(result)
Esempio n. 9
0
def test_get_slice_out_of_range_empty():
    with pytest.raises(IndexError) as context_manager:
        memory = Instance(TEST_BYTES).memory.uint8_view()
        memory[2:1]

    exception = context_manager.value
    assert str(exception) == ('Slice `2:1` cannot be empty.')
Esempio n. 10
0
def test_get_integer_out_of_range_negative():
    with pytest.raises(IndexError) as context_manager:
        memory = Instance(TEST_BYTES).memory.uint8_view()
        memory[-1]

    exception = context_manager.value
    assert str(exception) == ('Out of bound: Index cannot be negative.')
Esempio n. 11
0
def test_get_slice_out_of_range_invalid_step():
    with pytest.raises(IndexError) as context_manager:
        memory = Instance(TEST_BYTES).memory.uint8_view()
        memory[1:7:2]

    exception = context_manager.value
    assert str(exception) == ('Slice must have a step of 1 for now; given 2.')
Esempio n. 12
0
    def test_get(self):
        memory = Instance(TEST_BYTES).uint8_memory_view()
        index = 7
        value = 42
        memory[index] = value

        self.assertEqual(memory[index], value)
Esempio n. 13
0
def test_failed_to_instantiate():
    with pytest.raises(RuntimeError) as context_manager:
        Instance(INVALID_TEST_BYTES)

    exception = context_manager.value
    assert str(exception) == (
        'Failed to compile the module:\n    Validation error "Invalid type"')
Esempio n. 14
0
def test_store_with_various_engines_and_compilers():
    engines = [engine.JIT, engine.Native]
    compilers = [
        None,
        wasmer_compiler_cranelift.Compiler,
        #wasmer_compiler_llvm.Compiler,
        wasmer_compiler_singlepass.Compiler
    ]
    results = [
        ('jit', None),
        ('jit', 'cranelift'),
        #('jit', 'llvm'),
        ('jit', 'singlepass'),
        ('native', None),
        ('native', 'cranelift'),
        #('native', 'llvm'),
        ('native', 'singlepass'),
    ]

    for ((engine_, compiler), expected) in itertools.zip_longest(
            itertools.product(engines, compilers), results):
        store = Store(engine_(compiler))

        assert store.engine_name == expected[0]
        assert store.compiler_name == expected[1]

        if compiler != None:
            module = Module(store, TEST_BYTES)
            instance = Instance(module)

            assert instance.exports.sum(1, 2)
Esempio n. 15
0
def test_wasi_env_memory():
    store = Store()
    wasi_env = wasi.StateBuilder("foo").finalize()
    import_object = wasi_env.generate_import_object(store, wasi.Version.LATEST)

    instance = Instance(Module(store, TEST_BYTES), import_object)

    wasi_env.memory = instance.exports.memory
def main():
    sfip_start = time.time()
    # expects you to run wasm-pack build before
    with open(os.path.join("pkg", "slow_function_demo_bg.wasm"), "rb") as instance_bytes:
        instance = Instance(instance_bytes.read())
        instance.exports.slow_func()
    sfip_end = time.time()
    print(f"Time taken for slow function using WASM is {sfip_end - sfip_start} seconds")
Esempio n. 17
0
def test_global_read_write():
    y = Instance(TEST_BYTES).globals.y

    assert y.value == 7

    y.value = 8

    assert y.value == 8
Esempio n. 18
0
def test_get_invalid_index():
    with pytest.raises(ValueError) as context_manager:
        memory = Instance(TEST_BYTES).memory.uint8_view()
        memory['a']

    exception = context_manager.value
    assert str(exception) == (
        'Only integers and slices are valid to represent an index.')
Esempio n. 19
0
def test_memory_grow_too_much():
    with pytest.raises(RuntimeError) as context_manager:
        Instance(TEST_BYTES).memory.grow(100000)

    exception = context_manager.value
    assert str(exception) == (
        'Failed to grow the memory: Grow Error: Failed to add pages because would exceed maximum number of pages. Left: 17, Right: 100000, Pages added: 100017.'
    )
Esempio n. 20
0
def test_get_slice():
    memory = Instance(TEST_BYTES).memory.uint8_view()
    index = 7
    memory[index] = 1
    memory[index + 1] = 2
    memory[index + 2] = 3

    assert memory[index:index + 3] == [1, 2, 3]
Esempio n. 21
0
def test_benchmark_execution_time_nbody_llvm_jit(benchmark):
    store = Store(engine.JIT(LLVM))
    module = Module(store, TEST_BYTES)
    instance = Instance(module)
    main = instance.exports.main

    @benchmark
    def bench():
        _ = main(N)
Esempio n. 22
0
    def test_failed_to_instantiate(self):
        with self.assertRaises(RuntimeError) as context_manager:
            Instance(INVALID_TEST_BYTES)

        exception = context_manager.exception
        self.assertEqual(
            str(exception),
            'Failed to instantiate the module:\n    compile error: Validation error "Invalid type"'
        )
Esempio n. 23
0
 def test_call_i32_i64_f32_f64_f64(self):
     self.assertEqual(
         round(
             Instance(TEST_BYTES).call('i32_i64_f32_f64_f64', [
                 Value.i32(1),
                 Value.i64(2),
                 Value.f32(3.4),
                 Value.f64(5.6)
             ]), 6), 1 + 2 + 3.4 + 5.6)
Esempio n. 24
0
def test_get_integer_out_of_range_too_large():
    with pytest.raises(IndexError) as context_manager:
        memory = Instance(TEST_BYTES).memory.uint8_view()
        memory[len(memory) + 1]

    exception = context_manager.value
    assert str(exception) == (
        'Out of bound: Maximum index 1114113 is larger than the memory size 1114112.'
    )
Esempio n. 25
0
def test_benchmark_execution_time_nbody_singlepass_native(benchmark):
    store = Store(engine.Native(Singlepass))
    module = Module(store, TEST_BYTES)
    instance = Instance(module)
    main = instance.exports.main

    @benchmark
    def bench():
        _ = main(N)
Esempio n. 26
0
    def test_set_out_of_range(self):
        with self.assertRaises(RuntimeError) as context_manager:
            memory = Instance(TEST_BYTES).uint8_memory_view()
            memory[len(memory) + 1] = 42

        exception = context_manager.exception
        self.assertEqual(
            str(exception),
            'Out of bound: Absolute index 1114113 is larger than the memory size 1114112.'
        )
Esempio n. 27
0
def test_benchmark_memory_view_bytearray_get(benchmark):
    store = Store(engine.JIT(Compiler))
    module = Module(store, TEST_BYTES)
    instance = Instance(module)
    memory = bytearray(instance.exports.memory.buffer)

    def bench():
        _ = memory[0]

    benchmark(bench)
Esempio n. 28
0
def test_benchmark_memory_view_int8_get(benchmark):
    store = Store(engine.JIT(Compiler))
    module = Module(store, TEST_BYTES)
    instance = Instance(module)
    memory = instance.exports.memory.uint8_view()

    def bench():
        _ = memory[0]

    benchmark(bench)
def run_timing():
    with open(path, 'rb') as bytecode:
        wasm_bytes = bytecode.read()
        instance = Instance(wasm_bytes)
        # assign functions
        simple_add = instance.exports.simple_add
        fibo = instance.exports.fibo
        rust_geo_convex_hull = instance.exports.rust_geo_convex_hull

        # print exported functions
        print("Modules exported from Rust: ")
        print(instance.exports)

        # define metadata in results
        from collections import OrderedDict
        results = OrderedDict()
        results['timestap'] = str(datetime.now())
        results['python_wasmer_v'] = f'{wasmer.__version__}|{wasmer.__core_version__}'

        import subprocess
        rustc_v = subprocess.check_output(['rustc', '--version']).decode().rstrip()
        results['rustc_v'] = rustc_v

        results['data'] = {}

        t_py = timeit.timeit('[py_simple_add(n-1, n) for n in range(100, 1000)]', number=10000, setup='from examples.scientific import py_simple_add')
        print('py add', t_py)

        t_wasm = timeit.timeit('[simple_add(n-1, n) for n in range(100, 1000)]', number=10000, setup=context+'simple_add = instance.exports.simple_add')
        print('t_wasm add', t_wasm)
        results['data']['simple_add'] = { 'py': t_py, 'wasm': t_wasm }

        t_py = timeit.timeit('[py_fibonacci(n) for n in range(100, 1000)]', number=1000, setup='from examples.scientific import py_fibonacci')
        print('py fibo', t_py)

        t_wasm = timeit.timeit('[fibo(n) for n in range(100, 1000)]', number=1000, setup=context+'fibo = instance.exports.fibo')
        print('t_wasm fibo', t_wasm)
        results['data']['fibonacci'] = { 'py': t_py, 'wasm': t_wasm }

        t_py = timeit.timeit('[py_shapely_convex_hull() for n in range(100, 1000)]', number=1000, setup='from examples.scientific import py_shapely_convex_hull')
        print('py shapely convex hull', t_py)

        t_wasm = timeit.timeit('[rust_geo_convex_hull() for n in range(100, 1000)]', number=1000, setup=context+'rust_geo_convex_hull = instance.exports.rust_geo_convex_hull')
        print('t_wasm rust-geo convex hull', t_wasm)
        results['data']['convex_hull'] = { 'py': t_py, 'wasm': t_wasm }

        # CSV file
        csv_file = join(dirname(__file__), 'timing', 'data', 'timing.csv')
        file_exists = os.path.isfile(csv_file)
        with open(csv_file, 'a') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=results.keys())
            if not file_exists:
                writer.writeheader()
                file_exists = True
            writer.writerow(results)
Esempio n. 30
0
def test_global_read_write_constant():
    z = Instance(TEST_BYTES).globals.z

    assert z.value == 42

    with pytest.raises(RuntimeError) as context_manager:
        z.value = 153

    exception = context_manager.value
    assert str(exception) == (
        'The global variable `z` is not mutable, cannot set a new value.')