Coverage for examples/memory.py: 98%

53 statements  

« 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. 

6 

7from wasmtime import Store, Module, Instance, Trap, MemoryType, Memory, Limits, WasmtimeError 

8 

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, []) 

14 

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"] 

21 

22print("Checking memory...") 

23assert(memory.size(store) == 2) 

24assert(memory.data_len(store) == 0x20000) 

25 

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) 

32 

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) 

38 

39 

40def assert_traps(func): 

41 try: 

42 func() 

43 assert(False) 

44 except Trap: 

45 pass 

46 except WasmtimeError: 

47 pass 

48 

49 

50# out of bounds trap 

51assert_traps(lambda: load_fn(store, 0x20000)) 

52 

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)) 

58 

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) 

63 

64# Grow memory. 

65print("Growing memory...") 

66assert(memory.grow(store, 1)) 

67assert(memory.size(store) == 3) 

68assert(memory.data_len(store) == 0x30000) 

69 

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)) 

74 

75# Memory can fail to grow 

76assert_traps(lambda: memory.grow(store, 1)) 

77assert(memory.grow(store, 0)) 

78 

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))