Wasmex.Memory (wasmex v0.10.0)

Memory is a linear array of bytes to store Wasm values. The Memory module provides functions to read and write to this array.

Memory is accessible through Wasmex.Instance.memory/2, Wasmex.Memory.from_instance/2, or as the caller context of an imported function (see Wasmex.Instance.call_exported_function/5).

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Instance.memory(store, instance)
iex> Wasmex.Memory.set_byte(store, memory, 0, 42)
iex> Wasmex.Memory.get_byte(store, memory, 0)
42

Wasm memory is organized in pages of 64kb and may be grown by additional pages.

Summary

Functions

Returns the exported memory resource of the given Wasmex.Instance.

Returns the byte at the given index.

Grows the amount of available memory by the given number of pages.

Reads the given number of bytes from the given memory at the given index.

Reads the given number of bytes from the given memory at the given index.

Sets the byte at the given index to the given value.

Returns the size in bytes of the given memory.

Writes the given binary into the memory at the given index.

Types

t()

@type t() :: %Wasmex.Memory{reference: reference(), resource: binary()}

Functions

from_instance(store_or_caller, instance)

@spec from_instance(Wasmex.StoreOrCaller.t(), Wasmex.Instance.t()) ::
  {:ok, t()} | {:error, binary()}

Returns the exported memory resource of the given Wasmex.Instance.

Example

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, %Wasmex.Memory{}} = Wasmex.Memory.from_instance(store, instance)

get_byte(store_or_caller, memory, index)

@spec get_byte(Wasmex.StoreOrCaller.t(), t(), non_neg_integer()) :: number()

Returns the byte at the given index.

Example

Set a value at memory position 0 and read it back:

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.set_byte(store, memory, 0, 42)
iex> Wasmex.Memory.get_byte(store, memory, 0)
42

grow(store_or_caller, memory, pages)

@spec grow(Wasmex.StoreOrCaller.t(), t(), pos_integer()) ::
  pos_integer() | {:error, binary()}

Grows the amount of available memory by the given number of pages.

Returns the number of previously available pages. A page has a size of 64 kB or 65,536 bytes.

Returns an error if memory could not be grown.

Example

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.grow(store, memory, 1)
17

read_binary(store_or_caller, memory, index, length)

@spec read_binary(
  Wasmex.StoreOrCaller.t(),
  t(),
  non_neg_integer(),
  non_neg_integer()
) :: binary()

Reads the given number of bytes from the given memory at the given index.

Returns the read bytes as a binary.

Example

Reads 5 bytes from memory position 0, given it contains the 5 ASCII characters forming "hello".

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.write_binary(store, memory, 0, "hello")
iex> Wasmex.Memory.read_binary(store, memory, 0, 5)
"hello"
iex> Wasmex.Memory.read_binary(store, memory, 3, 2)
"lo"

read_string(store, memory, index, length)

@spec read_string(
  Wasmex.StoreOrCaller.t(),
  t(),
  non_neg_integer(),
  non_neg_integer()
) :: String.t()

Reads the given number of bytes from the given memory at the given index.

Returns the read bytes as a string.

Example

Reads 5 bytes from memory position 0, given it contains the 5 ASCII characters forming "hello".

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.write_binary(store, memory, 0, "hello")
iex> Wasmex.Memory.read_string(store, memory, 0, 5)
"hello"
iex> Wasmex.Memory.read_string(store, memory, 3, 2)
"lo"

set_byte(store_or_caller, memory, index, value)

@spec set_byte(Wasmex.StoreOrCaller.t(), t(), non_neg_integer(), number()) ::
  :ok | {:error, binary()}

Sets the byte at the given index to the given value.

Example

Set a value at memory position 0 and read it back:

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.set_byte(store, memory, 0, 42)
iex> Wasmex.Memory.get_byte(store, memory, 0)
42

size(store_or_caller, memory)

@spec size(Wasmex.StoreOrCaller.t(), t()) :: pos_integer()

Returns the size in bytes of the given memory.

Note that the size of the memory is always a multiple of 64kb (one page).

Example

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.size(store, memory)
1114112 # in bytes (17 pages of 64 kB)

write_binary(store_or_caller, memory, index, binary)

@spec write_binary(
  Wasmex.StoreOrCaller.t(),
  t(),
  non_neg_integer(),
  binary()
) :: :ok

Writes the given binary into the memory at the given index.

Example

Writes 5 bytes representing the ASCII characters for "hello" at memory position 0.

iex> %{store: store, module: module} = TestHelper.wasm_module()
iex> {:ok, instance} = Wasmex.Instance.new(store, module, %{})
iex> {:ok, memory} = Wasmex.Memory.from_instance(store, instance)
iex> Wasmex.Memory.write_binary(store, memory, 0, "hello")
:ok