Guidance for AI coding agents working on the mori package. mori — Shared Memory for R Objects: POSIX shared memory (Linux, macOS) / Win32 file mappings (Windows) + R's ALTREP framework let processes on one machine read the same physical pages. No external dependencies; requires R >= 4.3.0 (ALTLIST). R API (all thin .Call wrappers; logic is C-level): share(), map_shared(), shared_name(), is_shared(), prune_shared(). ALTREP serialization hooks emit the shared_name() identifier as the wire form — transparent under serialize() and mirai.
Claude Code users: add .claude/CLAUDE.md containing @../AGENTS.md (.claude/ is gitignored).
devtools::test() # full suite (testthat ed 3)
testthat::test_file("tests/testthat/test-nested.R") # single test file
devtools::document() # roxygen2 -> man/, NAMESPACE
rmarkdown::render("README.Rmd") # rebuild README.mdR CMD build .
R CMD check --no-manual --compact-vignettes=gs+qpdf mori_*.tar.gz # matches CI
bash tools/vendor.sh # re-vendor both layers: region (shm.c, mori_region.h) from libmizu, view (mori.h, altrep.c, serialize.c) from mizu
bash tools/vendor.sh --region-only # region layer only; --view-only for the view layer; --mizu/--libmizu override the refsConfig/build/compilation-database: truein DESCRIPTION →compile_commands.jsonon install (gitignored); clangd works out of the box.- R's in-source build ignores header dependencies: after re-vendoring,
rm src/*.o src/*.sobefore reinstalling — stale objects linked against old struct layouts cause sizeof mismatches and garbage fields. src/shm.candsrc/mori_region.hare vendored from libmizu bytools/vendor.sh(pinned ref, enumerated substitutions, self-grep gate) — never edit them by hand; changes go upstream to libmizu and are pulled by re-running the script. shm.c vendors without its public handle API (banner-to-EOF strip) and err_tls.c not at all: the view layer drives the stack/heap ext tier and reads themori_shmstruct fields directly, and the TLS error slot is embedder surface mori never reads — region failures are reported viamori_err_describe.mori_region.halso carries the carved wire-format helpers (mori_mors_geometry,mori_morh_validity_set,mori_na_build, the MIZL directory-entry readermori_morl_elemand its chain, the type tags) the view layer resolves onto.src/mori.h,src/altrep.candsrc/serialize.c— the view layer: the ALTREP consumer classes, the MORH/MORS/MORL layout oracle/writer, and the exact-size serialize streams — are vendored from mizu by the same script (pinned ref, the reverse substitution set, self-grep gate). The layouts have a single home: the canonical layer is first-class code in mizu and mori tracks it, so the byte format cannot drift between the two packages. Never edit these files by hand either; changes go upstream to mizu. After substitution the script strips the embedder-only surface mori never calls (anchored range deletes plus a carve gate; see the carve block intools/vendor.sh): the u64 landing class, the attrs interchange parse/match island, the hook setters, the remote-leaf directory walk,mori_release_now,mori_altrep_fini, the exported layout wrappers (mori_layout_size/mori_layout_size_sums), and the strictmori_is_int64. What remains of the embedder hooks is the typedefs and always-NULL statics that live code reads. Unless--libmizuis given, the region layer's ref is derived from the libmizu pin recorded in mizu's ownsrc/vendor/libmizu/VENDOR— the pairing mizu was built against.
- Zero-copy (SHM-backed): atomic vectors (any type/attributes) and data frame columns are written into SHM and ALTREP-backed on consumers; attributes serialize into a trailing region, reapplied on open. Numeric
Dataptr_or_nullreturns the SHM pointer;Dataptr(writable=TRUE)triggers COW into a private copy. Strings live in an Arrow large_utf8-shaped block (validity bitmap + i64 offsets + encoding bytes + packed data);Eltcreates CHARSXPs lazily;Dataptr_or_nullreturns NULL to force per-element access. - Validity bitmaps: MORS string blocks carry one always — it is the NA test at string
Elt(strings have no sentinel). The MORH/MORL header sections [40-55] are cross-language surface only: three states ({0,0} absent, {0,-1} known-NA-free, else bitmap offset + null count), built solely by the foreign staging mode (foreign = 1, embedders); the host path leaves them absent (NAs ride the sentinels) and no mori reader consults them. - int64: class-only
integer64vectors (REALSXP storage, no S4, non-ALTREP; the_anytest admits ALTREP storage) ride the wire as tag 32 (MORI_TYPE_INT64) in the header sexptype / directory entry — no attrs blob (the tag carries the class). - Nested lists (zero-copy): VECSXP/LISTSXP elements are written inline as a complete child MORL region at their
data_offset, each level wrapped in its own ALTLIST. Sub-lists areis_shared()-TRUE with path-bearingshared_name()s;map_shared(shared_name(sub))opens them directly. The OS region name is the prefix before[(sub("\\[.*$", "", shared_name(x))). - Pass-through: everything else (environments, closures, language, NULL) is returned unchanged; no SHM created.
Write-once on host, read-many on consumers, COW for any mutation.
- Each
share()allocates a fresh region; existing regions are never mutated. No locking anywhere — any change admitting in-place mutation breaks the model. - Names embed creator PID + randomly-seeded per-process counter (
mori_<pid>_<counter>,mori_region_name).mori_shm_create_heapusesO_EXCL/ERROR_ALREADY_EXISTS; a collision (orphan of a crashed same-PID process) is an error (MORI_ERRCAT_EXISTS), never worked around by reuse. prune_shared()clears such orphans; it must run while the PID is free — a live process cannot reap its own names.- The host writes the full region before its name is observable — partial writes are never seen. Consumer mappings are read-only (
PROT_READ/FILE_MAP_READ); mutation triggers COW. - Fork safety:
mori_shmrecords the creator PID;mori_host_finalizerunlinks only ongetpid()match, so a forked child's inherited finalizers skip the unlink (itsmunmapis process-local) —parallel::mclapplyforks cannot destroy parent regions.
- Already mori-backed (
mori_view_check) → returnxunchanged. Idempotence required: re-sharing a sub-list view must not allocate a fresh root region (would breakshared_name()). - Otherwise sizes via
mori_layout_size_impl(x, NULL, 0)(ok = NULL,foreign = 0— no vetoes; non-mori ALTREPs materialize throughDATAPTR_ROat write) and writes viamori_layout_write(base, x, 0); 0 size →xreturned as-is. Type ladder:VECSXP/LISTSXP→ MORL (pairlists coerced to VECSXP at every level; data frames included),STRSXP→ MORS, atomics (REALSXP/INTSXP/LGLSXP/RAWSXP/CPLXSXP) → MORH, everything else (incl.NILSXP) → pass-through.
The result returns via mori_make_result, which chains the host extptr into the ALTREP's keeper chain (see Internal State and Lifetime).
All writers are count-then-write pairs: mori_serialize_count/mori_serialize_into (serialize.c, fallback bytes), mori_attrs_size/mori_attrs_write (attribute blobs, honoring the embedder hooks), mori_nested_size/mori_nested_write (MORL regions), morh_size/morh_write, mors_size/mors_write. If a pair disagrees by even one byte, the region is malformed and consumers read garbage. Mirror every change in both sides. Exception by design: the foreign staging mode (foreign = 1) reserves validity-section bytes in the size pass that a clean (NA-free) write never spends — there the write returns the actual bytes used, always ≤ the size pass; on the host path (foreign = 0) the two agree exactly.
Declared in mori.h, C-level only (not .Call). mori is the consumer here, not an embedder target: the full embedder API lives upstream in mizu, and tools/vendor.sh strips the parts mori never calls (see the vendoring note above). What remains:
- Layout writer (internal):
mori_layout_size_impl(x, ok, foreign, sp)/mori_layout_write(base, x, foreign)— the exported wrappers are stripped;mori_createdrives the impl directly. The S4 object bit rides the layouts: header flags word at offset 32 (MORI_FLAG_S4) for MORH/MORS/MORL roots and nested lists, bit 30 of the directory entry'ssexptype(MORI_ELEM_S4) for vector/string leaves; applied withRf_asS4after attributes land. Theok/spveto machinery and theforeign = 1staging mode (validity sections,*_GET_REGIONcopies of admitted ALTREP atomics) are retained but dead in mori (ok/spalways NULL,foreignalways 0) — they are excluded from coverage (tools/coverage-exclusions.R), not carved, being interleaved with live code.mori_layout_writereturns the actual bytes written: exactly the size pass whenforeign == 0, at most that in the foreign staging mode (clean leaves' unspent validity reserve); it zeroes reserved header bytes [24-63] on every write (embedders may recycle regions). - Wrap constructors:
mori_vec_wrap/mori_str_wrap/mori_list_wrapbuild views over memory, pinningkeepervia the data1 extptr's protected slot; each takes areleaseonce-hook (see Internal State — never armed in mori).mori_restore_attrsreapplies a trailing attribute blob: the read hook's encoding when the blob's first byte is the 'I' interchange magic (MORI_INTEROP_MAGIC), elseR_Unserialize. - Introspection + resolve:
mori_view_check,mori_shm_name,mori_parse_id,mori_walk_path(walks an index path over an open region; the caller's keeper flows into the result's chain),mori_is_int64_any,mori_resolve_id(id, keeper)(the one identifier resolve path: parse, open-or-cache, wrap root or walk, fire the resolve hook — always a no-op in mori; a non-NULLkeepercomposes behind a fresh chain terminus),mori_refable,mori_remote_id,mori_chain_shm,mori_path_entry. - Hooks: the wire/open/attrs hook typedefs and statics remain and are read on the hot paths (
mori_emit_hook,mori_resolve_hook,mori_open_hook, the attrs blob hooks) — always NULL in mori since the setters are stripped.
Registered in mori_altrep_init. Numerics (mori_real/integer/logical/raw/complex) share the mori_vec pattern (SHM-backed data pointer). mori_string (mori_str) does lazy per-element Elt via Rf_mkCharLenCE: NA from the validity bitmap (mori_str_valid), the span [offsets[i], offsets[i+1]) bounds-checked against str_bytes (and INT_MAX), the encoding byte range-checked; the two end offsets are checked O(1) at wrap (mori_str_wrap). mori_list (mori_list_view) has a per-element directory and a lazy Elt cache using R_NilValue as the uncached sentinel (a fresh VECSXP is NIL-filled — zero init work). NIL elements are the sole singleton output of mori_unwrap_element's fallback path, so they're never cached and identity is preserved.
Any method returning a writable pointer (or mutating) must check R_altrep_data2(x) first — if non-null, the vector is materialized and the SHM pointer is no longer authoritative. New Dataptr / coercion methods routinely forget this. COW materialization also fires the view's release hook early (see Internal State).
All classes register Serialized_state + Unserialize.
- Wire form (single canonical shape):
mori_format_chainis the single source of truth formori_shm_name(the.Call) and allSerialized_statemethods — walks the keeper chain collectingview->index(>= 0only), formats<prefix>(root) or<prefix>[i1+1,...](sub-object). 1-based externalisation cues R's[[i]]; the parser converts back. - Unserialize:
mori_Unserialize(vec/list) andmori_string_Unserialize. Vec/list: a STRSXP state is always an identifier (their fallbacks are never STRSXP) — probed viamori_shm_open_and_wrap, a miss errors (corrupt stream); other states are materialized data. Strings: both forms are string-like, so the fallback is wrapped in a length-1 VECSXP (mori_wrap_string_state) — bare STRSXP = identifier, wrapper = data (unwrapped without probing). All identifier resolves route throughmori_resolve_id(parse, open-or-cache through the consumer LRU, wrap the root or walk the path, fire the resolve hook); the walk's intermediates step viamori_make_extptr(bare keeper-chain extptrs, no ALTLIST/attrs — never observed), leaf viamori_unwrap_element. - Wire hooks:
emit(view)fires fromSerialized_statewhen an identifier (not a materialization) is emitted;resolve(view, shm)fires after the wrap insidemori_resolve_id— notmori_walk_path, whose direct callers fire their own. Never fires in mori: the setters are stripped at vendoring (mizu sets them at embedder load for its cross-process lifetime protocol: flag regions on escape, count remote references on arrival).
Fallback to full materialization when: data2 is set (COW'd), or nesting exceeds MORI_MAX_PATH (64).
identifier ::= prefix [ "[" int1 ("," int1)* "]" ]
prefix ::= MORI_PREFIX_LITERAL hex+ "_" hex+
hex+ ::= [0-9a-f]+ # lowercase
int1 ::= [1-9][0-9]* # 1-based, no leading zeros
MORI_PREFIX_LITERAL (mori.h: /mori_ POSIX, Local\\mori_ Windows) is the single source of truth shared by shm.c's name-format strings and the parser's memcmp — change once, both sides stay in sync. Variable-width hex; MORI_NAME_MAX = 30 bounds the prefix on both platforms. mori_parse_id is bounded and single-pass (MORI_IDENTIFIER_MAX); indices stored 0-based; the path loop uses NUL as sentinel (every fail-branch excludes \0). Sizing invariant: MORI_NAME_MAX + 2 + 11 × MORI_MAX_PATH < MORI_FORMAT_BUFLEN.
map_shared and unserialize share mori_parse_id for shape validation but differ in failure mode: malformed → NULL (wrong type/length, NA, bad prefix/path); well-formed but unmappable → error (missing region, bad magic, truncated header, OOB index, non-VECSXP intermediate, fields inconsistent with mapped size). Consumer validation is total — corrupt input errors, never reads out of bounds: root headers vs mapped size (mori_open_vector/mori_open_string), the format flags word at every header read (mori_flags_known — an unknown set bit rejects as corrupt-or-newer), directory entries vs data region incl. the 64-byte alignment of data_offset (mori_unwrap_element), string blocks vs region (mori_str_wrap, O(1) on the two end offsets), spans at Elt. Preserve this split in mori_shm_open_and_wrap — collapsing it either way breaks the probe-vs-corruption distinction.
Magic in the first 4 bytes (MORI_MAGIC_*): MORH 0x4D4F5248 vector, MORL 0x4D4F524C list, MORS 0x4D4F5253 string. Every layout opens with a 64-byte header; bytes [24-31] are reserved for embedder cross-process state, [32-35] hold the format flags word (bit 0: S4 object bit; any other set bit rejects the region as corrupt-or-newer — mori_flags_known), [36-39] are reserved, [40-47]/[48-55] hold the optional validity section for MORH and MORL (i64 offset, i64 null count: {0,0} absent, {0,-1} known-NA-free, else the offset of a 64-byte-aligned bitmap section; MORS carries its bitmap in the string block instead), [56-63] are reserved (all zeroed on every write — embedders may recycle regions). Tables are the canonical spec; mori_nested_write / morh_write / mors_write (with mori_attrs_write or mori_serialize_into for attrs and fallbacks) are the implementations. Attributes are serialized R objects (pairlist on R < 4.6, named list otherwise) unless the embedder attrs hooks supply another encoding; mori_restore_attrs reapplies them on the consumer.
MORH — atomic vector. Data at byte 64 (64-byte aligned for SIMD); trailing attrs after the data.
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | magic |
| 4 | 4 | sexptype (MORI_TYPE_INT64 = 32 for class-only integer64 — no attrs) |
| 8 | 8 | length (int64) |
| 16 | 8 | attrs_size (int64, 0 if none) |
| 24 | 8 | reserved (zero) — embedder cross-process state |
| 32 | 4 | flags (bit 0: S4 object bit) |
| 36 | 4 | reserved (zero) |
| 40 | 8 | validity bitmap offset (0 = absent / known-NA-free) |
| 48 | 8 | null count (0 or -1 when offset is 0) |
| 56 | 8 | reserved (zero) |
| 64+ | raw vector data | |
| 64 + length×elt_size | serialized attributes (if attrs_size > 0), then the optional validity bitmap (foreign writes) |
MORL — ALTLIST. Header + element directory + per-element data regions.
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | magic |
| 4 | 4 | n_elements (int32) |
| 8 | 8 | attrs_offset (int64) |
| 16 | 8 | attrs_size (int64) |
| 24 | 8 | reserved (zero) — embedder cross-process state |
| 32 | 4 | flags (bit 0: S4 object bit) |
| 36 | 4 | reserved (zero) |
| 40 | 8 | validity table offset (0 = absent / known-NA-free) |
| 48 | 8 | total null count across leaves (0 or -1 when offset is 0) |
| 56 | 8 | reserved (zero) |
| 64 | 32×n | element directory |
| varies | element data (each 64-byte aligned), then serialized attributes, then the optional validity tail (foreign writes) |
Directory entry (32 bytes): data_offset(8, 64-byte aligned — enforced at read) + data_size(8) + sexptype(4) + attrs_size(4) + length(8). sexptype: 0 → serialized bytes (serialize.c); STRSXP → a string block (the MORS body layout) at data_offset; VECSXP → nested MORL region inlined at data_offset of size data_size (child header/directory/elements/attrs all inline; parent's attrs_size always 0 for VECSXP children); MORI_TYPE_INT64 (32) → class-only integer64 leaf (the tag carries the class — no attrs blob); 33 → remote leaf (the column lives in another region: data_offset/data_size span its identifier — name with optional index path, 1-255 bytes — resolved by reference through the consumer open + path walk, with the entry's length/attrs/NA claims cross-checked against the referenced region; mori_nested_write emits it when a list being shared holds an already-shared, attribute-free view as an element (mori_refable), and the S4 bit is never set); other → raw zero-copy data, with bit 30 of sexptype (MORI_ELEM_S4) flagging an S4 leaf (masked off at read). Non-VECSXP attrs sit at data_offset + data_size - attrs_size. The foreign-mode validity tail: one LSB-first bitmap per NA-capable atomic leaf (1 = present, spent only where NAs are present), then an n-entry table of {i64 offset, i64 null count} pairs the header's validity words point at; a VECSXP/STRSXP leaf's pair is {0,0} (the nested header / string block carries its own).
MORS — ALTSTRING. Header + string block + optional trailing attrs.
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | magic |
| 4 | 4 | attrs_size (int32, 0 if none) |
| 8 | 8 | n_strings (int64) |
| 16 | 8 | str_data_size (int64: the string block's byte size, incl. padding) |
| 24 | 8 | reserved (zero) — embedder cross-process state |
| 32 | 4 | flags (bit 0: S4 object bit) |
| 36 | 28 | reserved (zero) |
| 64 | str_data_size | the string block |
| 64 + str_data_size | serialized attributes (if attrs_size > 0) |
The string block (also the form of a STRSXP element in MORL regions, at the entry's data_offset; element attrs use the directory entry's attrs_size): four sections, each 64-byte aligned from the block start — validity bitmap (ceil(n/8) bytes, LSB first: 1 = present, 0 = NA), offsets ((n+1) int64; offsets[0] = 0, non-decreasing; string i is data[offsets[i], offsets[i+1]), an NA spans zero bytes), encoding (n bytes; cetype_t: 0=native, 1=UTF-8, 2=Latin-1, 3=bytes), then the packed string bytes (no terminators). The first, second and fourth are Arrow large_utf8's three buffers verbatim; the encoding section is R's per-CHARSXP mark. Section offsets come from one geometry function (mori_mors_geometry in mori_region.h, wrapped by mori_str_geometry in mori.h). The block carries its own validity bitmap — MORS headers have no [40-55] section.
SHM lifetime is automatic via chained extptr finalizers. Three interned tags (C globals in altrep.c):
mori_shm_tag— SHM mapping extptr (both sides). Addrmori_shm *; finalizermunmap.mori_host_tag— host-only unlink extptr frommori_make_result; addrmori_shm *(name on POSIX, HANDLE on Windows); finalizershm_unlink/CloseHandle, skipped when creatorpid≠getpid()(fork guard). Chained above the shm extptr.mori_owned_tag— every malloc-backed extptr: ALTREP data1 (view/vec/str) and bare path-walk intermediates (mori_make_extptr, alwaysmori_list_view *). Addr type at the ALTREP boundary fromTYPEOF(x):VECSXP → mori_list_view *,STRSXP → mori_str *, elsemori_vec *.indexfield: -1 standalone/root, >= 0 element. Finalizermori_owned_finalizer: release hook once, thenfree.
Release hook: every owned struct embeds mori_owned (release + release_arg) as its first member, so the finalizer recovers it from any addr. Fires exactly once (mori_release_once's NULL store) — at COW materialization or the finalizer, whichever first; internal callers pass NULL. ALTLIST views fire at the finalizer only: extracted elements keep referencing the region.
is_shared() = mori_view_check (ALTREP with mori_owned_tag data1). mori_shm_name() = mori_format_chain (bare prefix for roots, path form for sub-objects).
- Host:
mori_shm_create_heapmmaps (POSIX fd closed after mmap);mori_make_resultsplits ownership — ALTREP gets the mapping (mori_shm_tagextptr), the host unlink extptr is chained as itsprot. Both finalizers run at GC;R_RegisterCFinalizerEx(..., TRUE)covers session exit. - Consumer:
mori_shm_open_heapmaps read-only (never unlinks). Prefix-opened lists: shm extptr → root view extptr (index -1) → data1;Eltsub-lists chain through parent views. Path-form: intermediates are bare extptrs, only the leaf gets an ALTLIST. Element vec/str extptrs'protis the parent view (shm extptr at root). The resolve paths (map_shared, the ALTREP Unserialize methods) dedupe consumer mappings through a process-global name-keyed LRU cache (MORI_CACHE_MAX= 16 slots, the vendoredmori_open_consumer; eviction drops the cache's reference, never unmaps under a live view): repeated opens of one region share one mapping, which then lives until cache eviction + the last view over it is GC'd, and stays read-only (a write attempt COWs). Caveat: an unlinked name still resolves while cached (stale-but-valid pages instead of "not found") — this softensprune_shared()finality until eviction. - Lifetime: leaves pin the root SHM through the chain (leaf → views → shm → host); every
R_MakeExternalPtrretains itsprot, so the chain survives GC of enclosing ALTLISTs.mori_format_chainis the only chain walker (mori_owned_taghops, alwaysmori_list_view *).
The view layer (src/mori.h, src/altrep.c, src/serialize.c) is vendored from mizu and the region layer (src/shm.c, src/mori_region.h) from libmizu, both by tools/vendor.sh — all generated, never edited here; the bullets describe the vendored content.
- src/mori.h — types (
mori_shmincl. creatorpid,mori_buf,mori_owned,mori_vec,mori_list_view,mori_str_geom), the retained C-level declarations (mori_layout_write, wrap constructors,mori_resolve_id,mori_walk_path, hook typedefs — the setters are stripped), constants (MORI_MAGIC_*,MORI_HEADER_SIZE,MORI_TAG_*, grammar bounds,MORI_PREFIX_LITERAL,MORI_CACHE_MAX,MORI_FLAGS_OFF/MORI_FLAG_S4,MORI_ELEM_S4,MORI_TYPE_INT64),MORI_ALIGN64,mori_sizeof_elt,mori_flags_known,mori_str_geometry/mori_str_valid(wrapping the region header'smori_mors_geometry). - src/mori_region.h — assembled from carved libmizu sections: status/error enums, region magics + header layout constants (incl.
MORI_HDR_FLAGS_OFF/MORI_HDR_FLAG_S4,MORI_HDR_VALID_OFF/MORI_HDR_VALID_COUNT), wire type tags (mori_type_e,MORI_TYPE_INT64) and NA sentinels, binding-tier constants (MORI_ZC_FLOOR,MORI_OPEN_CACHE_MAX,MORI_INTEROP_MAGIC, the language/capability registries), themori_shmstruct + the region ext-tier decls (stack/heap create/open, close, host release, reap — the public handle API is not vendored;MORI_COLDis re-established in the preamble for shm.c's cold paths), and the carved layout helpers the view layer delegates to (mori_mors_geometry,mori_morh_validity_set,mori_na_build, and the bounds-checked MIZL directory-entry readermori_morl_elemwith itsmori_morl_entrystruct andmori_ext_morl_ent/mori_ext_morl_tag_ok/mori_ext_valid_ok/mori_ext_flags_known/mori_type_elt_sizechain —MORI_EXT_INLINEstatic inlines overMORI_REGION_ALIGN64arithmetic). - src/shm.c — platform SHM create/open/close (stack/heap ext tier; the public handle API is stripped at vendoring) + finalizers.
mori_shm_reapenumerates the platform name source (/dev/shmon Linux; per-user registry dir on macOS — see Platform Notes), classifies by embedded PID (mori_pid_alive), feedsmori_reap_unlink; a dead-PID region is reported removed only whenshm_unlinkactually reclaimed it (concurrent reaps never double-report). Windows / other POSIX can't reap.mori_shm_os_unlinkis the single unlink seam. Errors:mori_err_classifymaps native errno/GetLastError →MORI_E*before any close/unlink clobbers it;mori_err_describe→ summary + remediation hint. - src/serialize.c —
mori_serialize_count/mori_serialize_into/mori_unserialize_from: fallback MORL entries (sexptype == 0) and (unless the attrs hooks take them) attributes. - src/altrep.c — everything else: ALTREP classes,
mori_create, layout dispatchers + size/write pairs (incl. the foreign staging mode: validity sections,*_GET_REGIONcopies of admitted ALTREP atomics, the integer64 leaf gate), wrap constructors, consumer open+wrap,mori_resolve_id+ path walk, identifier formatter/parser, serialization + wire hooks,mori_altrep_init. Create failures:mori_shm_create_failedcomposes size (mori_format_bytes) +mori_err_describeinto oneRf_error. - src/init.c —
R_init_mori; 5.Callentries (names match C functions; all take oneSEXPexceptmori_prune). - R/ —
mori-package.R(docs),share.R(the five wrappers).import-standalone-defer.Ris vendored from withr (usethis::use_standalone("r-lib/withr", "defer")) — don't edit by hand.
testthat edition 3; tests/testthat.R entry point; tests/testthat/test-*.R grouped by topic. Nothing gated behind skip_on_cran or env vars. test-corruption.R hand-crafts malformed regions byte-by-byte and is layout-sensitive by design — it must track the layouts above (directory entries 64-byte aligned; the string block in the Arrow-shaped form via its str_block helper; tag-33 remote leaves via TAG_REF/morl_header_v; serialized payloads are R's native binary format — serialize(..., xdr = FALSE) — matching the package's streams). Those cases run only on Linux (file-backed /dev/shm), so macOS local runs skip them — CI's Ubuntu jobs are the ones that exercise them.
Coverage: covr instruments the compiled C, so the vendored layer dominates the report. The workflow sources tools/coverage-exclusions.R, which computes line_exclusions from text anchors (not line numbers — they track re-vendoring) for the code mori cannot execute: the foreign = 1 staging branches, the ok/sp veto walk, the Get_region methods (unreachable while Dataptr_or_null returns the SHM pointer), list Dataptr (never called on VECSXP), always-NULL hook branches, and the write-unwind failure arm. An anchor that stops matching fails the coverage workflow — update the anchors or the carve when re-vendoring changes these regions.
- Linux:
/dev/shmtmpfs viaopen()/unlink()directly (avoids the-lrtdependency).MAP_POPULATEpre-faults. - macOS:
shm_open/shm_unlink(libc);MAP_POPULATEis a no-op. The kernel namespace can't be enumerated (invisible once the creator dies), so reaping uses a per-user registry underTMPDIR: one append-only log per process (<dir>/mori_<pid>, not a file per region): each created region recorded as one 4-byte binary record holding its name counter (the pid comes from the filename) — onewrite()~1 µs vs ~40 µs file creation, opened lazily on first share bymori_log_append(sole creator; retries throughmkdironENOENT). Single-writer ⇒ no locking; readers are reapers of dead PIDs.mori_log_releasetracks a live-region count; at zero it unlinks the log andrmdirs the dir. The count is incremented even when logging fails (forfeits reapability, never the region). Fork-safe viamori_log_fork_guard(reopens on PID change). Awrite()is cross-process visible withoutfsync, lost only on reboot. All log ops best-effort. - Windows: page-file-backed
CreateFileMappingA/MapViewOfFile. The host must keep the mapping handle alive until consumers open it (the GC-chained host extptr does).
- roxygen2 (markdown); NAMESPACE auto-generated. MIT license. Version
major.minor.patch.dev(dev tag.9000). README.mdis generated fromREADME.Rmd— edit the.Rmdand re-knit, neverREADME.md.AGENTS.md,.claude/,.posit/are in.Rbuildignore.