packages feed

nova-nix-0.2.0.0: cbits/nn_env.h

/*
 * nn_env.h — C-native evaluation environments.
 *
 * Nix evaluation creates millions of environments, each with a
 * variable-size array of slot pointers, optional lazy scope (attr set),
 * optional parent pointer, and a with-scopes chain.
 *
 * All nn_env_t structs and their backing arrays are arena-allocated
 * from a page-based bump allocator.  Nothing is individually freed —
 * nn_env_destroy() tears down everything at eval end.
 *
 * Lifecycle: nn_env_init() before evaluation, nn_env_destroy() after.
 * Not thread-safe — single-threaded evaluation only.
 */

#ifndef NN_ENV_H
#define NN_ENV_H

#include <stdint.h>

/* --- Env struct --- */

/* 48 bytes on 64-bit (with padding after slot_count and with_count).
 * Could be reduced to 40 bytes by reordering fields, but the current
 * layout groups related fields logically and matches access patterns. */
typedef struct nn_env {
    void         **slots;        /* nn_thunk_t* array (or NULL for 0 slots) */
    uint32_t       slot_count;   /* 4 bytes + 4 pad to align lazy_scope */
    void          *lazy_scope;   /* nn_attrset_t* or NULL */
    struct nn_env *parent;       /* nn_env_t* or NULL */
    void         **with_scopes;  /* array of nn_attrset_t* (or NULL) */
    uint16_t       with_count;   /* 2 bytes + 6 pad to struct alignment */
} nn_env_t;

/* --- Lifecycle --- */

/* Initialize the global env allocator.  Must be called once before
 * any nn_env_* calls (except nn_env_destroy). */
void nn_env_init(void);

/* Destroy the global env allocator, freeing all page memory.
 * All pointers returned by any nn_env_* function become invalid. */
void nn_env_destroy(void);

/* --- Slot allocation (unchanged from original API) --- */

/* Allocate an array of `count` void* pointers.  O(1) amortized.
 * All slots initialized to NULL.  Returns NULL if count is 0. */
void **nn_env_alloc_slots(uint32_t count);

/* --- Env constructors (all arena-allocated) --- */

/* Return a pointer to the global empty env (all fields zero/NULL).
 * Valid until nn_env_destroy().  Do not modify the returned struct. */
nn_env_t *nn_env_empty(void);

/* Full constructor: set all fields explicitly. */
nn_env_t *nn_env_new(void **slots, uint32_t slot_count,
                     void *lazy_scope, nn_env_t *parent,
                     void **with_scopes, uint16_t with_count);

/* Child env with positional slots, inheriting parent's with-scopes.
 * lazy_scope = NULL. */
nn_env_t *nn_env_from_slots(void **slots, uint32_t slot_count,
                            nn_env_t *parent);

/* Copy base env with a new with-scope prepended (innermost position).
 * Allocates a new with-scopes array of size (base->with_count + 1). */
nn_env_t *nn_env_push_with(nn_env_t *base, void *scope);

/* Minimal env: slots only, no parent, no with-scopes, no lazy scope. */
nn_env_t *nn_env_new_minimal(void **slots, uint32_t slot_count);

/* --- Accessors --- */

void       **nn_env_slots(const nn_env_t *env);
uint32_t     nn_env_slot_count(const nn_env_t *env);
void        *nn_env_lazy_scope(const nn_env_t *env);
nn_env_t    *nn_env_parent(const nn_env_t *env);
void       **nn_env_with_scopes(const nn_env_t *env);
uint16_t     nn_env_with_count(const nn_env_t *env);

/* --- Lookup --- */

/* Resolved variable lookup: walk `level` parent hops, then read
 * slots[idx].  Returns the nn_thunk_t* at that position.
 * Caller must ensure level/idx are in bounds (guaranteed by
 * the resolution pass). */
void *nn_env_lookup_resolved(const nn_env_t *env, int level, int idx);

/* Walk parent chain to the root env (parent == NULL), return its
 * lazy_scope.  Returns NULL if the root has no lazy scope. */
void *nn_env_root_scope(const nn_env_t *env);

/* --- With-scopes array allocation --- */

/* Allocate an arena array of `count` void* pointers for with-scopes.
 * All entries initialized to NULL.  Returns NULL if count is 0. */
void **nn_env_alloc_with_scopes(uint16_t count);

/* --- Diagnostics --- */

/* Total bytes allocated across all pages (for memory tracking). */
uint64_t nn_env_bytes_allocated(void);

#endif /* NN_ENV_H */