13c51d3adSAlex Crichton //! An example of how to interact with wasm memory.
23c51d3adSAlex Crichton //!
33c51d3adSAlex Crichton //! Here a small wasm module is used to show how memory is initialized, how to
43c51d3adSAlex Crichton //! read and write memory through the `Memory` object, and how wasm functions
53c51d3adSAlex Crichton //! can trap when dealing with out-of-bounds addresses.
63c51d3adSAlex Crichton
7b86cba98SDaniel Marin // You can execute this example with `cargo run --example memory`
83c51d3adSAlex Crichton
93c51d3adSAlex Crichton use wasmtime::*;
103c51d3adSAlex Crichton
main() -> Result<()>113c51d3adSAlex Crichton fn main() -> Result<()> {
127a1b7cdfSAlex Crichton // Create our `store_fn` context and then compile a module and create an
133c51d3adSAlex Crichton // instance from the compiled module all in one go.
147a1b7cdfSAlex Crichton let mut store: Store<()> = Store::default();
157a1b7cdfSAlex Crichton let module = Module::from_file(store.engine(), "examples/memory.wat")?;
167a1b7cdfSAlex Crichton let instance = Instance::new(&mut store, &module, &[])?;
173c51d3adSAlex Crichton
187a1b7cdfSAlex Crichton // load_fn up our exports from the instance
193c51d3adSAlex Crichton let memory = instance
207a1b7cdfSAlex Crichton .get_memory(&mut store, "memory")
21*94740588SNick Fitzgerald .ok_or(wasmtime::format_err!("failed to find `memory` export"))?;
22b0939f66SAlex Crichton let size = instance.get_typed_func::<(), i32>(&mut store, "size")?;
23b0939f66SAlex Crichton let load_fn = instance.get_typed_func::<i32, i32>(&mut store, "load")?;
24b0939f66SAlex Crichton let store_fn = instance.get_typed_func::<(i32, i32), ()>(&mut store, "store")?;
253c51d3adSAlex Crichton
263c51d3adSAlex Crichton println!("Checking memory...");
277a1b7cdfSAlex Crichton assert_eq!(memory.size(&store), 2);
287a1b7cdfSAlex Crichton assert_eq!(memory.data_size(&store), 0x20000);
297a1b7cdfSAlex Crichton assert_eq!(memory.data_mut(&mut store)[0], 0);
307a1b7cdfSAlex Crichton assert_eq!(memory.data_mut(&mut store)[0x1000], 1);
317a1b7cdfSAlex Crichton assert_eq!(memory.data_mut(&mut store)[0x1003], 4);
323c51d3adSAlex Crichton
337a1b7cdfSAlex Crichton assert_eq!(size.call(&mut store, ())?, 2);
347a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0)?, 0);
357a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x1000)?, 1);
367a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x1003)?, 4);
377a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x1ffff)?, 0);
387a1b7cdfSAlex Crichton assert!(load_fn.call(&mut store, 0x20000).is_err()); // out of bounds trap
393c51d3adSAlex Crichton
403c51d3adSAlex Crichton println!("Mutating memory...");
417a1b7cdfSAlex Crichton memory.data_mut(&mut store)[0x1003] = 5;
423c51d3adSAlex Crichton
437a1b7cdfSAlex Crichton store_fn.call(&mut store, (0x1002, 6))?;
447a1b7cdfSAlex Crichton assert!(store_fn.call(&mut store, (0x20000, 0)).is_err()); // out of bounds trap
453c51d3adSAlex Crichton
467a1b7cdfSAlex Crichton assert_eq!(memory.data(&store)[0x1002], 6);
477a1b7cdfSAlex Crichton assert_eq!(memory.data(&store)[0x1003], 5);
487a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x1002)?, 6);
497a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x1003)?, 5);
503c51d3adSAlex Crichton
513c51d3adSAlex Crichton // Grow memory.
523c51d3adSAlex Crichton println!("Growing memory...");
537a1b7cdfSAlex Crichton memory.grow(&mut store, 1)?;
547a1b7cdfSAlex Crichton assert_eq!(memory.size(&store), 3);
557a1b7cdfSAlex Crichton assert_eq!(memory.data_size(&store), 0x30000);
563c51d3adSAlex Crichton
577a1b7cdfSAlex Crichton assert_eq!(load_fn.call(&mut store, 0x20000)?, 0);
587a1b7cdfSAlex Crichton store_fn.call(&mut store, (0x20000, 0))?;
597a1b7cdfSAlex Crichton assert!(load_fn.call(&mut store, 0x30000).is_err());
607a1b7cdfSAlex Crichton assert!(store_fn.call(&mut store, (0x30000, 0)).is_err());
613c51d3adSAlex Crichton
627a1b7cdfSAlex Crichton assert!(memory.grow(&mut store, 1).is_err());
637a1b7cdfSAlex Crichton assert!(memory.grow(&mut store, 0).is_ok());
643c51d3adSAlex Crichton
653c51d3adSAlex Crichton println!("Creating stand-alone memory...");
66e68aa995SAlex Crichton let memorytype = MemoryType::new(5, Some(5));
677a1b7cdfSAlex Crichton let memory2 = Memory::new(&mut store, memorytype)?;
687a1b7cdfSAlex Crichton assert_eq!(memory2.size(&store), 5);
697a1b7cdfSAlex Crichton assert!(memory2.grow(&mut store, 1).is_err());
707a1b7cdfSAlex Crichton assert!(memory2.grow(&mut store, 0).is_ok());
713c51d3adSAlex Crichton
723c51d3adSAlex Crichton Ok(())
733c51d3adSAlex Crichton }
74