1/* @ajax/mesh-exec-wasm-imports: the `mesh::*` imports (mesh-abi v2::wasm) of meshd's wasm
2 * executor, ported from mesh-host/src/wasm.rs (`LaneData`, `linker`, `copy_out`, `copy_in`).
3 *
4 * A guest has no pointer into the mailbox: every access names a window (W_VIEW, W_EXCHANGE for
5 * the lockstep program, W_PEER + s for a view `peer` resolved for this task) and an offset, and is
6 * bounds-checked against the slot's own words exactly as mesh-rt's View is (out of range: reads 0,
7 * writes dropped, P_FAULT = FAULT_VIEW_BOUNDS | off << 8, the first fault kept; meshd fails the
8 * slot). Loads are acquire, stores release, read-modify-writes acq_rel. */
9#ifndef MESH_EXEC_WASM_IMPORTS_H
10#define MESH_EXEC_WASM_IMPORTS_H
1112#include "mesh/abi/base.h"
13#include "mesh/mailbox.h"
14#include "wasm/interp.h"
1516#include <stdatomic.h>
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
2021/* A lane's store data: its slot's windows, the task's peer views, the budget. */
22typedef struct {
23 mesh_mailbox mb;
24 uint32_t slot, node, nodes;
25 size_t view_off; /* the own view: mailbox offset, bytes */
26 uint32_t view_len;
27 uint32_t req_off, req_max;
28 uint32_t resp_off, resp_max;
29 uint32_t input_off, input_len;
30 bool lockstep;
31 /* Peer views resolved for the running task (`mesh::peer`). */
32 bool peer_set[MESH_PROG_SLOTS];
33 size_t peer_off[MESH_PROG_SLOTS];
34 uint32_t peer_len[MESH_PROG_SLOTS];
35 uint32_t ticket;
36 /* The task's epoch budget (re-armed after an exchange's wait). */
37 uint64_t ticks;
38 /* The engine's epoch counter (the deadline counts its ticks). */
39 const _Atomic uint64_t *epoch;
40} mesh_wasm_lane_data;
4142/* Reads the slot's table entry (stable while it runs: meshd rewrites it only halted). */
43void mesh_wasm_lane_data_init(mesh_wasm_lane_data *d, mesh_mailbox mb, uint32_t slot, uint32_t node, uint32_t nodes,
44 uint32_t task_ms, const _Atomic uint64_t *epoch);
45/* A new task: no peer views resolved, its ticket. */
46void mesh_wasm_lane_data_task(mesh_wasm_lane_data *d, uint32_t ticket);
4748/* The slot's first fault (P_FAULT keeps only the first). */
49void mesh_wasm_lane_fault(const mesh_wasm_lane_data *d, uint32_t code);
50/* The mailbox offset of n bytes at off in window h, align-aligned: true with *at, or false (and
51 * the fault mesh-rt's View records). */
52bool mesh_wasm_lane_at(const mesh_wasm_lane_data *d, uint32_t h, uint32_t off, uint32_t n, size_t align, size_t *at);
53/* The slot's reads mask now: its own entry under the PT_GEN seqlock. */
54uint32_t mesh_wasm_lane_reads_mask(const mesh_wasm_lane_data *d);
55/* Slot s's view for this task, if `reads` lists it: its length, or -1. */
56int32_t mesh_wasm_lane_peer(mesh_wasm_lane_data *d, uint32_t s);
5758/* Window bytes at mailbox offset a into dst (word loads where aligned), and back. */
59void mesh_wasm_copy_out(mesh_mailbox mb, size_t a, uint8_t *dst, size_t n);
60void mesh_wasm_copy_in(mesh_mailbox mb, size_t a, const uint8_t *src, size_t n);
6162/* The `mesh::*` imports, shared by every image: an instance's user pointer must be its lane's
63 * mesh_wasm_lane_data. */
64const wasm_host_func *mesh_wasm_imports(size_t *n);
6566#endif