1453bb9a4SAlex Crichton /** 2453bb9a4SAlex Crichton * \file wasmtime/memory.hh 3453bb9a4SAlex Crichton */ 4453bb9a4SAlex Crichton 5453bb9a4SAlex Crichton #ifndef WASMTIME_MEMORY_HH 6453bb9a4SAlex Crichton #define WASMTIME_MEMORY_HH 7453bb9a4SAlex Crichton 8453bb9a4SAlex Crichton #include <wasmtime/error.hh> 9453bb9a4SAlex Crichton #include <wasmtime/memory.h> 10453bb9a4SAlex Crichton #include <wasmtime/span.hh> 11453bb9a4SAlex Crichton #include <wasmtime/store.hh> 12453bb9a4SAlex Crichton #include <wasmtime/types/memory.hh> 13453bb9a4SAlex Crichton 14453bb9a4SAlex Crichton namespace wasmtime { 15453bb9a4SAlex Crichton 16453bb9a4SAlex Crichton /** 17453bb9a4SAlex Crichton * \brief A WebAssembly linear memory. 18453bb9a4SAlex Crichton * 19453bb9a4SAlex Crichton * This class represents a WebAssembly memory, either created through 20453bb9a4SAlex Crichton * instantiating a module or a host memory. 21453bb9a4SAlex Crichton * 22453bb9a4SAlex Crichton * Note that this type does not itself own any resources. It points to resources 23453bb9a4SAlex Crichton * owned within a `Store` and the `Store` must be passed in as the first 24453bb9a4SAlex Crichton * argument to the functions defined on `Table`. Note that if the wrong `Store` 25453bb9a4SAlex Crichton * is passed in then the process will be aborted. 26453bb9a4SAlex Crichton */ 27453bb9a4SAlex Crichton class Memory { 28453bb9a4SAlex Crichton friend class Instance; 29453bb9a4SAlex Crichton wasmtime_memory_t memory; 30453bb9a4SAlex Crichton 31453bb9a4SAlex Crichton public: 32453bb9a4SAlex Crichton /// Creates a new memory from the raw underlying C API representation. Memory(wasmtime_memory_t memory)33453bb9a4SAlex Crichton Memory(wasmtime_memory_t memory) : memory(memory) {} 34453bb9a4SAlex Crichton 35453bb9a4SAlex Crichton /// Creates a new host-defined memory with the type specified. create(Store::Context cx,const MemoryType & ty)36453bb9a4SAlex Crichton static Result<Memory> create(Store::Context cx, const MemoryType &ty) { 37453bb9a4SAlex Crichton wasmtime_memory_t memory; 38453bb9a4SAlex Crichton auto *error = wasmtime_memory_new(cx.ptr, ty.ptr.get(), &memory); 39453bb9a4SAlex Crichton if (error != nullptr) { 40453bb9a4SAlex Crichton return Error(error); 41453bb9a4SAlex Crichton } 42453bb9a4SAlex Crichton return Memory(memory); 43453bb9a4SAlex Crichton } 44453bb9a4SAlex Crichton 45453bb9a4SAlex Crichton /// Returns the type of this memory. type(Store::Context cx) const46453bb9a4SAlex Crichton MemoryType type(Store::Context cx) const { 47453bb9a4SAlex Crichton return wasmtime_memory_type(cx.ptr, &memory); 48453bb9a4SAlex Crichton } 49453bb9a4SAlex Crichton 50453bb9a4SAlex Crichton /// Returns the size, in WebAssembly pages, of this memory. size(Store::Context cx) const51453bb9a4SAlex Crichton uint64_t size(Store::Context cx) const { 52453bb9a4SAlex Crichton return wasmtime_memory_size(cx.ptr, &memory); 53453bb9a4SAlex Crichton } 54453bb9a4SAlex Crichton 55453bb9a4SAlex Crichton /// Returns a `span` of where this memory is located in the host. 56453bb9a4SAlex Crichton /// 57453bb9a4SAlex Crichton /// Note that embedders need to be very careful in their usage of the returned 58453bb9a4SAlex Crichton /// `span`. It can be invalidated with calls to `grow` and/or calls into 59453bb9a4SAlex Crichton /// WebAssembly. data(Store::Context cx) const60453bb9a4SAlex Crichton Span<uint8_t> data(Store::Context cx) const { 61453bb9a4SAlex Crichton auto *base = wasmtime_memory_data(cx.ptr, &memory); 62453bb9a4SAlex Crichton auto size = wasmtime_memory_data_size(cx.ptr, &memory); 63453bb9a4SAlex Crichton return {base, size}; 64453bb9a4SAlex Crichton } 65453bb9a4SAlex Crichton 66453bb9a4SAlex Crichton /// Grows the memory by `delta` WebAssembly pages. 67453bb9a4SAlex Crichton /// 68453bb9a4SAlex Crichton /// On success returns the previous size of this memory in units of 69453bb9a4SAlex Crichton /// WebAssembly pages. grow(Store::Context cx,uint64_t delta) const70453bb9a4SAlex Crichton Result<uint64_t> grow(Store::Context cx, uint64_t delta) const { 71453bb9a4SAlex Crichton uint64_t prev = 0; 72453bb9a4SAlex Crichton auto *error = wasmtime_memory_grow(cx.ptr, &memory, delta, &prev); 73453bb9a4SAlex Crichton if (error != nullptr) { 74453bb9a4SAlex Crichton return Error(error); 75453bb9a4SAlex Crichton } 76453bb9a4SAlex Crichton return prev; 77453bb9a4SAlex Crichton } 783a5dda5fSAlex Crichton 79*7948e0ffSNick Fitzgerald /// Returns the size of a page, in bytes, for this memory. 80*7948e0ffSNick Fitzgerald /// 81*7948e0ffSNick Fitzgerald /// WebAssembly memories are made up of a whole number of pages, so the byte 82*7948e0ffSNick Fitzgerald /// size will always be a multiple of their page size. Different Wasm memories 83*7948e0ffSNick Fitzgerald /// may have different page sizes. 84*7948e0ffSNick Fitzgerald /// 85*7948e0ffSNick Fitzgerald /// By default this is 64KiB (aka `0x10000`, `2**16`, `1<<16`, or `65536`) 86*7948e0ffSNick Fitzgerald /// but [the custom-page-sizes proposal] allows opting into a page size of 87*7948e0ffSNick Fitzgerald /// `1`. Future extensions might allow any power of two as a page size. 88*7948e0ffSNick Fitzgerald /// 89*7948e0ffSNick Fitzgerald /// [the custom-page-sizes proposal]: 90*7948e0ffSNick Fitzgerald /// https://github.com/WebAssembly/custom-page-sizes page_size(Store::Context cx) const91*7948e0ffSNick Fitzgerald uint64_t page_size(Store::Context cx) const { 92*7948e0ffSNick Fitzgerald return wasmtime_memory_page_size(cx.ptr, &memory); 93*7948e0ffSNick Fitzgerald } 94*7948e0ffSNick Fitzgerald 95*7948e0ffSNick Fitzgerald /// Returns the log2 of this memory's page size, in bytes. 96*7948e0ffSNick Fitzgerald /// 97*7948e0ffSNick Fitzgerald /// WebAssembly memories are made up of a whole number of pages, so the byte 98*7948e0ffSNick Fitzgerald /// size will always be a multiple of their page size. Different Wasm memories 99*7948e0ffSNick Fitzgerald /// may have different page sizes. 100*7948e0ffSNick Fitzgerald /// 101*7948e0ffSNick Fitzgerald /// By default the page size is 64KiB (aka `0x10000`, `2**16`, `1<<16`, or 102*7948e0ffSNick Fitzgerald /// `65536`) but [the custom-page-sizes proposal] allows opting into a page 103*7948e0ffSNick Fitzgerald /// size of `1`. Future extensions might allow any power of two as a page 104*7948e0ffSNick Fitzgerald /// size. 105*7948e0ffSNick Fitzgerald /// 106*7948e0ffSNick Fitzgerald /// [the custom-page-sizes proposal]: 107*7948e0ffSNick Fitzgerald /// https://github.com/WebAssembly/custom-page-sizes page_size_log2(Store::Context cx) const108*7948e0ffSNick Fitzgerald uint8_t page_size_log2(Store::Context cx) const { 109*7948e0ffSNick Fitzgerald return wasmtime_memory_page_size_log2(cx.ptr, &memory); 110*7948e0ffSNick Fitzgerald } 111*7948e0ffSNick Fitzgerald 1123a5dda5fSAlex Crichton /// Returns the raw underlying C API memory this is using. capi() const1133a5dda5fSAlex Crichton const wasmtime_memory_t &capi() const { return memory; } 114453bb9a4SAlex Crichton }; 115453bb9a4SAlex Crichton 116453bb9a4SAlex Crichton } // namespace wasmtime 117453bb9a4SAlex Crichton 118453bb9a4SAlex Crichton #endif // WASMTIME_MEMORY_HH 119