# `F3.Wasm`

Loads one embedded Wasm module after the caller has opted in.

Metadata inspection does not call this module. `lib_urls` are not read.
The section named `WASMBinaries` is a FlatBuffers table of offsets. The
module bytes are read only for the `wasm_id` on the encoding unit, and
only when `F3.Dispatch` has already chosen `:wasm`.

The host fuel budget is 5000000 instructions. Upstream does not set
fuel. Linear memory is capped at 8 MiB. A module is at most 1 MiB unless
`wasm_module_bytes:` raises that, and never above 16 MiB. An omitted
`wasm_id` selects module 0.

# `decode`

```elixir
@spec decode(map(), map(), binary(), atom()) ::
  {:ok, F3.Column.t()} | {:error, F3.Error.t()}
```

Decodes one unit with the sandboxed host. The module bytes do not leave
the NIF as an Arrow buffer. The return is an owned `F3.Column`.

`plan` must include `:operation`. A nested `type` is
`:unsupported_encoding` and does not load a module. A missing Wasm section
is `:corrupt`. This raises `KeyError` when `plan.operation` is absent.

## Examples

    iex> plan = %{operation: :read}
    iex> {:error, error} = F3.Wasm.decode(plan, %{}, <<>>, :list)
    iex> error.category
    :unsupported_encoding

# `default_module_bytes`

```elixir
@spec default_module_bytes() :: pos_integer()
```

Default maximum module size, in bytes.

## Examples

    iex> F3.Wasm.default_module_bytes()
    1_048_576

# `fuel`

```elixir
@spec fuel() :: pos_integer()
```

Instruction budget passed to Wasmtime. Upstream sets no fuel.

## Examples

    iex> F3.Wasm.fuel()
    5_000_000

# `max_module_bytes`

```elixir
@spec max_module_bytes() :: pos_integer()
```

Hard maximum for `wasm_module_bytes:`. The pinned built-in module is
larger than 8 MiB, so the ceiling is 16 MiB.

## Examples

    iex> F3.Wasm.max_module_bytes()
    16_777_216

# `memory_bytes`

```elixir
@spec memory_bytes() :: pos_integer()
```

Linear memory cap, in bytes.

## Examples

    iex> F3.Wasm.memory_bytes()
    8_388_608

# `modules`

```elixir
@spec modules(binary()) :: {:ok, [map()]} | {:error, F3.Error.t()}
```

Parses a `WASMBinaries` FlatBuffers root. Field `lib_urls` is not walked.
A buffer that is not a table is `:corrupt`. A non-binary raises no error
here. It returns the same `:corrupt` error.

## Examples

    iex> {:error, error} = F3.Wasm.modules(<<>>)
    iex> error.message
    "wasm section is truncated"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
