Coverage for examples/memory.py: 98%
53 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
1# An example of how to interact with wasm memory.
2#
3# Here a small wasm module is used to show how memory is initialized, how to
4# read and write memory through the `Memory` object, and how wasm functions
5# can trap when dealing with out-of-bounds addresses.
7from wasmtime import Store, Module, Instance, Trap, MemoryType, Memory, Limits, WasmtimeError
9# Create our `Store` context and then compile a module and create an
10# instance from the compiled module all in one go.
11store = Store()
12module = Module.from_file(store.engine, "examples/memory.wat")
13instance = Instance(store, module, [])
15# Load up our exports from the instance
16exports = instance.exports(store)
17memory = exports["memory"]
18size_fn = exports["size"]
19load_fn = exports["load"]
20store_fn = exports["store"]
22print("Checking memory...")
23assert(memory.size(store) == 2)
24assert(memory.data_len(store) == 0x20000)
26# Note that usage of `data_ptr` is unsafe! This is a raw C pointer which is not
27# bounds checked at all. We checked our `data_len` above but you'll want to be
28# very careful when accessing data through `data_ptr()`
29assert(memory.data_ptr(store)[0] == 0)
30assert(memory.data_ptr(store)[0x1000] == 1)
31assert(memory.data_ptr(store)[0x1003] == 4)
33assert(size_fn(store) == 2)
34assert(load_fn(store, 0) == 0)
35assert(load_fn(store, 0x1000) == 1)
36assert(load_fn(store, 0x1003) == 4)
37assert(load_fn(store, 0x1ffff) == 0)
40def assert_traps(func):
41 try:
42 func()
43 assert(False)
44 except Trap:
45 pass
46 except WasmtimeError:
47 pass
50# out of bounds trap
51assert_traps(lambda: load_fn(store, 0x20000))
53print("Mutating memory...")
54memory.data_ptr(store)[0x1003] = 5
55store_fn(store, 0x1002, 6)
56# out of bounds trap
57assert_traps(lambda: store_fn(store, 0x20000, 0))
59assert(memory.data_ptr(store)[0x1002] == 6)
60assert(memory.data_ptr(store)[0x1003] == 5)
61assert(load_fn(store, 0x1002) == 6)
62assert(load_fn(store, 0x1003) == 5)
64# Grow memory.
65print("Growing memory...")
66assert(memory.grow(store, 1))
67assert(memory.size(store) == 3)
68assert(memory.data_len(store) == 0x30000)
70assert(load_fn(store, 0x20000) == 0)
71store_fn(store, 0x20000, 0)
72assert_traps(lambda: load_fn(store, 0x30000))
73assert_traps(lambda: store_fn(store, 0x30000, 0))
75# Memory can fail to grow
76assert_traps(lambda: memory.grow(store, 1))
77assert(memory.grow(store, 0))
79print("Creating stand-alone memory...")
80memorytype = MemoryType(Limits(5, 5))
81memory2 = Memory(store, memorytype)
82assert(memory2.size(store) == 5)
83assert_traps(lambda: memory2.grow(store, 1))
84assert(memory2.grow(store, 0))