xref: /wasmtime-44.0.1/examples/memory.cc (revision 13ebd6f5)
1 #undef NDEBUG
2 
3 #include <fstream>
4 #include <iostream>
5 #include <sstream>
6 #include <wasmtime.hh>
7 
8 using namespace wasmtime;
9 
readFile(const char * name)10 std::string readFile(const char *name) {
11   std::ifstream watFile;
12   watFile.open(name);
13   std::stringstream strStream;
14   strStream << watFile.rdbuf();
15   return strStream.str();
16 }
17 
main()18 int main() {
19   // Create our `store` context and then compile a module and create an
20   // instance from the compiled module all in one go.
21   Engine engine;
22   Module module =
23       Module::compile(engine, readFile("examples/memory.wat")).unwrap();
24   Store store(engine);
25   Instance instance = Instance::create(store, module, {}).unwrap();
26 
27   // load_fn up our exports from the instance
28   auto memory = std::get<Memory>(*instance.get(store, "memory"));
29   auto size = std::get<Func>(*instance.get(store, "size"));
30   auto load_fn = std::get<Func>(*instance.get(store, "load"));
31   auto store_fn = std::get<Func>(*instance.get(store, "store"));
32 
33   std::cout << "Checking memory...\n";
34   assert(memory.size(store) == 2);
35   auto data = memory.data(store);
36   assert(data.size() == 0x20000);
37   assert(data[0] == 0);
38   assert(data[0x1000] == 1);
39   assert(data[0x1003] == 4);
40 
41   assert(size.call(store, {}).unwrap()[0].i32() == 2);
42   assert(load_fn.call(store, {0}).unwrap()[0].i32() == 0);
43   assert(load_fn.call(store, {0x1000}).unwrap()[0].i32() == 1);
44   assert(load_fn.call(store, {0x1003}).unwrap()[0].i32() == 4);
45   assert(load_fn.call(store, {0x1ffff}).unwrap()[0].i32() == 0);
46   load_fn.call(store, {0x20000}).err(); // out of bounds trap
47 
48   std::cout << "Mutating memory...\n";
49   memory.data(store)[0x1003] = 5;
50 
51   store_fn.call(store, {0x1002, 6}).unwrap();
52   store_fn.call(store, {0x20000, 0}).err(); // out of bounds trap
53 
54   assert(memory.data(store)[0x1002] == 6);
55   assert(memory.data(store)[0x1003] == 5);
56   assert(load_fn.call(store, {0x1002}).unwrap()[0].i32() == 6);
57   assert(load_fn.call(store, {0x1003}).unwrap()[0].i32() == 5);
58 
59   // Grow memory.
60   std::cout << "Growing memory...\n";
61   memory.grow(store, 1).unwrap();
62   assert(memory.size(store) == 3);
63   assert(memory.data(store).size() == 0x30000);
64 
65   assert(load_fn.call(store, {0x20000}).unwrap()[0].i32() == 0);
66   store_fn.call(store, {0x20000, 0}).unwrap();
67   load_fn.call(store, {0x30000}).err();
68   store_fn.call(store, {0x30000, 0}).err();
69 
70   memory.grow(store, 1).err();
71   memory.grow(store, 0).ok();
72 
73   std::cout << "Creating stand-alone memory...\n";
74   MemoryType ty(5, 5);
75   Memory memory2 = Memory::create(store, ty).unwrap();
76   assert(memory2.size(store) == 5);
77   memory2.grow(store, 1).err();
78   memory2.grow(store, 0).ok();
79 }
80