C API Reference

Every public function, type, enum, and macro in mino.h. Auto-generated from the source.

Conventions

Naming
*_new and *_alloc return values the caller owns; release them with the matching *_free or *_destroy. *_get and *_peek return borrowed pointers that must not be freed. *_take transfers ownership from the runtime to the caller.
Lifetime
Values returned by the runtime are borrowed: they stay valid until the next allocation, which can trigger collection. To keep a value alive across multiple runtime calls, root it with mino_ref_new and release it with mino_unref. Values bound in a live environment are rooted automatically. See Embedding Guide for the full model.
Threading
A mino_state is not thread-safe: the host must not call into one state from multiple threads at once. Worker threads for agents, futures, and the blocking async ops are spawned by the runtime itself, but only after the host raises the per-state ceiling via mino_set_thread_limit (default 1, which disables host-threaded primitives). mino_interrupt(S) is the only function in this reference that is safe to call from a non-owning thread.

Version

MINO_VERSION_MAJORmacro

#define MINO_VERSION_MAJOR 0

Compile-time version constants, bumped by the release process. Host code can check these at preprocessor time to guard against embedding against an unexpected runtime:

#if MINO_VERSION_MAJOR == 0 && MINO_VERSION_MINOR < 48 # error "embedded mino is too old; need >= 0.48" #endif

The linked-in version (which may differ if the header was updated without rebuilding the runtime) is available at runtime via mino_version_string().

MINO_VERSION_MINORmacro

#define MINO_VERSION_MINOR 422

MINO_VERSION_PATCHmacro

#define MINO_VERSION_PATCH 1

mino_version_string

Human-readable version string of the *linked* runtime, e.g. "0.48.0". The pointer is to a static string with program lifetime; callers must not free it.

const char *mino_version_string(void);

Value types

mino_typeenum

VariantDescription
MINO_NIL
MINO_BOOL
MINO_INT
MINO_FLOAT64-bit IEEE 754 double.
MINO_FLOAT3232-bit IEEE 754 single. Distinct tag so float? matches both tiers and double? matches only MINO_FLOAT. Stored in the same as.f field as MINO_FLOAT (the 32-bit cast precision narrowing happens at construction); arithmetic always promotes to MINO_FLOAT, matching JVM Clojure where Float arithmetic yields Double.
MINO_CHARUnicode scalar value (codepoint)
MINO_STRING
MINO_SYMBOL
MINO_KEYWORD
MINO_EMPTY_LISTsingleton: the canonical empty list (). Distinct from nil: seq?-true, nil?-false, empty?-true. Walkers terminate on it because mino_is_cons returns false. Construct via mino_empty_list(S).
MINO_CONS
MINO_VECTOR
MINO_MAP
MINO_SETpersistent set: HAMT of keys with sentinel values
MINO_SORTED_MAPpersistent sorted map: red-black tree
MINO_SORTED_SETpersistent sorted set: red-black tree
MINO_PRIM
MINO_FN
MINO_MACROuser-defined macro (shares the fn struct layout)
MINO_HANDLEopaque host object: pointer + type tag string
MINO_ATOMmutable reference cell: wraps a single value
MINO_VOLATILElightweight single-slot mutable cell. No watches, no validators, no atomic publish. Intended for transducer state where the reducing fn already implies single-thread access. Constructed via mino_volatile / volatile!.
MINO_LAZYlazy sequence: thunk body + env, cached on first force
MINO_CHUNKfixed-capacity buffer of values used as the leaf of a chunked seq. Constructed via chunk-buffer (mutable, for accumulation) and sealed via chunk (returns the same value with sealed=1). After sealing, chunk-append throws.
MINO_CHUNKED_CONSchunked-seq cell: holds one MINO_CHUNK plus an offset into it and a more seq for what follows the chunk. first/next/rest treat this transparently as a seq; chunk-first / chunk-rest expose the underlying chunk so combinators can pull a whole chunk at a time and emit chunked output. Constructed via chunk-cons.
MINO_RECURinternal tail-call trampoline sentinel
MINO_TAIL_CALLproper tail call: carries {fn, args} for trampoline
MINO_REDUCEDearly termination wrapper for reduce
MINO_VARfirst-class var: ns + name + root binding
MINO_TRANSIENTmutable staging wrapper for batch mutation of a persistent vector, map, or set. Embedders call mino_transient / mino_persistent and the *_bang accessors below.
MINO_BIGINTarbitrary-precision signed integer. Backed by the vendored imath library (src/vendor/imath.c). The mpz_t struct is embedded in the value cell; the digit storage is owned by the cell and freed during GC sweep. See also 1N literals and the bigint / biginteger constructors.
MINO_RATIOarbitrary-precision rational number, stored as a numerator/denominator pair of bigints. The representation is always reduced (gcd = 1) and the denominator is always positive (sign lives on the numerator). See also 1/2 literals and the numerator / denominator primitives.
MINO_BIGDECarbitrary-precision decimal, stored as an unscaled bigint plus a non-negative integer scale: value = unscaled * 10^-scale. Constructed from 1.5M / 1M literals or via (bigdec x).
MINO_TYPEfirst-class record type. Carries identity (ptr), defining namespace, unqualified name, and an ordered vector of declared field-name keywords. Method tables are not stored here; protocol dispatch lives in the protocol's namespace, keyed by what (type x) returns. Construct via mino_defrecord.
MINO_RECORDrecord value: pointer to its MINO_TYPE plus a malloc-owned array of field-value slots and an optional MINO_MAP for extension keys. Storage is field slots, not a backing map; map-iso behaviour (get, assoc, seq, count, ...) is a contract layered on top via primitive dispatch on this tag. Construct via mino_record.
MINO_FUTUREhost-thread future: carries a result-or-exception cell, a state machine (PENDING, RESOLVED, FAILED, CANCELLED), a mutex+cond for cross-thread delivery, and a thread handle. Promises share this type — a promise is a future that exposes deliver and never has a worker thread.
MINO_UUIDRFC 4122 UUID. 16 bytes inline. Equality is byte-wise; hash mixes the 16 bytes. The #uuid "..." reader literal and (random-uuid), (parse-uuid s) construct it.
MINO_REGEXCompiled-on-use regex pattern. Holds the source string only -- mino's regex engine compiles per call. Equality is identity (matches Clojure JVM's (= #"x" #"x") returning false); print form is #"source". The reader's #"..." literal and (re-pattern s) construct it.
MINO_MAP_ENTRYMap entry: a (k, v) pair returned by first/seq of a map. Distinct from MINO_VECTOR -- key and val accept only MAP_ENTRY, throwing on plain 2-vectors -- but vector-shaped: vector?, coll?, sequential?, indexed?, counted?, associative?, reversible? all true; equality with a 2-vector compares element-wise. count is 2; nth 0 / 1 yield k / v; first/second/last/peek dispatch accordingly. Constructed by first/seq of a map and by clojure.lang.MapEntry/create.
MINO_HOST_ARRAYJVM-style host array: a fixed-length container with element-kind tag (:object, :int, :long, etc.) for printing and zero-fill semantics. Distinct from MINO_VECTOR: predicates like vector?, coll?, sequential?, counted?, associative? all return false (matching JVM's Java arrays which don't implement IPersistentCollection). seq returns a chunked seq over the elements. Equality is identity. Constructed via object-array, int-array, long-array, etc.
MINO_TX_REFSoftware transactional memory ref: identity cell holding a single committed value plus per-cell watches and validator. Mutations are confined to dosync transactions and serialized through a single-version optimistic protocol (read-set validation at commit; conflicts trigger retry). Equality is identity, matching atoms. Constructed via (ref v). The MINO_REF symbol was already taken by the embedder rooting handle (mino_ref), so the enum tag is MINO_TX_REF; the Clojure-level type keyword is :ref.
MINO_AGENTAsynchronous mutable cell with a per-state action run-queue. send / send-off enqueue (fn args) onto the queue and return the agent immediately; a worker thread drains the queue serially, applies actions under state_lock, and signals await waiters when the agent's in-flight count reaches zero. Watches and validators follow the atom/ref shape. Equality is identity. Constructed via (agent v). The worker counts against thread_limit, so send / send-off throw MTH001 if the host hasn't granted a thread budget (default thread_limit == 1 means no agents).
MINO_CHANclojure.core.async channel. Owns its buffer (for :fixed / :dropping / :sliding kinds), pending-putters and pending-takers queues, a closed flag, and optional transducer + ex- handler hooks directly in C-side mutable slots. Replaces the previous atom-of-map shape so each offer!/poll!/put!/take! is one C call with no script-side state-map allocation. Equality is identity. Constructed via (chan) / (chan n) / (chan n xform) / (promise-chan).
MINO_QUEUEclojure.lang.PersistentQueue equivalent: a persistent FIFO with amortised O(1) enqueue (conj) and dequeue (pop). Backed by two cons lists: a front list (the next-to-pop side, in order) and a back list (the most-recently-conj side, in REVERSE order). When the front empties the back is reversed and becomes the new front. count is cached. Predicates / seq / conj / peek / pop dispatch element-wise; equality is sequence equality with other queues only. Constructed via clojure.lang.PersistentQueue/ EMPTY plus conj, or the mino-native EMPTY-QUEUE binding.
MINO_BYTESImmutable binary-data value. Carries a heap- allocated buffer plus byte length plus a bit_tail field (0 for byte-aligned values, 1..7 for bit-aligned bitstrings). bytes? is true when bit_tail == 0; bitstring? is true for any MINO_BYTES regardless of bit_tail. Print form is #bytes "HEX..." (hex-encoded bytes, optional /N trailing-bit-count suffix for non-byte-aligned values). Constructed via (byte-array ...). aget reads a byte as int; aset! throws :mino/immutable -- the persistent- value model excludes in-place writes here. seq yields unsigned 0..255 ints, codepoint by codepoint. The bit_tail layout is forward- compatible with the bit-syntax surface (bits constructor + destructure) that ships in a follow-on cycle.

mino_typeof

Return the effective type of a value. Works for both heap-allocated cells and tagged scalars (int, bool, nil, char). NULL is treated as MINO_NIL. Use this to dispatch on type from C without reaching into the value's internal layout.

mino_type mino_typeof(const mino_val *v);

mino_prim_fntypedef

typedef mino_val *(*mino_prim_fn)(mino_state *S, mino_val *args, mino_env *env);

mino_prim_fn2typedef

typedef mino_val *(*mino_prim_fn2)(mino_state *S, mino_val **argv, int argc, mino_env *env);

argv ABI: receives evaluated args as a flat C array instead of a cons spine. Skips eval_args' per-call cons allocation for prims registered with mino_prim_argv. argv slots are GC-rooted by the conservative stack scan for the duration of the call.

mino_finalizer_fntypedef

typedef void (*mino_finalizer_fn)(void *ptr, const char *tag);

mino_host_fntypedef

typedef mino_val *(*mino_host_fn)(mino_state *S, mino_val *target, mino_val *args, void *ctx);

Host interop callback. target is the handle (NULL for ctor/static), args is a cons list of evaluated arguments.

Constructors

mino_nil

Return the singleton nil value.

mino_val *mino_nil(mino_state *S);

mino_true

Return the singleton true value.

mino_val *mino_true(mino_state *S);

mino_false

Return the singleton false value.

mino_val *mino_false(mino_state *S);

mino_empty_list

Return the singleton empty-list value (). Distinct from nil: seq? is true, nil? is false, empty? is true, and = against nil is false. Walkers using mino_is_cons terminate on it because the type tag is MINO_EMPTY_LIST, not MINO_CONS.

mino_val *mino_empty_list(mino_state *S);

mino_int

Create an integer value from a signed long long. Total over the full long long range. Values in [-2^60, 2^60 - 1] return a tag-encoded pointer (no allocation). Values outside that band depend on the MINO_CAP_BIGNUM capability: with bignum installed, the result is a MINO_BIGINT carrying the same numeric value, so hosts that opt in to arbitrary-precision arithmetic see one int family that grows past 64 bits transparently; without bignum, the result is a boxed MINO_INT cell that still holds the full 64-bit signed integer.

Inside mino's runtime, deterministic operations such as the reader, bitwise primitives, and the unchecked-* family never auto-promote; they keep producing MINO_INT (boxed when outside the tag range) so Clojure-style "long stays long" semantics are preserved.

Capability-conditional behaviour -------------------------------- The auto-promote of a tag-overflowing mino_int argument to a MINO_BIGINT when MINO_CAP_BIGNUM is installed is the C-side peer to JVM Clojure's +' / inc' / *' / dec' opt-in arithmetic. An embedder that wants "long stays long" (regardless of magnitude) uses mino_install_minimal plus the explicit unchecked-* surface; an embedder that wants the JVM BigInteger-shaped "promote silently" semantics installs the BIGNUM capability and gets the auto-promote through this constructor.

mino_val *mino_int(mino_state *S, long long n);

mino_float

Create a floating-point value.

mino_val *mino_float(mino_state *S, double f);

mino_float32

Create a 32-bit single-precision floating-point value. The double argument is narrowed to float and stored back as a double so equality / print see the rounded value; the type tag distinguishes it from MINO_FLOAT so double? returns false on the result.

mino_val *mino_float32(mino_state *S, double f);

mino_bigint_from_ll

Create a bigint from a signed long long.

mino_val *mino_bigint_from_ll(mino_state *S, long long n);

mino_bigint_from_string

Create a bigint by parsing a base-10 numeric string (optional leading '+' or '-'). Returns NULL on parse failure.

mino_val *mino_bigint_from_string(mino_state *S, const char *s);

mino_ratio_from_ll

Create a rational from numerator and denominator long longs. The result is reduced (gcd = 1) and normalised so the denominator is positive. If denom is zero, throws division-by-zero. If the result is integer, returns a MINO_INT or MINO_BIGINT instead of a MINO_RATIO.

mino_val *mino_ratio_from_ll(mino_state *S, long long num, long long denom);

mino_bigdec_from_string

Create a bigdec from a base-10 numeric string. Returns NULL on parse failure. Recognises optional sign, fractional part, and 'e'-prefixed exponent; the trailing 'M' suffix is optional in this entry point.

mino_val *mino_bigdec_from_string(mino_state *S, const char *s);

mino_char

Create a character value from a Unicode codepoint (0..0x10FFFF).

mino_val *mino_char(mino_state *S, int codepoint);

mino_string

Create a string from a NUL-terminated C string. The data is copied.

mino_val *mino_string(mino_state *S, const char *s);

mino_string_n

Create a string from a buffer of length len. The data is copied.

mino_val *mino_string_n(mino_state *S, const char *s, size_t len);

mino_symbol

Intern a symbol from a NUL-terminated C string.

mino_val *mino_symbol(mino_state *S, const char *s);

mino_symbol_n

Intern a symbol from a buffer of length len.

mino_val *mino_symbol_n(mino_state *S, const char *s, size_t len);

mino_keyword

Intern a keyword from a NUL-terminated C string (without the leading :).

mino_val *mino_keyword(mino_state *S, const char *s);

mino_keyword_n

Intern a keyword from a buffer of length len (without the leading :).

mino_val *mino_keyword_n(mino_state *S, const char *s, size_t len);

mino_keyword_ns_n

Intern a keyword from explicit (ns, name) buffers. The resulting keyword carries ns_len so name / namespace round-trip the originally-passed segments — (keyword "a/b" "c") and (keyword "a" "b/c") produce DISTINCT vals even though their printed flat form is identical. ns may be NULL or ns_len == 0 for an unqualified keyword.

mino_val *mino_keyword_ns_n(mino_state *S, const char *ns, size_t ns_len, const char *name, size_t name_len);

mino_symbol_ns_n

Same shape for symbols.

mino_val *mino_symbol_ns_n(mino_state *S, const char *ns, size_t ns_len, const char *name, size_t name_len);

mino_cons

Create a cons cell (list node) with the given car and cdr.

mino_val *mino_cons(mino_state *S, mino_val *car, mino_val *cdr);

mino_vector

Create a persistent vector from a C array of values.

mino_val *mino_vector(mino_state *S, mino_val **items, size_t len);

mino_map

Create a persistent hash map from parallel key and value arrays.

mino_val *mino_map(mino_state *S, mino_val **keys, mino_val **vals, size_t len);

mino_set

Create a persistent hash set from a C array of values.

mino_val *mino_set(mino_state *S, mino_val **items, size_t len);

Collection builders

mino_vec_buildertypedefstruct mino_vec_builder

typedef struct mino_vec_builder mino_vec_builder;

Builders are an embedder-friendly facade over transients. Use them when you produce elements one at a time from C: open a builder, push/put/add each element, finish to get the persistent value.

mino_vec_builder *b = mino_vector_builder_new(S); for (size_t i = 0; i < n; i++) { mino_vector_builder_push(b, mino_int(S, items[i])); } mino_val *v = mino_vector_builder_finish(b);

The builder roots the in-flight collection across GC; _finish hands back the persistent result and releases the builder.

mino_map_buildertypedefstruct mino_map_builder

typedef struct mino_map_builder mino_map_builder;

mino_set_buildertypedefstruct mino_set_builder

typedef struct mino_set_builder mino_set_builder;

mino_vector_builder_new

mino_vec_builder *mino_vector_builder_new   (mino_state *S);

mino_vector_builder_push

void                mino_vector_builder_push  (mino_vec_builder *b, mino_val *v);

mino_vector_builder_finish

mino_val         *mino_vector_builder_finish(mino_vec_builder *b);

mino_map_builder_new

mino_map_builder *mino_map_builder_new      (mino_state *S);

mino_map_builder_put

void                mino_map_builder_put      (mino_map_builder *b, mino_val *k, mino_val *v);

mino_map_builder_finish

mino_val         *mino_map_builder_finish   (mino_map_builder *b);

mino_set_builder_new

mino_set_builder *mino_set_builder_new      (mino_state *S);

mino_set_builder_add

void                mino_set_builder_add      (mino_set_builder *b, mino_val *v);

mino_set_builder_finish

mino_val         *mino_set_builder_finish   (mino_set_builder *b);

Collection iterator

mino_itertypedefstruct mino_iter

typedef struct mino_iter mino_iter;

One iterator type walks every sequential / associative collection mino exposes: vectors, maps (hashed and sorted), sets (hashed and sorted), cons lists, the empty-list singleton, lazy seqs, and chunked seqs. Dispatch happens internally on each step.

The iterator is opaque; the host allocates storage of mino_iter_sizeof() bytes (typically on the C stack via alloca or as a local struct) and passes a pointer into mino_iter_init.

Usage:

mino_iter *it = alloca(mino_iter_sizeof()); mino_iter_init(S, it, coll); mino_val *k, *v; while (mino_iter_next(it, &k, &v)) { // for vectors / sets / lists: k is the element, v is NULL // for maps: k is the key, v is the value } mino_iter_done(it);

mino_iter_init roots coll for the iterator's lifetime so a GC fired mid-walk cannot reclaim the cells the walker borrows pointers into. mino_iter_done releases that root and must always be called once, even if iteration ends early. Calling _next after it returns 0 keeps returning 0; calling _next or _done on a NULL iterator is harmless.

mino_iter_sizeof

size_t       mino_iter_sizeof(void);

mino_iter_init

void         mino_iter_init  (mino_state *S, mino_iter *it, mino_val *coll);

mino_iter_next

int          mino_iter_next  (mino_iter *it, mino_val **out_k, mino_val **out_v);

mino_iter_done

void         mino_iter_done  (mino_iter *it);

mino_prim

Create a primitive function value from a C function pointer.

mino_val *mino_prim(mino_state *S, const char *name, mino_prim_fn fn);

mino_prim_argv

Create a primitive value backed by an argv-style C function.

mino_val *mino_prim_argv(mino_state *S, const char *name, mino_prim_fn2 fn);

mino_handle

Wrap a host pointer as an opaque handle with a type tag.

mino_val *mino_handle(mino_state *S, void *ptr, const char *tag);

mino_handle_ex

Wrap a host pointer with a type tag and a finalizer called on GC.

mino_val *mino_handle_ex(mino_state *S, void *ptr, const char *tag, mino_finalizer_fn finalizer);

mino_atom

Create a mutable atom initialized with val.

mino_val *mino_atom(mino_state *S, mino_val *val);

mino_is_handle

Return 1 if v is a handle, 0 otherwise.

int         mino_is_handle(const mino_val *v);

mino_handle_ptr

Return the host pointer from a handle, or NULL if v is not a handle.

void       *mino_handle_ptr(const mino_val *v);

mino_handle_tag

Return the type tag from a handle, or NULL if v is not a handle.

const char *mino_handle_tag(const mino_val *v);

mino_is_atom

Return 1 if v is an atom, 0 otherwise.

int         mino_is_atom(const mino_val *v);

mino_atom_deref

Return the current value of an atom.

mino_val *mino_atom_deref(const mino_val *a);

mino_volatile

Create a volatile cell initialized with val.

mino_val *mino_volatile(mino_state *S, mino_val *val);

mino_is_volatile

Return 1 if v is a volatile, 0 otherwise.

int         mino_is_volatile(const mino_val *v);

mino_volatile_deref

Return the current value of a volatile, or NULL if v is not a volatile.

mino_val *mino_volatile_deref(const mino_val *v);

mino_atom_reset

Set the value of an atom.

void        mino_atom_reset(mino_val *a, mino_val *val);

mino_map_entry

Construct a map entry holding (k, v). Used by first / seq of a map to publish entries with the right type identity (so key / val can type-check), and by clojure.lang.MapEntry/create.

mino_val *mino_map_entry(mino_state *S, mino_val *k, mino_val *v);

mino_queue_empty

Build an empty PersistentQueue. The mino-native canonical empty value is bound to clojure.lang.PersistentQueue/EMPTY after a normal mino_install; conj / peek / pop / count / seq behave canonically.

mino_val *mino_queue_empty(mino_state *S);

mino_is_queue

Return 1 if v is a MINO_QUEUE, 0 otherwise. NULL-safe.

int         mino_is_queue(const mino_val *v);

mino_queue_count

count / conj / peek / pop / seq on a PersistentQueue. NULL on type mismatch except count which returns 0. conj appends to the back; peek returns the next-to-pop element; pop returns the queue without its head. The seq returns the elements in deque order.

size_t      mino_queue_count(const mino_val *q);

mino_queue_conj

mino_val *mino_queue_conj (mino_state *S, mino_val *q, mino_val *v);

mino_queue_peek

mino_val *mino_queue_peek (const mino_val *q);

mino_queue_pop

mino_val *mino_queue_pop  (mino_state *S, mino_val *q);

mino_queue_seq

mino_val *mino_queue_seq  (mino_state *S, const mino_val *q);

mino_bytes

MINO_BYTES constructors and accessors.

mino_bytes(S, src, n) copies n bytes from src into a fresh GC-managed MINO_BYTES value with bit_tail == 0. If src is NULL the buffer is zero-filled.

mino_bytes_from_array(S, src, n) is the JVM byte-array-shape peer: same as mino_bytes() but accepts a signed char * so embed code that already holds Java-shaped jbyte-style buffers can pass them straight through.

mino_bytes_len returns the byte count (NOT bit count); use mino_bytes_bit_len for the total bit count (byte_len*8 + bit_tail).

mino_bytes_data returns a pointer into the GC-managed buffer; the pointer is valid until the bytes value becomes unreachable.

mino_bytes_get(v, i) reads a single byte as an unsigned int (0..255) and returns -1 if i is out of range.

mino_val *mino_bytes              (mino_state *S, const unsigned char *src, size_t n);

mino_bytes_from_array

mino_val *mino_bytes_from_array   (mino_state *S, const signed char  *src, size_t n);

mino_is_bytes

int         mino_is_bytes           (const mino_val *v);

mino_is_bitstring

int         mino_is_bitstring       (const mino_val *v);

mino_bytes_len

size_t      mino_bytes_len          (const mino_val *v);

mino_bytes_bit_len

size_t      mino_bytes_bit_len      (const mino_val *v);

mino_bytes_data

const unsigned char *mino_bytes_data(const mino_val *v);

mino_bytes_get

int         mino_bytes_get          (const mino_val *v, size_t i);

mino_tx_ref

Construct an STM ref holding the given committed value. The watches map and validator slots start NULL; install them via add-watch / set-validator! on the returned cell. The ref's identity (returned monotonic ID) is unique within S.

mino_val *mino_tx_ref(mino_state *S, mino_val *val);

mino_agent

Construct an asynchronous agent holding the given initial state. Watches, validator, and error handler all start NULL; install them via add-watch / set-validator! / set-error-handler! on the returned cell. The agent's action queue is heap-allocated and freed via the GC sweep finalizer when the agent becomes unreachable.

mino_val *mino_agent(mino_state *S, mino_val *initial);

mino_is_agent

Return 1 if v is an agent, 0 otherwise. NULL-safe.

int         mino_is_agent(const mino_val *v);

mino_agent_deref

Return the agent's current state value (the most-recently committed action result, or the initial value if no action has applied). Returns NULL if v is not an agent. Mirrors mino_atom_deref / mino_tx_ref_deref.

mino_val *mino_agent_deref(const mino_val *a);

mino_send

Enqueue (fn current-value arg1 arg2 ...) onto the agent's POOLED run-queue and return the agent immediately. extra_args is a cons list (or nil) holding the extra arguments after the agent's current value; the action fn is called as (fn current-value arg1 arg2 ...)

Throws (and returns NULL) if: - agent is NULL or not an agent (MTY001), - agent was created in a different state (MST007), - agents have been shut down (MST008), - the agent is failed and its error mode is :fail (MST002), - the host has not granted enough thread budget to spawn the pool's worker (MTH001) -- the embedder thread does not count against the limit; raise via mino_set_thread_limit (>= 1 for one agent worker; >= 2 if both send and send-off are used concurrently; more if mixing with futures / host threads).

Inside a transaction, the action is queued and only fires after a successful commit, matching JVM canon.

mino_val *mino_send(mino_state *S, mino_val *agent, mino_val *fn, mino_val *extra_args);

mino_send_off

Like mino_send but routes the action onto the SOLO pool. Same error semantics. mino's per-state eval lock means actions across the two pools still serialize, but the queues are independent.

mino_val *mino_send_off(mino_state *S, mino_val *agent, mino_val *fn, mino_val *extra_args);

mino_await

Block the calling thread until each named agent's in-flight count reaches zero. agents is a NULL-terminated array of MINO_AGENT values (or NULL/empty for a no-op). Throws (and returns NULL) if called from inside an agent action (MST002, would self-deadlock) or if any agent is from a foreign state (MST007). Returns nil on success.

mino_val *mino_await(mino_state *S, mino_val **agents);

mino_await_for

Like mino_await with a millisecond timeout. Returns 1 if every named agent reached zero in-flight before the deadline, 0 on timeout. Throws on cross-state misuse or self-await (returns 0 after the throw is published).

int         mino_await_for(mino_state *S, long long timeout_ms, mino_val **agents);

mino_agent_error

Return the agent's most recent captured exception value, or NULL if the agent is in a clean state. Throws on cross-state misuse (returns NULL).

mino_val *mino_agent_error(mino_state *S, mino_val *agent);

mino_restart_agent

Restart a failed agent: clears its captured error and resets its value to new_state. With clear_actions=1, drops every queued action targeting this agent across both pools. Returns the new state on success, or NULL after throwing if: - agent is not an agent (MTY001), - agent is from a foreign state (MST007), - agent is not failed (MST002), - the validator (if any) rejects new_state (MCT001).

mino_val *mino_restart_agent(mino_state *S, mino_val *agent, mino_val *new_state, int clear_actions);

mino_is_tx_ref

Return 1 if v is an STM ref (MINO_TX_REF), 0 otherwise. NULL-safe.

int         mino_is_tx_ref(const mino_val *v);

mino_tx_ref_deref

Read a ref. Outside any transaction: atomic load of the ref's committed value. Inside a transaction on the calling thread: the in-tx effective value (alter tentative, commute-log replay, or committed) AND records the read for read-set validation. Equivalent to Clojure's @ref. The caller must already be on a thread that has either entered an outer mino_tx_run or is executing inside a Clojure dosync; outside both, the committed value is returned without any tx bookkeeping. Returns NULL if v is not a ref.

mino_val *mino_tx_ref_deref(mino_state *S, mino_val *v);

mino_tx_ref_set

Set the ref's in-transaction tentative value to val. Must be called from inside a transaction (started either by a Clojure dosync or by mino_tx_run); throws eval/state MST002 outside a tx. Throws MST002 "Can't set after commute" if commute was called on this ref earlier in the same tx. Throws eval/type MTY001 if v is not a ref. Returns val on success. Equivalent to Clojure's (ref-set ref val).

mino_val *mino_tx_ref_set(mino_state *S, mino_val *v, mino_val *val);

mino_tx_xform_fntypedef

typedef mino_val *(*mino_tx_xform_fn)(mino_state *S, mino_val *cur, void *user, mino_env *env);

C-callable transformer used by mino_tx_alter_c / mino_tx_commute_c. cur is the in-tx effective value at call time; user is the caller-supplied opaque pointer. Returns the new value. May call mino_call for nested Clojure dispatch and may throw via prim_throw_classified -- both unwind through the enclosing tx runner. The function pointer must remain valid for the lifetime of the transaction (in particular: across retries and through commit- time replay for commute).

mino_tx_alter_c

Apply (fn cur user) to ref's current in-tx value and store the result. Records a read for read-set validation. Must be called from inside a transaction. Returns the new value, or NULL if the transformer threw. Equivalent to (alter ref #(fn % user)).

mino_val *mino_tx_alter_c(mino_state *S, mino_val *v, mino_tx_xform_fn fn, void *user, mino_env *env);

mino_tx_commute_c

Like mino_tx_alter_c but does NOT record a read (commute semantics). The fn is invoked once eagerly to produce the call-site value; if the ref did not also have an alter / ref-set in the same tx, the fn is replayed at commit time against the latest committed value (the fn must therefore be commutative). Otherwise the call-site value is what gets committed (matching JVM, which skips commute-log replay for refs in the write set). Returns the call-site value, or NULL if the transformer threw.

mino_val *mino_tx_commute_c(mino_state *S, mino_val *v, mino_tx_xform_fn fn, void *user, mino_env *env);

mino_tx_ensure

Pin the ref against any concurrent committer until this transaction commits or aborts. Returns the in-tx effective value. Must be in a transaction. Equivalent to (ensure ref).

mino_val *mino_tx_ensure(mino_state *S, mino_val *v, mino_env *env);

mino_tx_body_fntypedef

typedef mino_val *(*mino_tx_body_fn)(mino_state *S, void *user, mino_env *env);

C-callable transaction body, used by mino_tx_run. Returns the body's last value. The body may invoke any in-tx accessor (mino_tx_ref_deref / mino_tx_alter_c / ...), call mino_call to dispatch into Clojure code, and throw via prim_throw_classified.

The body is re-invoked on commit-time conflict, up to 10000 retries before throwing eval/state MST004. Any user state mutated through user survives across retries; if clean retry semantics matter, snapshot mutable state into a retry-local buffer at the top of the body. mino_val * pointers captured in user state should not be relied on across retries (the GC may relocate or finalize between iterations); re-derive them from the ref / world on each call.

mino_tx_run

Run body inside a transaction. Returns body's result on commit, or NULL if the body threw an unhandled exception or the retry cap was exhausted. Nests cleanly: if a transaction is already running on the calling thread (started by an outer dosync or mino_tx_run), the inner call is absorbed into the outer's tx and runs once without its own setjmp / retry frame. Equivalent to the host-level (dosync (body)).

mino_val *mino_tx_run(mino_state *S, mino_tx_body_fn body, void *user, mino_env *env);

Record types

mino_defrecord

Define a record type. Returns the MINO_TYPE value. The pointer is stable for the life of the state (record types are pinned), so type identity is pointer equality.

Idempotent: subsequent calls with the same ns/name return the existing type so re-loading scripts is safe. Field shape on a re-call is ignored (the existing type wins) — the script-layer defrecord macro validates shape changes when it re-evaluates.

The strings are copied into the state's intern table on first use, so callers may pass stack-allocated names. Field names are converted to keywords and stored in declared order.

Mirrors the Clojure defrecord macro name to make the C/script analogy obvious to a C/C++/Rust embedder.

mino_val *mino_defrecord(mino_state *S, const char *ns, const char *name, const char *const *field_names, size_t n_fields);

mino_is_record_type

Return 1 if v is a record type (MINO_TYPE), 0 otherwise.

int mino_is_record_type(const mino_val *v);

mino_record

Build a record. type must be a MINO_TYPE returned by mino_defrecord; n_vals must equal the type's declared field count; vals[i] gives the value for the i-th declared field. The vals array is copied into a fresh malloc-owned slot vector owned by the returned record. Returns NULL on type mismatch or arity mismatch (the caller should treat NULL as a runtime error).

The new record has no extension keys; assoc with an undeclared key lazily allocates the ext map.

mino_val *mino_record(mino_state *S, mino_val *type, mino_val **vals, size_t n_vals);

mino_record_field

Read a declared field by name. Returns the field value (borrowed) or NULL if name is not a declared field of record's type. Extension keys are not read by this entry point; embedders can reach them via the script-level (get r :ext-key) path.

mino_val *mino_record_field(const mino_val *record, const char *name);

mino_is_record

Return 1 if v is a record (MINO_RECORD), 0 otherwise.

int mino_is_record(const mino_val *v);

Transient (batch-mutation) API

mino_transient

Wrap a persistent vector, map, or set in a new transient. Throws on other types. The returned value is reusable until mino_persistent is called on it.

mino_val *mino_transient(mino_state *S, mino_val *coll);

mino_persistent

Extract the current persistent value and invalidate the transient. Further *_bang calls on t will throw.

mino_val *mino_persistent(mino_state *S, mino_val *t);

mino_assoc_bang

Transient mutators. Each returns t on success (after updating its inner persistent value) and NULL on a classified error. The caller must use the returned value instead of retaining its own handle to the transient across the call, matching Clojure's convention.

mino_val *mino_assoc_bang(mino_state *S, mino_val *t, mino_val *key, mino_val *val);

mino_conj_bang

mino_val *mino_conj_bang(mino_state *S, mino_val *t, mino_val *val);

mino_dissoc_bang

mino_val *mino_dissoc_bang(mino_state *S, mino_val *t, mino_val *key);

mino_disj_bang

mino_val *mino_disj_bang(mino_state *S, mino_val *t, mino_val *key);

mino_pop_bang

mino_val *mino_pop_bang(mino_state *S, mino_val *t);

mino_is_transient

Transient predicates and accessors.

int         mino_is_transient(const mino_val *v);

mino_transient_count

size_t      mino_transient_count(const mino_val *t);

Predicates and accessors

mino_is_nil

Type-predicate grid. Each returns 1 iff v has the given effective type, 0 otherwise. NULL is treated as MINO_NIL. The predicates are tag-aware: they work identically for inline scalars (int, bool, char, nil) and boxed cells. mino_is_float matches both MINO_FLOAT (double) and MINO_FLOAT32; mino_is_map / mino_is_set match the sorted and unsorted variants.

int mino_is_nil       (const mino_val *v);

mino_is_truthy

int mino_is_truthy    (const mino_val *v);

mino_is_bool

int mino_is_bool      (const mino_val *v);

mino_is_int

int mino_is_int       (const mino_val *v);

mino_is_float

int mino_is_float     (const mino_val *v);

mino_is_char

int mino_is_char      (const mino_val *v);

mino_is_string

int mino_is_string    (const mino_val *v);

mino_is_symbol

int mino_is_symbol    (const mino_val *v);

mino_is_keyword

int mino_is_keyword   (const mino_val *v);

mino_is_cons

int mino_is_cons      (const mino_val *v);

mino_is_empty_list

int mino_is_empty_list(const mino_val *v);

mino_is_vector

int mino_is_vector    (const mino_val *v);

mino_is_map

int mino_is_map       (const mino_val *v);

mino_is_set

int mino_is_set       (const mino_val *v);

mino_is_fn

int mino_is_fn        (const mino_val *v);

mino_is_macro

int mino_is_macro     (const mino_val *v);

mino_is_prim

int mino_is_prim      (const mino_val *v);

mino_is_lazy

int mino_is_lazy      (const mino_val *v);

mino_is_var

int mino_is_var       (const mino_val *v);

mino_is_bigint

int mino_is_bigint    (const mino_val *v);

mino_is_ratio

int mino_is_ratio     (const mino_val *v);

mino_is_bigdec

int mino_is_bigdec    (const mino_val *v);

mino_is_uuid

int mino_is_uuid      (const mino_val *v);

mino_is_regex

int mino_is_regex     (const mino_val *v);

mino_is_float32

int mino_is_float32   (const mino_val *v);

mino_is_sorted_map

int mino_is_sorted_map(const mino_val *v);

mino_is_sorted_set

int mino_is_sorted_set(const mino_val *v);

mino_is_map_entry

int mino_is_map_entry (const mino_val *v);

mino_is_host_array

int mino_is_host_array(const mino_val *v);

mino_is_record

int mino_is_record    (const mino_val *v);  /* also at mino_defrecord */

mino_is_queue

int mino_is_queue     (const mino_val *v);  /* also at mino_queue_empty */

mino_is_bytes

int mino_is_bytes     (const mino_val *v);  /* declared above near mino_bytes */

mino_is_bitstring

int mino_is_bitstring (const mino_val *v);  /* declared above near mino_bytes */

mino_is_record_type

int mino_is_record_type(const mino_val *v); /* also at mino_defrecord */

mino_is_handle

int mino_is_handle    (const mino_val *v);  /* also near mino_handle */

mino_is_atom

int mino_is_atom      (const mino_val *v);  /* also near mino_atom */

mino_is_volatile

int mino_is_volatile  (const mino_val *v);  /* also near mino_volatile */

mino_is_agent

int mino_is_agent     (const mino_val *v);  /* also near mino_agent */

mino_is_tx_ref

int mino_is_tx_ref    (const mino_val *v);  /* also near mino_tx_ref */

mino_is_transient

int mino_is_transient (const mino_val *v);  /* also near mino_transient */

mino_is_future

int mino_is_future    (const mino_val *v);

mino_eq

Structural equality. Returns 1 if a and b are equal, 0 otherwise.

int mino_eq(const mino_val *a, const mino_val *b);

mino_compare

Three-way comparison. Returns -1, 0, or 1 for orderable arguments matching Clojure compare. Cross-type comparison throws via the runtime's error path (the caller sees a NULL last_error change); orderless types (fn, prim, handle, ...) likewise throw. NULL is treated as nil; (compare nil nil) is 0.

int mino_compare(mino_state *S, const mino_val *a, const mino_val *b);

mino_hash

Canonical 32-bit value hash matching Clojure's hash contract: for any pair where mino_eq(a, b) is 1, mino_hash(a) == mino_hash(b). Tag-aware; NULL hashes the same as nil.

uint32_t mino_hash(const mino_val *v);

mino_car

Return the first element of a cons cell, or NULL.

mino_val *mino_car(const mino_val *v);

mino_cdr

Return the rest of a cons cell, or NULL.

mino_val *mino_cdr(const mino_val *v);

mino_seq

Universal seq abstraction matching Clojure's seq / first / rest / next:

mino_seq(S, coll) -- coerce coll to a seq; returns NULL for an eval error, mino_nil() for an empty input. mino_first(coll) -- first element of the seq; mino_nil() if empty. mino_rest(S, coll) -- the seq of everything after the first; an empty list when there's nothing left. mino_next(S, coll) -- (seq (rest coll)): nil when empty, the forced seq otherwise. Matches the Clojure idiom for terminating while-let loops.

The cons-spine-only mino_car/mino_cdr above stay; this quartet covers the universal walk across vec / map / set / lazy / chunked / sorted variants.

mino_val *mino_seq  (mino_state *S, mino_val *coll);

mino_first

mino_val *mino_first(mino_val *coll);

mino_rest

mino_val *mino_rest (mino_state *S, mino_val *coll);

mino_next

mino_val *mino_next (mino_state *S, mino_val *coll);

mino_meta

Metadata read / attach matching script-side (meta x) and (with-meta x m). mino_with_meta returns a fresh shallow-copy with the new meta map; identity-shaped types (atom, agent) throw. m must be a MINO_MAP or MINO_NIL.

mino_val *mino_meta(const mino_val *v);

mino_with_meta

mino_val *mino_with_meta(mino_state *S, mino_val *v, mino_val *meta);

mino_binding_frametypedefstruct mino_binding_frame

typedef struct mino_binding_frame mino_binding_frame;

Dynamic-binding push/pop from C, peer to script-side (binding [...] ...). vars is an array of MINO_SYMBOL values naming the dynamic vars to rebind; vals is the parallel array of values. Returns an opaque frame handle the embedder pops with mino_pop_bindings after evaluating the dynamically-scoped work.

Nests correctly with script-side binding frames: a script-side unwind through throw walks the dyn stack and clears any frames still open above the catching frame, including ones the embedder pushed.

Returns NULL on allocation failure or invalid argument shape (any non-symbol in vars, or attempting to bind a non-dynamic var).

mino_push_bindings

mino_binding_frame *mino_push_bindings(mino_state *S, mino_val **vars, mino_val **vals, size_t n);

mino_pop_bindings

void                mino_pop_bindings (mino_state *S, mino_binding_frame *frame);

mino_can_clone

Cross-state transferability pre-flight. Returns 1 if the value tree contains only transferable types (nil, bool, int, float, string, symbol, keyword, cons, vector, map, set, sorted variants, lazy, bigint, ratio, bigdec, uuid, regex source); returns 0 if any identity-bearing leaf (atom, agent, handle, future, tx_ref, fn, prim, etc.) is reached. When non-NULL, *out_reason names the first non-transferable type encountered. Cheaper than mino_clone because no copy is performed.

int mino_can_clone(const mino_val *v, const char **out_reason);

mino_length

Return the number of cons cells in a list.

size_t mino_length(const mino_val *list);

mino_to_int

Type-safe C extraction. Each returns 1 on success, 0 on type mismatch. mino_to_bool uses truthiness (only nil and false are falsey). String, keyword, and symbol extractors write the interned byte pointer through out (NUL-terminated, mino-owned) and the byte length through len.

int mino_to_int    (const mino_val *v, long long *out);

mino_to_float

int mino_to_float  (const mino_val *v, double *out);

mino_to_float32

int mino_to_float32(const mino_val *v, float *out);

mino_to_bool

int mino_to_bool   (const mino_val *v);

mino_to_char

int mino_to_char   (const mino_val *v, int *cp);

mino_to_string

int mino_to_string (const mino_val *v, const char **out, size_t *len);

mino_to_keyword

int mino_to_keyword(const mino_val *v, const char **out, size_t *len);

mino_to_symbol

int mino_to_symbol (const mino_val *v, const char **out, size_t *len);

mino_to_bigint_str

Bigint -> decimal-string serialiser. Writes into the caller-owned buf of n bytes; the number of bytes written (not counting the NUL terminator) lands in *out_written when non-NULL. Returns 1 on success, 0 on type mismatch, -1 if the buffer is too small to hold the formatted result + NUL.

int mino_to_bigint_str(const mino_val *v, char *buf, size_t n, size_t *out_written);

mino_to_ratio

Ratio extractor for ratios whose numerator and denominator both fit in long long. Returns 1 on success, 0 on type mismatch or out-of- range (bigint-backed ratios that overflow long long).

int mino_to_ratio(const mino_val *v, long long *out_num, long long *out_den);

mino_to_bigdec_str

Bigdec -> string serialiser (canonical Clojure-style printing, e.g. "1.5M"-shaped value prints as "1.5"). Same buffer contract as mino_to_bigint_str.

int mino_to_bigdec_str(const mino_val *v, char *buf, size_t n, size_t *out_written);

mino_to_uuid_bytes

UUID extractor. Writes the 16 RFC 4122 bytes into the caller-owned out[16] array. Returns 1 on success, 0 on type mismatch.

int mino_to_uuid_bytes(const mino_val *v, uint8_t out[16]);

mino_to_regex_source

Regex source extractor. Writes the pattern source pointer through out (mino-owned, NUL-terminated) and the byte length through len. Returns 1 on success, 0 on type mismatch.

int mino_to_regex_source(const mino_val *v, const char **out, size_t *len);

Printer

mino_print

Print a value to stdout in readable form.

void mino_print(mino_state *S, const mino_val *v);

mino_println

Print a value to stdout followed by a newline.

void mino_println(mino_state *S, const mino_val *v);

mino_print_to

Print a value to the given FILE stream.

void mino_print_to(mino_state *S, FILE *out, const mino_val *v);

mino_print_to_buf

Print a value's readable form into a sized buffer (NUL-terminated). Returns the number of bytes written excluding the trailing NUL, or -1 on error (NULL buf, zero capacity, or I/O failure). When the printed form is longer than n - 1 bytes, the output is truncated to fit and the function still returns the truncated byte count. Use this when the embedder routes output elsewhere than a FILE * (server response buffer, plugin host, IDE panel).

int  mino_print_to_buf(mino_state *S, const mino_val *v, char *buf, size_t n);

Reader

mino_read

Read one form from src. On success returns a value and writes a pointer just past the consumed input to *end (when end is non-NULL). On EOF (only whitespace / comments remaining) returns NULL with *end advanced past the trailing whitespace. On parse error returns NULL and writes a human-readable message via mino_last_error().

mino_val *mino_read(mino_state *S, const char *src, const char **end);

mino_last_error

Return the last error message, or NULL if no error occurred.

const char *mino_last_error(mino_state *S);

mino_diagtypedefstruct mino_diag

typedef struct mino_diag mino_diag;

Opaque structured diagnostic type. Use mino_last_diag() to retrieve.

mino_last_diag

Return the last structured diagnostic, or NULL if no error occurred. The returned pointer is valid until the next error or clear_error.

const mino_diag *mino_last_diag(mino_state *S);

mino_last_error_map

Return the last error as a mino map with :mino/kind, :mino/code, etc. Returns nil if no error occurred. The value is GC-owned and cached.

mino_val *mino_last_error_map(mino_state *S);

mino_error_kind

Return the last error's classified kind (e.g. "eval/type", "eval/arity", "name", "reader") or NULL when no error is current. The returned pointer is valid until the next error or mino_clear_error call.

const char *mino_error_kind(mino_state *S);

mino_error_code

Return the last error's stable code (e.g. "MTY001", "MNS002") or NULL when no error is current. Lifetimes match mino_error_kind.

const char *mino_error_code(mino_state *S);

mino_clear_error

Clear the last error and diagnostic. After this call mino_last_error, mino_error_kind, and mino_error_code all return NULL.

void mino_clear_error(mino_state *S);

MINO_DIAG_RENDER_COMPACTmacro

#define MINO_DIAG_RENDER_COMPACT 0

Diagnostic rendering modes.

MINO_DIAG_RENDER_PRETTYmacro

#define MINO_DIAG_RENDER_PRETTY  1

mino_render_diag

Render a diagnostic into buf. Returns bytes written (excl NUL). mode is one of MINO_DIAG_RENDER_COMPACT or _PRETTY.

int mino_render_diag(mino_state *S, const mino_diag *d, int mode, char *buf, size_t n);

Runtime state

mino_state_new

Create a new isolated runtime state. Each state owns its own GC, intern tables, module cache, and singletons. Multiple states may coexist in the same process; they share no mutable data.

Fatal: aborts on allocation failure (no state exists to report through).

mino_state *mino_state_new(void);

mino_state_free

Free a runtime state and all resources owned by it. All GC-managed objects, intern tables, module caches, and metadata are released. Environments created within this state become invalid.

void mino_state_free(mino_state *S);

mino_jit_modeenum

JIT mode control (per-state).

AUTO -- default. Eligible fns JIT after warming past the runtime's hot threshold (currently 100 calls; tune with mino_state_set_jit_hot_threshold). Cold fns stay on the interpreter. OFF -- never JIT. The interpreter handles every call. Useful for embedding hosts that need predictable cold-start latency, deterministic resource usage, or that ship a security policy banning W^X violations. ON -- JIT every eligible fn on its first call (no threshold). Useful for benchmarking or when the embedder knows ahead of time that JIT'd execution is wanted everywhere.

mino-lean (the no-JIT distributable) ignores the mode and behaves as if OFF; the call exists in both builds so embedders can write portable initialisation code.

Initial mode on state_new follows MINO_JIT env var (auto / off / on case-insensitive), defaulting to AUTO.

VariantDescription
MINO_JIT_MODE_AUTO
MINO_JIT_MODE_OFF
MINO_JIT_MODE_ON

mino_state_set_jit_mode

void            mino_state_set_jit_mode(mino_state *S, mino_jit_mode mode);

mino_state_jit_mode

mino_jit_mode mino_state_jit_mode(const mino_state *S);

mino_state_set_jit_hot_threshold

JIT hot threshold (call count before AUTO mode triggers a compile). Defaults to a runtime-internal value (currently 100). Embedders tune it per-workload via this setter:

- Lower values JIT sooner (better steady-state throughput at the cost of more upfront compile time and a larger native footprint -- short-lived fns may compile then never run again). - Higher values delay JIT (less upfront work, but slower to warm).

A value of 0 is clamped to 1 (compile on first call -- the same behaviour as MINO_JIT_MODE_ON, but staying in AUTO so the OFF/ON gate still applies). The threshold is irrelevant when the mode is OFF (no compile happens regardless) or ON (compile fires on call 1).

Initial value follows MINO_JIT_HOT_THRESHOLD env var (positive integer); unparseable / non-positive values fall back to the default. NULL state is a no-op.

void     mino_state_set_jit_hot_threshold(mino_state *S, unsigned threshold);

mino_state_jit_hot_threshold

unsigned mino_state_jit_hot_threshold(const mino_state *S);

struct mino_jit_capabilitystruct

JIT capability query. Returns a snapshot of the runtime's JIT configuration so embedders can inspect what they got -- useful for diagnostics, telemetry, and conditional embedding logic that wants to behave differently when JIT is unavailable.

available -- non-zero when this build was compiled with JIT support AND the host arch / OS is one of the supported targets. Always 0 on mino-lean. mode -- the state's current mino_jit_mode. threshold -- the state's current hot threshold. host_arch -- "arm64" / "x86_64" / "unknown". host_os -- "darwin" / "linux" / "windows" / "unknown".

The host_arch and host_os strings live in static storage; the caller does not free them.

TypeFieldDescription
intavailable
mino_jit_modemode
unsignedthreshold
const char *host_arch
const char *host_os

mino_state_jit_capability

mino_jit_capability mino_state_jit_capability(const mino_state *S);

Environment and evaluator

mino_env_new

Allocate a fresh root environment and register it with the collector so every value reachable through it survives collection. The runtime holds the returned env weakly: mino_env_free unregisters it and lets the next sweep reclaim the frame and any closures that were reachable only from within it. The host does not free any mino-owned pointers directly.

Returns NULL on allocation failure (check mino_last_error).

mino_env *mino_env_new(mino_state *S);

mino_env_free

Free an environment and unregister it from the collector.

void        mino_env_free(mino_state *S, mino_env *env);

mino_env_clone

Clone an environment: allocate a new root environment and copy all bindings from the source. Values are shared (not deep-copied), so the clone is only meaningful within the same state. Useful for snapshotting a session before independent evaluation in each copy.

mino_env *mino_env_clone(mino_state *S, mino_env *env);

mino_env_new_default

Convenience: allocate a new env and install the sandbox preset. Equivalent to:

mino_env *env = mino_env_new(S); mino_install_sandbox(S, env);

Use this when getting a runnable env in one line matters and the sandbox surface is the right contract. For a custom tier, build the env explicitly and pass a MINO_CAP_* bitmask to mino_install.

mino_env *mino_env_new_default(mino_state *S);

mino_env_set

Define or replace a binding in env.

void        mino_env_set(mino_state *S, mino_env *env, const char *name, mino_val *val);

mino_env_get

Look up name. Returns NULL if unbound.

mino_val *mino_env_get(mino_env *env, const char *name);

mino_eval

Evaluate one form. Returns NULL on error and writes a message via mino_last_error(). Returns mino_nil() for an explicit nil result.

A top-level try frame catches out-of-memory conditions and unhandled exceptions during evaluation, surfacing them as NULL + error message rather than aborting the process. The state remains usable after an OOM return.

mino_val *mino_eval(mino_state *S, mino_val *form, mino_env *env);

mino_eval_string

Read and evaluate all forms in src. Returns the value of the last form, or NULL on error. An empty string returns mino_nil().

Installs its own try frame: OOM during read or eval returns NULL with an error message rather than aborting.

mino_val *mino_eval_string(mino_state *S, const char *src, mino_env *env);

mino_load_file

Read a file at path and evaluate all forms. Returns the value of the last form, or NULL on error (file I/O failures and parse/eval errors).

mino_val *mino_load_file(mino_state *S, const char *path, mino_env *env);

mino_eval_ex

Protected variants of mino_eval / mino_eval_string / mino_load_file. Return 0 on success (writing the result to *out) or -1 on error.

Unlike the unsuffixed variants, the _ex form disambiguates "real nil result" from "error": a 0 return with *out == mino_nil() is genuine nil; a -1 return means a throw / OOM / parse failure was caught. If out_ex is non-NULL, on error *out_ex is set to the raw thrown payload (matching mino_pcall's contract). *out_ex is NULL on success or when out_ex is NULL.

The _ex variants do NOT publish to mino_last_error on a caught throw; embedders that want a diagnostic must inspect *out_ex or call mino_last_error explicitly.

int mino_eval_ex       (mino_state *S, mino_val *form, mino_env *env, mino_val **out, mino_val **out_ex);

mino_eval_string_ex

int mino_eval_string_ex(mino_state *S, const char *src, mino_env *env, mino_val **out, mino_val **out_ex);

mino_load_file_ex

int mino_load_file_ex  (mino_state *S, const char *path, mino_env *env, mino_val **out, mino_val **out_ex);

mino_register_fn

Shorthand: bind a C function as a primitive in env. Equivalent to mino_env_set(S, env, name, mino_prim(S, name, fn)).

void mino_register_fn(mino_state *S, mino_env *env, const char *name, mino_prim_fn fn);

struct mino_regstruct

Bulk-register an array of C primitives. The array is terminated by a sentinel row {NULL, NULL, NULL, 0}. Each row's argv field picks the ABI: 0 = cons-list (fn is mino_prim_fn), 1 = argv (fn2 is mino_prim_fn2). Either fn or fn2 must be set (matching the chosen ABI), the other can be NULL. Matches the peer convention used by other embedded scripting C APIs for bulk registration.

Example: static mino_val *prim_a(mino_state *S, mino_val *args, mino_env *e) {...} static mino_val *prim_b(mino_state *S, mino_val **argv, int n, mino_env *e) {...} static const mino_reg my_prims[] = { {"a", prim_a, NULL, 0}, {"b", NULL, prim_b, 1}, {NULL, NULL, NULL, 0}, }; mino_register_fns(S, env, my_prims);

TypeFieldDescription
const char *name
mino_prim_fnfn
mino_prim_fn2fn2
intargv0 = cons ABI (use fn), 1 = argv ABI (use fn2)

mino_register_fns

void mino_register_fns(mino_state *S, mino_env *env, const mino_reg *regs);

mino_call

Call a callable value (fn, macro, prim) with an argument list. Returns the result, or NULL on error (via mino_last_error).

mino_val *mino_call(mino_state *S, mino_val *fn, mino_val *args, mino_env *env);

mino_pcall

Protected call: same as mino_call but returns 0 on success (writing the result to *out) or -1 on error. The error message is available via mino_last_error(). *out is set to NULL on error.

If out_ex is non-NULL, on error *out_ex is set to the raw thrown exception value (the cell passed to (throw ...) by the inner code). This is the original payload, not a diagnostic map -- useful for captures-and-stores callers like agent dispatch and STM validator handling that want to surface the user's ex-info / map / etc. unchanged. *out_ex is set to NULL on success or if out_ex is NULL.

int mino_pcall(mino_state *S, mino_val *fn, mino_val *args, mino_env *env, mino_val **out, mino_val **out_ex);

Exceptions

mino_throw

Raise a mino exception carrying ex as the payload. When called from a C primitive that is executing inside a mino (try ... (catch ...)) frame, the payload is delivered to the matching catch binding. When called outside any try frame, the exception surfaces as a classified error through mino_last_error (kind "user", code "MUS001") and the function returns NULL.

Inside a try frame this call does NOT return; control transfers to the try handler via longjmp. Callers should treat it as "returns NULL" for typing purposes and not rely on any code after the call:

return mino_throw(S, mino_keyword(S, "bad-arg"));

The payload can be any mino value: a keyword, a string, or an information-carrying map built via mino_map(). This is the C-side analogue of the (throw ex) mino primitive.

mino_val *mino_throw(mino_state *S, mino_val *ex);

Argument parsing

mino_args_parse

Type-check and destructure a primitive's argument list into C variables. The format string lists one character per expected positional argument; each variadic pointer receives the corresponding extracted value:

"i" long long * -- MINO_INT "f" double * -- MINO_FLOAT or MINO_INT (promoted) "s" const char -- MINO_STRING; pointer into mino-owned data "S" const char , -- MINO_STRING; pointer plus byte length size_t * (write both in order: "S" consumes two ptrs) "k" const char -- MINO_KEYWORD name (without the leading :) "y" const char -- MINO_SYMBOL name "b" int * -- MINO_BOOL (0 or 1) "c" int * -- MINO_CHAR codepoint (0..0x10FFFF) "v" mino_val -- any value (no type check) "V" mino_val -- MINO_VECTOR "M" mino_val -- MINO_MAP "L" mino_val -- MINO_CONS or MINO_NIL (a list) "H" mino_val -- MINO_HANDLE "A" mino_val -- MINO_ATOM

Returns 0 on success, -1 on arity or type error. On failure the current error is set via mino_last_error with kind "eval/arity" or "eval/type" so the caller can just return NULL; after a non-zero return. The name argument is used in error messages ("foo: expected int, got string").

Extra arguments beyond the format string cause an arity error; missing arguments do the same.

int mino_args_parse(mino_state *S, const char *name, mino_val *args, const char *fmt, ...);

Host interop

mino_host_enable

Enable interop dispatch. By default all host primitives return "interop disabled". Call this after registration to activate them.

void mino_host_enable(mino_state *S);

mino_host_register_ctor

Register host capabilities. String arguments must outlive the state. Call before eval -- the registry is intended to be immutable after init.

arity: expected argument count, or -1 for variadic.

void mino_host_register_ctor(mino_state *S, const char *type_key, int arity, mino_host_fn fn, void *ctx);

mino_host_register_method

void mino_host_register_method(mino_state *S, const char *type_key, const char *method_key, int arity, mino_host_fn fn, void *ctx);

mino_host_register_static

void mino_host_register_static(mino_state *S, const char *type_key, const char *method_key, int arity, mino_host_fn fn, void *ctx);

mino_host_register_getter

void mino_host_register_getter(mino_state *S, const char *type_key, const char *field_key, mino_host_fn fn, void *ctx);

Modules

mino_resolve_fntypedef

typedef const char *(*mino_resolve_fn)(const char *name, void *ctx);

Module resolver callback. Given a module name (the argument to require), return a file path to load, or NULL on failure. ctx is the opaque pointer passed to mino_set_resolver.

mino_set_resolver

Register a module resolver. When mino code calls (require "name"), the resolver is invoked to map the name to a file path. The file is loaded once; subsequent requires of the same name return the cached value. Pass NULL to remove the resolver.

void mino_set_resolver(mino_state *S, mino_resolve_fn fn, void *ctx);

mino_register_bundled_lib

Register a bundled-stdlib source under name. Subsequent calls to (require ') load this in-memory source instead of going to the disk resolver, so embeds and brew/scoop installs without a lib/ directory still resolve their bundled namespaces.

The source pointer must outlive the state -- typically a static C-string literal in a generated header (e.g. lib_clojure_string.h). The name is copied and freed at state teardown. Re-registering the same name silently replaces the previous source.

Use mino_install_clojure_ wrappers (declared below) when an install hook fits the embedder's group; this raw API is exposed for embedders that bundle their own non-clojure namespaces (mirroring mino_set_resolver for the disk path).

void mino_register_bundled_lib(mino_state *S, const char *name, const char *source);

Capability-gated install API

MINO_CAP_FLOORmacro

#define MINO_CAP_FLOOR         (1u <<  0)

Capabilities are addressable as bits. Pass a bitmask to mino_install to install exactly the subset the host wants:

mino_install(S, env, MINO_CAP_IO | MINO_CAP_FS | MINO_CAP_REGEX);

Or pick one of the named presets:

mino_install_minimal(S, env) -> floor only, no core.clj mino_install_sandbox(S, env) -> floor + canonical Clojure-core + safe libs; no I/O, FS, PROC, STM, AGENT, HOST, ASYNC mino_install_all(S, env) -> every capability and every bundled lib

The floor (MINO_CAP_FLOOR) is always installed by any mino_install* call — numeric, collections, sequences, printing, foundational macros, plus the *ns* / *out* / *in* dynamic vars. Passing caps = 0 to mino_install is equivalent to mino_install_minimal.

Capabilities are independent; mino_install does not chain implicit dependencies. Embedders who want canonical bundles use MINO_CAP_DEFAULT or MINO_CAP_ALL. mino_install is idempotent: re-installing a capability is a no-op.

Calling mino_install with any non-floor capability also evaluates core.clj on the floor env so the capability-gated sections fire.

MINO_CAP_REGEXmacro

#define MINO_CAP_REGEX         (1u <<  1)

MINO_CAP_BIGNUMmacro

#define MINO_CAP_BIGNUM        (1u <<  2)

MINO_CAP_MULTIMETHODSmacro

#define MINO_CAP_MULTIMETHODS  (1u <<  3)

MINO_CAP_PROTOCOLSmacro

#define MINO_CAP_PROTOCOLS     (1u <<  4)

MINO_CAP_TRANSDUCERSmacro

#define MINO_CAP_TRANSDUCERS   (1u <<  5)

MINO_CAP_IOmacro

#define MINO_CAP_IO            (1u <<  6)

MINO_CAP_FSmacro

#define MINO_CAP_FS            (1u <<  7)

MINO_CAP_PROCmacro

#define MINO_CAP_PROC          (1u <<  8)

MINO_CAP_STMmacro

#define MINO_CAP_STM           (1u <<  9)

MINO_CAP_AGENTmacro

#define MINO_CAP_AGENT         (1u << 10)

MINO_CAP_HOSTmacro

#define MINO_CAP_HOST          (1u << 11)

MINO_CAP_ASYNCmacro

#define MINO_CAP_ASYNC         (1u << 12)

MINO_CAP_STRING_LIBmacro

#define MINO_CAP_STRING_LIB    (1u << 13)  /* clojure.string */

clojure.string

MINO_CAP_SET_LIBmacro

#define MINO_CAP_SET_LIB       (1u << 14)  /* clojure.set */

clojure.set

MINO_CAP_WALKmacro

#define MINO_CAP_WALK          (1u << 15)  /* clojure.walk */

clojure.walk

MINO_CAP_EDNmacro

#define MINO_CAP_EDN           (1u << 16)  /* clojure.edn */

clojure.edn

MINO_CAP_PPRINTmacro

#define MINO_CAP_PPRINT        (1u << 17)  /* clojure.pprint */

clojure.pprint

MINO_CAP_ZIPmacro

#define MINO_CAP_ZIP           (1u << 18)  /* clojure.zip */

clojure.zip

MINO_CAP_DATAmacro

#define MINO_CAP_DATA          (1u << 19)  /* clojure.data */

clojure.data

MINO_CAP_TESTmacro

#define MINO_CAP_TEST          (1u << 20)  /* clojure.test (+ clojure.test.check) */

clojure.test (+ clojure.test.check)

MINO_CAP_REPL_LIBmacro

#define MINO_CAP_REPL_LIB      (1u << 21)  /* clojure.repl */

clojure.repl

MINO_CAP_DATAFYmacro

#define MINO_CAP_DATAFY        (1u << 22)  /* clojure.datafy + core.protocols */

clojure.datafy + core.protocols

MINO_CAP_INSTANTmacro

#define MINO_CAP_INSTANT       (1u << 23)  /* clojure.instant */

clojure.instant

MINO_CAP_SPECmacro

#define MINO_CAP_SPEC          (1u << 24)  /* clojure.spec.alpha */

clojure.spec.alpha

MINO_CAP_TOOLINGmacro

#define MINO_CAP_TOOLING       (1u << 25)  /* mino.deps + mino.tasks */

mino.deps + mino.tasks

MINO_CAP_MATH_LIBmacro

#define MINO_CAP_MATH_LIB      (1u << 26)  /* clojure.math */

clojure.math

MINO_CAP_REDUCERSmacro

#define MINO_CAP_REDUCERS      (1u << 27)  /* clojure.core.reducers */

clojure.core.reducers

MINO_CAP_DEFAULTmacro

#define MINO_CAP_DEFAULT (MINO_CAP_FLOOR | MINO_CAP_REGEX | MINO_CAP_BIGNUM | \

The sandbox preset: floor + Clojure-core (multimethods, protocols, transducers, regex, bignum) + the bundled libraries that have no I/O surface (string, set, walk, edn, data, test, datafy). Excludes IO, FS, PROC, HOST, STM, AGENT, ASYNC.

MINO_CAP_ALLmacro

#define MINO_CAP_ALL     0xFFFFFFFFu

Every defined capability bit.

mino_install

Install the given set of capabilities into env. FLOOR is always installed implicitly. Passing 0 installs just the floor (no core.clj), matching mino_install_minimal. Idempotent: bits already installed are skipped silently.

void mino_install(mino_state *S, mino_env *env, unsigned int caps);

mino_install_minimal

Floor-only convenience. Installs the foundational C primitives plus the unconditional sections of core.clj's prelude (defn / when / cond / and / or / threading / lazy seqs / basic collections / printing). Does NOT evaluate core.clj. Use when targeting Lua-class cold start in embedded mode.

void mino_install_minimal(mino_state *S, mino_env *env);

mino_install_sandbox

Sandbox preset: equivalent to mino_install(S, env, MINO_CAP_DEFAULT). Names the recipe for "safe untrusted-script env" so embedders don't reinvent the threat model.

void mino_install_sandbox(mino_state *S, mino_env *env);

mino_install_all

Install every capability and every bundled stdlib namespace the standalone binary ships with. Equivalent to mino_install(S, env, MINO_CAP_ALL).

void mino_install_all(mino_state *S, mino_env *env);

mino_capabilities

Inspect installed capabilities. Bit set per MINO_CAP_*.

unsigned int mino_capabilities(const mino_state *S);

mino_capability_installed

int          mino_capability_installed(const mino_state *S, unsigned int cap);

struct mino_capability_infostruct

Enumerate the full capability registry. The returned array is static, NULL-terminated, and ordered by install tier. Each entry names the capability, its bit, and a one-line UX summary. Use this to render a "supported capabilities" list to the host's user.

TypeFieldDescription
const char *namecanonical label ("io", "regex", ...)
unsigned intbitMINO_CAP_*
const char *summaryone-line UX description

mino_capability_list

const mino_capability_info *mino_capability_list(void);

mino_capability_for_symbol

Look up the capability that owns a given symbol name, if any. Returns the capability info pointer or NULL when the name is not a known gateable primitive or canonical core.clj definition. Used by the eval_symbol MNS002 diagnostic to enrich "unbound symbol" errors.

const mino_capability_info *mino_capability_for_symbol(const char *name);

Execution limits

MINO_LIMIT_STEPSmacro

#define MINO_LIMIT_STEPS  1   /* max eval steps per mino_eval/mino_eval_string */

max eval steps per mino_eval/mino_eval_string

MINO_LIMIT_HEAPmacro

#define MINO_LIMIT_HEAP   2   /* max bytes under GC management                */

max bytes under GC management

mino_set_limit

Set a global execution limit. Pass 0 to disable a limit. Step limits are reset at the start of each mino_eval or mino_eval_string call. When a limit is exceeded, the current eval returns NULL and mino_last_error() reports the cause.

void mino_set_limit(mino_state *S, int kind, size_t value);

mino_interrupt

Request interruption of a running eval. Sets a flag that the eval loop checks on each step. Safe to call from a different thread than the one running eval. The flag is cleared at the start of the next eval call.

void mino_interrupt(mino_state *S);

Host thread grant

mino_set_thread_limit

Set the per-state thread limit. n=0 or n=1 disables host threads; n>1 grants the runtime permission to spawn that many concurrent worker threads. Calling with the same value twice is a no-op.

Calling with n>1 BEFORE any (future ...) is in flight is the supported sequence; lowering the limit while threads are running does not interrupt them, but new spawns will respect the new ceiling.

void mino_set_thread_limit(mino_state *S, int n);

mino_get_thread_limit

Read the current thread limit. Returns 1 by default (single-threaded).

int  mino_get_thread_limit(mino_state *S);

mino_thread_count

Return the count of host threads currently spawned by this state. Decremented as threads complete and join. Returns 0 in single- threaded mode.

int  mino_thread_count(mino_state *S);

mino_quiesce_threads

Wait for all in-flight host threads to finish. Intended to be called by the embedder before mino_state_free; calling it from a worker thread that this state spawned is undefined behaviour. Safe to call when no threads are in flight (returns immediately).

void mino_quiesce_threads(mino_state *S);

Host thread pool, factory, stack-size knobs subject to change

This section is provisional. Symbols below may change in subsequent releases; pin your usage and re-test on each version bump.

struct mino_thread_poolstructsubject to change

Function-pointer interface a host thread pool implements. Mino calls submit_fn for each (future ...) while a pool is registered; the pool MUST eventually call (*work)(ctx) on a worker thread. The pool MUST NOT call work synchronously on the calling thread — that defeats the parallelism mino is asking for.

TypeFieldDescription
void *user_data

mino_set_thread_poolsubject to change

Register a host thread pool for this state. Pass NULL to revert to spawn-per-future. The pool's submit_fn is consulted for each (future ...). The pool may be shared across multiple states; mino does not enforce single-state ownership. The thread_limit still applies — submission is rejected when the per-state count is full.

void mino_set_thread_pool(mino_state *S, mino_thread_pool *pool);

mino_thread_lifecycle_fntypedefsubject to change

typedef void (*mino_thread_lifecycle_fn)(mino_state *S, void *ctx);

Per-thread factory hooks for the spawn-per-future path. start_fn runs on the worker thread before the body executes; end_fn runs after the body returns (whether normally or via uncaught throw). ctx is opaque to mino. Pass NULL fns to clear. Ignored entirely when a pool is registered (the pool owns thread lifecycle).

mino_set_thread_factorysubject to change

void mino_set_thread_factory(mino_state *S, mino_thread_lifecycle_fn start_fn, mino_thread_lifecycle_fn end_fn, void *ctx);

mino_set_thread_stack_sizesubject to change

Per-worker stack size for the spawn-per-future path. n=0 means platform default. Ignored when a pool is registered.

void mino_set_thread_stack_size(mino_state *S, size_t n);

Garbage collector control subject to change

This section is provisional. Symbols below may change in subsequent releases; pin your usage and re-test on each version bump.

mino_gc_kindenumsubject to change

UNSTABLE: GC tuning, kind enum, phase constants, and the stats struct stay UNSTABLE through the 0.x alpha series. The collector is still evolving (generational + incremental layout, threshold heuristics) and this section will track those changes. Pin behavior through explicit mino_gc_collect calls at quiescent points; do not rely on tuning parameter ranges or the stats struct layout across releases.

Kinds of collection the host can request. Use at quiescent points such as between REPL turns, after bulk import, or before long-idle periods.

MINO_GC_MINOR -- nursery collection only; cheapest, bounded by young set size. Safe at any time including mid-major. MINO_GC_MAJOR -- drain any in-flight incremental major cycle and sweep, then start a fresh STW major if no cycle is active. Reclaims old-gen dead; leaves young-gen alone. MINO_GC_FULL -- minor, then finish or run a fresh STW major. Strongest reclamation; highest pause.

VariantDescription
MINO_GC_MINOR
MINO_GC_MAJOR
MINO_GC_FULL

mino_gc_collectsubject to change

void mino_gc_collect(mino_state *S, mino_gc_kind kind);

mino_gc_paramenumsubject to change

Tunable parameters. Values out of range are rejected; mino_gc_set_param returns 0 on success and -1 on a bad parameter or out-of-range value.

NURSERY_BYTES young-gen trigger; minor fires when young exceeds. Default 1 MiB. Range 64 KiB .. 256 MiB. MAJOR_GROWTH_TENTHS old-gen growth multiplier in tenths (15 = 1.5x). Default 15. Range 11 .. 40. PROMOTION_AGE minor-survival count before YOUNG->OLD promotion. Default 1. Range 1 .. 8. INCREMENTAL_BUDGET headers popped per incremental major slice. Default 4096. Range 64 .. 65536. STEP_ALLOC_BYTES bytes allocated between automatic slices. Default 16 KiB. Range 1 KiB .. 16 MiB.

VariantDescription
MINO_GC_NURSERY_BYTES
MINO_GC_MAJOR_GROWTH_TENTHS
MINO_GC_PROMOTION_AGE
MINO_GC_INCREMENTAL_BUDGET
MINO_GC_STEP_ALLOC_BYTES

mino_gc_set_paramsubject to change

int mino_gc_set_param(mino_state *S, mino_gc_param p, size_t value);

MINO_GC_PHASE_IDLEmacrosubject to change

#define MINO_GC_PHASE_IDLE        0

Phase tag returned in mino_gc_stats_out.phase.

MINO_GC_PHASE_MINORmacrosubject to change

#define MINO_GC_PHASE_MINOR       1

MINO_GC_PHASE_MAJOR_MARKmacrosubject to change

#define MINO_GC_PHASE_MAJOR_MARK  2

MINO_GC_PHASE_MAJOR_SWEEPmacrosubject to change

#define MINO_GC_PHASE_MAJOR_SWEEP 3

struct mino_gc_stats_outstructsubject to change

Collector statistics. Populated by mino_gc_stats. No allocation is performed; the host owns the out struct. Counters are cumulative since state creation except where noted.

Note: bytes_alloc is NOT a monotonic total. It tracks bytes live in the bump path; minor GC decrements it by the bytes it sweeps and major GC resets it to bytes_live. To recover a true allocation total over a window, sum (delta bytes_alloc + delta bytes_freed); bytes_freed IS monotonic. This is the formula the perf-gate allocation tracker uses.

TypeFieldDescription
size_tcollections_minor
size_tcollections_major
size_tbytes_liveyoung + old
size_tbytes_young
size_tbytes_old
size_tbytes_alloccurrent; reset by major, decremented by minor
size_tbytes_freedmonotonic: total ever swept
size_ttotal_gc_ns
size_tmax_gc_ns
size_tminor_mark_ns
size_tminor_sweep_ns
size_tmajor_mark_ns
size_tmajor_sweep_ns
size_troot_scan_ns
size_tbarrier_satb_pushes
size_tbarrier_dijkstra_pushes
size_tmark_stack_overflows
size_tbytes_promoted_minor
uint64_tyoung_age_bucket[8]
uint64_talloc_by_tag[16]
size_tremset_entriescurrent remembered-set size
size_tremset_capremembered-set capacity
size_tremset_high_waterpeak remset size this state
size_tmark_stack_capmark-stack capacity
size_tmark_stack_high_waterpeak mark-stack depth this state
intphaseMINO_GC_PHASE_*

mino_gc_statssubject to change

void mino_gc_stats(mino_state *S, mino_gc_stats_out *out);

mino_gc_stats_pausessubject to change

Pause-time distribution accessors. The GC keeps a circular buffer of the last 256 pause durations (one entry per minor / major slice / fully-STW major) and a log2 histogram covering buckets [2^i, 2^(i+1)) ns from i = 0 (1 ns) to i = 23 (>= 8.4 ms).

mino_gc_stats_pauses populates the four percentile out-pointers from the recent-window ring (any of which may be NULL to skip). Percentiles are computed by sorting a temporary copy of the active ring entries; computed values are saturated at UINT32_MAX ns.

mino_gc_pause_hist copies the 24-bucket lifetime histogram into the host-owned out array. out_count returns the number of valid entries currently in the ring (0..256).

void mino_gc_stats_pauses(mino_state *S, uint64_t *out_p50_ns, uint64_t *out_p95_ns, uint64_t *out_p99_ns, uint64_t *out_max_ns);

mino_gc_pause_histsubject to change

void mino_gc_pause_hist(mino_state *S, uint32_t out_buckets[24], unsigned *out_count);

Allocation profiler subject to change

This section is provisional. Symbols below may change in subsequent releases; pin your usage and re-test on each version bump.

mino_alloc_profile_enabledsubject to change

UNSTABLE: the allocation profiler is opt-in (compile-time gated on -DMINO_ALLOC_PROFILE=1) and stays UNSTABLE through the 0.x alpha series; its output format is in flux. The functions below are part of the public surface for parity with tooling that needs profile data, but their shape may change in subsequent releases.

Reports 1 when the binary was built with -DMINO_ALLOC_PROFILE=1, else 0. The recording paths and dump output are only meaningful in profile builds.

int  mino_alloc_profile_enabled(void);

mino_alloc_profile_resetsubject to change

Reset the profile counters to zero. No-op in non-profile builds.

void mino_alloc_profile_reset(mino_state *S);

mino_alloc_profile_dump_topsubject to change

Dump the top top_n call sites by allocation count to out (stderr if NULL). Pass top_n <= 0 to dump every recorded site. Format is a fixed-width table: rank, count, bytes, tag, file:line. In non-profile builds emits a single "rebuild with MINO_ALLOC_PROFILE=1" line.

void mino_alloc_profile_dump_top(mino_state *S, FILE *out, int top_n);

In-process REPL handle

MINO_REPL_OKmacro

#define MINO_REPL_OK     0   /* form evaluated; result written to *out      */

Return codes for mino_repl_feed.

MINO_REPL_MOREmacro

#define MINO_REPL_MORE   1   /* line accepted; more input needed            */

line accepted; more input needed

MINO_REPL_ERRORmacro

#define MINO_REPL_ERROR  2   /* parse or eval error; see mino_last_error()  */

parse or eval error; see mino_last_error()

mino_repltypedefstruct mino_repl

typedef struct mino_repl mino_repl;

mino_repl_new

Create a REPL handle that evaluates forms in env. The handle owns an internal line buffer; the host drives it by feeding one line at a time via mino_repl_feed. No thread is required: the host controls the call cadence entirely.

env must outlive the REPL handle.

mino_repl *mino_repl_new(mino_state *S, mino_env *env);

mino_repl_feed

Feed one line of input to the REPL. Returns: MINO_REPL_OK - a complete form was read and evaluated. The result is written to *out (when out is non-NULL). MINO_REPL_MORE - the line was accumulated; more input is needed to complete the current form. MINO_REPL_ERROR - a parse or eval error occurred. The error message is available via mino_last_error(). The buffer is reset so the next feed starts a fresh form.

Multiple complete forms on one line: only the first is evaluated per call. Feed an empty line (or call again with "") to drain remaining buffered forms.

int mino_repl_feed(mino_repl *repl, const char *line, mino_val **out);

mino_repl_free

Free the REPL handle and its internal buffer. Does not free env.

void mino_repl_free(mino_repl *repl);

Value retention (refs)

mino_ref_new

Values returned by constructors and eval are borrowed: they survive until the next GC cycle but are not pinned. A ref roots a value so it survives collection indefinitely. The host must call mino_unref when the value is no longer needed.

mino_ref *r = mino_ref_new(S, val); // root val mino_val *v = mino_deref(r); // get the value mino_unref(S, r); // release the root

Refs are owned by the state that created them and freed when the state is freed, but the host should unref explicitly to avoid holding objects longer than necessary.

mino_ref *mino_ref_new(mino_state *S, mino_val *val);

mino_deref

mino_val *mino_deref(const mino_ref *ref);

mino_unref

void        mino_unref(mino_state *S, mino_ref *ref);

Value cloning (cross-state transfer)

mino_clone

Deep-copy a value from one state into another. Transferable types: nil, bool, int, float, string, symbol, keyword, cons, vector, map, set.

Returns NULL (and sets an error on dst) if the value contains a non-transferable type (fn, macro, prim, handle, atom, lazy-seq). Nested collections are cloned recursively; a non-transferable element anywhere in the tree causes the entire clone to fail.

mino_val *mino_clone(mino_state *dst, mino_state *src, mino_val *val);