# "WASM Functions" _Path: en/wasm/functions_ > "Configure inline WAT functions and precompiled WASM functions as registry entries." ## Table of Contents - WASM Functions ## Content # WASM Functions Use `function.wat` for inline WebAssembly Text source and `function.wasm` for precompiled binaries. **Classification: function configuration reference.** WAT blocks are small registry examples. Precompiled examples assume an external component build, a filesystem entry, exported methods matching the guest WIT, and a SHA-256 digest calculated from the exact binary. Real-looking sample hashes are illustrative. ## Inline WAT Functions Define a WAT function directly in `_index.yaml`: ```yaml entries: - name: answer kind: function.wat source: | (module (func (export "answer") (result i32) i32.const 42 ) ) wit: | answer: func() -> s32; method: answer pool: type: inline ``` For larger WAT sources, use a file reference: ```yaml - name: answer kind: function.wat source: file://answer.wat wit: | answer: func() -> s32; method: answer pool: type: inline ``` ### WAT Configuration Fields | Field | Required | Description | |-------|----------|-------------| | `source` | Yes | Inline WAT source or `file://` reference | | `method` | Yes | Exported function name to call | | `wit` | No | WIT signature for raw/core modules | | `pool` | No | Worker pool configuration | | `transport` | No | Input/output mapping (default: `payload`) | | `imports` | No | Host imports to enable (e.g., `wasi:cli`, `wasi:io`) | | `wasi` | No | WASI configuration (args, env, mounts) | | `options.limits` | No | Execution limits (`limits` remains a deprecated compatibility spelling) | ## Precompiled WASM Functions Load compiled `.wasm` binaries from a filesystem entry: ```yaml entries: - name: assets kind: fs.directory directory: ./wasm - name: compute kind: function.wasm fs: myns:assets path: /compute.wasm hash: sha256:292b796376f8b4cc360acf2ea6b82d1084871c3607a079f30b446da8e5c984a4 method: compute pool: type: lazy max_size: 4 ``` ### WASM Configuration Fields | Field | Required | Description | |-------|----------|-------------| | `fs` | Yes | Filesystem entry ID containing the binary | | `path` | Yes | Path to `.wasm` file within the filesystem | | `hash` | Yes | SHA-256 hash for integrity verification (`sha256:...`) | | `method` | Yes | Exported function name to call | | `wit` | No | WIT signature for raw/core modules | | `pool` | No | Worker pool configuration | | `transport` | No | Input/output mapping (default: `payload`) | | `imports` | No | Host imports to enable | | `wasi` | No | WASI configuration | | `options.limits` | No | Execution limits (`limits` remains a deprecated compatibility spelling) | ## Worker Pools Each WASM function uses a pool of pre-compiled instances. The pool type controls concurrency and resource usage. | Type | Description | |------|-------------| | `inline` | Mutex-serialized. Synchronous and asyncified calls reuse one warm instance; retained-memory policy or an execution failure can trigger replacement. | | `lazy` | Zero idle workers. Scales on demand up to `max_size`. | | `static` | Fixed number of workers with request queue. | | `adaptive` | Auto-scaling elastic pool. | ### Pool Configuration ```yaml pool: type: static size: 4 # Total pool size workers: 2 # Worker threads buffer: 16 # Request queue buffer (default: workers * 64) ``` ```yaml pool: type: lazy max_size: 8 # Maximum concurrent instances ``` ```yaml pool: type: adaptive max_size: 16 # Upper scaling bound ``` The 100-worker default applies only to the implicitly selected pool (when no `type` is set). When you explicitly set `type: lazy` or `type: adaptive` without `max_size`, the default maximum is 16 workers. ### Worker Classes and Core Affinity Setting `pool.worker_class` routes the function to a dedicated pool of OS-thread-pinned workers instead of the shared pool types above (`type` is ignored when set; conventional name: `wasm`): ```yaml pool: worker_class: wasm workers: 8 # optional; defaults to reserved cores, else min(NumCPU, 4) ``` Core isolation is opted into per runtime in `.wippy.yaml`: ```yaml scheduler: wasm_isolation: enabled: true # default: false reserved_cores: 2 # cores reserved for WASM pools (default: 1) ``` With isolation enabled, the actor scheduler and the pinned WASM pools run on disjoint CPU sets (`sched_setaffinity`, Linux only — other platforms size the pools but do not bind threads). Long-running WASM calls then cannot starve actor scheduling. ## Transports Transports control how input and output are mapped between the runtime and the WASM module. | Transport | Description | |-----------|-------------| | `payload` | Maps runtime payloads directly to WASM call arguments (default) | | `wasi-http` | Maps HTTP request/response context to WASM arguments and results | ### Payload Transport The default transport passes arguments directly. Lua values are transcoded to Go types, then lowered to WIT types: ```yaml - name: compute kind: function.wasm fs: myns:assets path: /compute.wasm hash: sha256:... method: compute pool: type: inline ``` ```lua -- Arguments passed directly as WASM function parameters local result, err = funcs.call("myns:compute", 6, 7) if err then return nil, err end -- result: 42 ``` ### WASI HTTP Transport The `wasi-http` transport maps HTTP requests to WASM and writes results back to the HTTP response. Use this to expose WASM functions as HTTP endpoints: ```yaml - name: greet_wasm kind: function.wasm fs: myns:assets path: /greet.wasm hash: sha256:... method: greet transport: wasi-http pool: type: inline - name: greet_endpoint kind: http.endpoint meta: router: myns:api method: POST path: /api/greet func: greet_wasm ``` ## Execution Limits The `options.limits` block bounds a function's execution time, its warm-worker memory, and the sockets it may open: ```yaml options: limits: max_execution_ms: 5000 max_retained_memory_bytes: 134217728 retained_memory_check_interval: 32 max_open_sockets: 8 socket_timeout_ms: 5000 ``` | Field | Default | Description | |-------|---------|-------------| | `max_execution_ms` | unlimited | Wall-clock budget for one call. When exceeded, the execution is cancelled and an error is returned. | | `max_retained_memory_bytes` | `67108864` (64 MiB) | Post-call recycling trigger. A warm worker whose linear memory exceeds this is retired after the call instead of being reused. An explicit `0` disables retained-memory recycling. | | `retained_memory_check_interval` | `16` with the built-in limit, every call with an explicit limit | Number of calls between post-call memory inspections. | | `max_open_sockets` | `16` | Concurrently open connections per instance for the `socket` host. | | `socket_timeout_ms` | `30000` | Deadline for a `socket` dial and for each send/receive. | Negative values are rejected at boot. The root `limits` and `meta.options.limits` spellings are accepted temporarily with a deprecation warning. Keep `pool` at the entry root; it has not moved under `options`. ## WASI Configuration Configure WASI capabilities for the guest module: ```yaml wasi: args: ["--verbose"] cwd: "/app" env: - id: myns:api_key name: API_KEY required: true - id: myns:debug_mode name: DEBUG mounts: - fs: myns:data_files guest: /data read_only: true - fs: myns:output guest: /output ``` | Field | Description | |-------|-------------| | `args` | Command-line arguments passed to the guest | | `cwd` | Working directory inside the guest (must be absolute) | | `env` | Environment variables mapped from registry env entries | | `mounts` | Filesystem mounts from registry filesystem entries | Environment variables are resolved from the environment registry at call time. Required variables cause an error if not found. Mount paths must be absolute and unique. Each mount maps a runtime filesystem entry to a guest directory path. ### Data Transformation Pipeline ```yaml entries: - name: wasm_binaries kind: fs.directory directory: ./wasm - name: transform_users kind: function.wasm fs: myns:wasm_binaries path: /mapper.wasm hash: sha256:7304fc7d19778605458ae5804dae9a7343dcd3f5fc22bcc9415e98b5047192dd method: transform-users pool: type: lazy max_size: 4 - name: filter_active kind: function.wasm fs: myns:wasm_binaries path: /mapper.wasm hash: sha256:7304fc7d19778605458ae5804dae9a7343dcd3f5fc22bcc9415e98b5047192dd method: filter-active pool: type: lazy max_size: 4 ``` ```lua local funcs = require("funcs") local users = { {id = 1, name = "Alice", tags = {"admin", "dev"}, active = true}, {id = 2, name = "Bob", tags = {"user"}, active = false}, {id = 3, name = "Carol", tags = {"dev"}, active = true}, } -- Transform: adds display field and tag count local transformed, err = funcs.call("myns:transform_users", users) if err then return nil, err end -- Filter: returns only active users local active, filter_err = funcs.call("myns:filter_active", users) if filter_err then return nil, filter_err end ``` ### Async Sleep with WASI Clocks WASM components that import `wasi:clocks`, `wasi:io` and `wasi:poll` can use clocks and polling. The async yield mechanism integrates with the Wippy dispatcher: ```yaml - name: sleep_ms kind: function.wasm fs: myns:wasm_binaries path: /sleep_test.wasm hash: sha256:... method: "test-sleep#sleep-ms" imports: - wasi:io - wasi:poll - wasi:clocks pool: type: inline ``` The `#` separator in the method field references an interface method: `test-sleep#sleep-ms` calls the `sleep-ms` function from the `test-sleep` interface. ## See Also - [Overview](wasm/overview.md) - WebAssembly runtime overview - [Host Functions](wasm/hosts.md) - Available host interfaces - [Processes](wasm/processes.md) - Running WASM as processes - [Entry Kinds](guides/entry-kinds.md) - All registry entry kinds ## Navigation Previous: "WebAssembly Runtime" (wasm/overview) Next: "Host Functions" (wasm/hosts)