1
1
mirror of https://github.com/urbit/shrub.git synced 2024-12-15 04:22:48 +03:00

%ames to %gall as /q/gm/[app]/[logo].

This commit is contained in:
C. Guy Yarvin 2014-06-26 05:18:30 -07:00
parent 84bbaa3b7a
commit e21d615beb

673
include/f/liar.h Normal file
View File

@ -0,0 +1,673 @@
/* include/rail.h
**
** This file is in the public domain.
*/
/** Configurations.
**/
# undef U2_LEAK_DEBUG
# ifdef U2_LEAK_DEBUG
# define u2_leak_on(x) (COD_w = x)
extern c3_w COD_w;
# define u2_leak_off (COD_w = 0)
# endif
/** Data types.
**/
/** Ray types.
**/
/* u2_rail: an allocation control frame.
*/
typedef u2_ray u2_rail;
/* u2_wire: an execution context, inheriting rail
*/
typedef u2_ray u2_wire;
/** Structures - in loom space.
**/
/* Base rail.
*/
typedef struct _u2_loom_rail {
u2_ray cap_r; // top of transient region
u2_ray hat_r; // top of new durable region
u2_ray mat_r; // bottom of transient region
u2_ray rut_r; // bottom of new durable region
c3_m hip_m; // memory model in durable; c3__rock, c3__sand
} u2_loom_rail;
# define u2_rail_cap_r(ral_r) *u2_at(ral_r, u2_loom_rail, cap_r)
# define u2_rail_hat_r(ral_r) *u2_at(ral_r, u2_loom_rail, hat_r)
# define u2_rail_mat_r(ral_r) *u2_at(ral_r, u2_loom_rail, mat_r)
# define u2_rail_rut_r(ral_r) *u2_at(ral_r, u2_loom_rail, rut_r)
# define u2_rail_hip_m(ral_r) *u2_at(ral_r, u2_loom_rail, hip_m)
/* Pork - base of frame.
*/
typedef struct {
u2_ray mut_r; // parent mat
u2_ray rit_r; // parent rut
c3_m hap_m; // parent hip
} u2_loom_pork;
# define u2_pork_mut_r(pik_r) *u2_at(pik_r, u2_loom_pork, mut_r)
# define u2_pork_rit_r(pik_r) *u2_at(pik_r, u2_loom_pork, rit_r)
# define u2_pork_hap_m(pik_r) *u2_at(pik_r, u2_loom_pork, hap_m)
/* Floe - a solid rail allocator. Implied by `hip_m == c3__sand`.
*/
typedef struct {
} u2_loom_floe;
/* Soup - a liquid rail allocator.
*/
# define u2_soup_free_no 28
typedef struct {
u2_ray fre_r[u2_soup_free_no]; // doubly-linked free lists
u2_cash_slot lot_s; // modern memo cache
#ifdef U2_PROFILE_MEMORY
c3_w liv_w; // number of words live
#endif
} u2_loom_soup;
# define u2_soup_fre_r(sop_r, x) *u2_at(sop_r, u2_loom_soup, fre_r[x])
# define u2_soup_lot_r(sop_r) u2_aftr(sop_r, u2_loom_soup, lot_s)
# define u2_soup_liv_w(sop_r) *u2_at(sop_r, u2_loom_soup, liv_w)
/* A noun box, for liquid hats. Behind pointer, addressed fwd.
**
** The box size is also stored at the end of the box in classic
** bad ass malloc style. Hence a box is:
**
** ---
** siz_w
** use_w
** user data
** siz_w
** ---
**
** Do not attempt to adjust this structure!
*/
typedef struct _u2_loom_rail_box {
c3_w siz_w; // size of this box
c3_w use_w; // reference count; free if 0
#ifdef U2_LEAK_DEBUG
c3_w cod_w; // allocation code
#endif
} u2_loom_rail_box;
# define u2_rail_box_siz(box) *u2_at(box, u2_loom_rail_box, siz_w)
# define u2_rail_box_use(box) *u2_at(box, u2_loom_rail_box, use_w)
# define u2_rail_box_cod(box) *u2_at(box, u2_loom_rail_box, cod_w)
/* A free node. Addressed from the box.
*/
typedef struct _u2_loom_rail_hut {
u2_loom_rail_box b;
u2_ray pre_r; // next on free list
u2_ray nex_r; // next on free list
} u2_loom_rail_hut;
# define u2_rail_hut_siz(hut) *u2_at(hut, u2_loom_rail_hut, b.siz_w)
# define u2_rail_hut_use(hut) *u2_at(hut, u2_loom_rail_hut, b.use_w)
# define u2_rail_hut_pre(hut) *u2_at(hut, u2_loom_rail_hut, pre_r)
# define u2_rail_hut_nex(hut) *u2_at(hut, u2_loom_rail_hut, nex_r)
# define u2_rail_box(som) \
( u2_fly_is_cat(som) \
? 0 \
: (u2_dog_a(som) - c3_wiseof(u2_loom_rail_box)) )
/** Abbreviations.
**/
# define u2_rc(ral_r, a, b) u2_rl_cell(ral_r, a, b)
# define u2_rt(ral_r, a, b, c) u2_rl_trel(ral_r, a, b, c)
# define u2_rq(ral_r, a, b, c, d) u2_rl_qual(ral_r, a, b, c, d)
# define u2_ri(ral_r, a, b, c, d, e) u2_rl_quil(ral_r, a, b, c, d, e)
# define u2_ro(ral_r, a) u2_rl_lone(ral_r, a)
# define u2_ru(ral_r, a) u2_rl_unit(ral_r, a)
# define u2_rx(ral_r, a) u2_rl_take(ral_r, a)
# define u2_rz(ral_r, a) u2_rl_lose(ral_r, a)
# define u2_rl u2_rl_list
# define u2_rk u2_rl_rack
/** Functions.
**/
/** Miscellaneous and interesting.
**/
/* u2_rl_boot():
**
** Create an empty rail in an empty loom, with memory model `hip`.
** See u2_rl_leap() for storage policies.
*/
u2_ray
u2_rl_boot(c3_m hip_m);
/* u2_rl_clear():
**
** Yes iff [lef] does not point to any word >= [net]
** and < [bat].
*/
u2_bean
u2_rl_clear(u2_noun lef,
u2_ray net_r,
u2_ray bat_r);
/* u2_rl_init():
**
** Install an empty rail within `hat_r` and `mat_r` in the loom,
** with memory model `hip`.
**
** Returns ray to rail, which always equalls the passed `mat_r`.
*/
u2_ray
u2_rl_init(c3_m hip_m,
u2_ray hat_r,
u2_ray mat_r);
/* u2_rl_dump():
**
** Print memory structure for benefit of archeologists.
*/
void
u2_rl_dump(u2_ray ral_r);
/* u2_rl_drain():
**
** Clear the memo cache (soup).
*/
void
u2_rl_drain(u2_ray ral_r);
/* u2_rl_fall():
**
** Reverse the beams backward, restoring the old frame.
*/
void
u2_rl_fall(u2_ray ral_r);
/* u2_rl_fall_part():
**
** Fall on `ral`, also releasing the partition `aux`.
*/
void
u2_rl_fall_part(u2_ray ral_r,
u2_ray aux_r);
/* u2_rl_flog():
**
** Release the can, setting cap to mat.
*/
void
u2_rl_flog(u2_ray ral_r);
/* u2_rl_gain():
**
** Gain a reference to `som`, returning it.
*/
u2_weak // transfer
u2_rl_gain(u2_ray ral_r,
u2_weak som); // retain
/* u2_rl_free():
**
** Free storage allocated by u2_rl_malloc().
*/
void
u2_rl_free(u2_ray ral_r,
void* lag_v);
/* u2_rl_ok():
**
** Ensure that all reference counts are valid in `som`.
*/
void
u2_rl_ok(u2_ray ral_r,
u2_noun som); // retain
/* u2_rl_junior():
**
** Yes iff `dus` is junior in `ral` - ie, must be copied
** to be referenced on the hat.
*/
u2_bean
u2_rl_junior(u2_ray ral_r,
u2_noun dus); // retain
/* u2_rl_leap():
**
** Reverse the beams forward, with memory model `hip`.
** Memory models at present:
**
** c3__sand solid, no boxes or reference counts
** c3__rock liquid, boxes, reference-counted heap
**
** Returns u2_yes on success.
*/
u2_bean
u2_rl_leap(u2_ray ral_r,
c3_m hip_m);
/* u2_rl_leap_part():
**
** Reverse and split rail, inserting partition of size `num/dem`
** plus `tip`.
**
** Returns partition rail, `aux_r`.
*/
u2_ray
u2_rl_leap_part(u2_ray ral_r,
c3_m hop_m,
c3_w num_w,
c3_w dem_w,
c3_w tip_w);
/* u2_rl_lose():
**
** Lose a reference to `som`. Free it if refcount == 0.
*/
void
u2_rl_lose(u2_ray ral_r,
u2_weak som); // transfer
/* u2_rl_gc_mark_noun():
**
** Mark a noun for gc. Return allocated words.
*/
c3_w
u2_rl_gc_mark_noun(u2_ray ral_r,
u2_noun som);
/* u2_rl_gc_mark_ptr():
**
** Mark a pointer allocated with ralloc. Return allocated words.
*/
c3_w
u2_rl_gc_mark_ptr(u2_ray ral_r,
u2_ray ptr_r);
/* u2_rl_gc_mark():
**
** Mark a rail (mainly memo cache). Return allocated words.
*/
c3_w
u2_rl_gc_mark(u2_ray ral_r);
/* u2_rl_gc_sweep():
**
** Sweep memory, freeing unused blocks. Match live, save leaked.
*/
c3_w
u2_rl_gc_sweep(u2_ray ral_r, c3_w sav_w);
/* u2_rl_malloc():
**
** Allocate `sib_w` *bytes* of raw C storage.
*/
void*
u2_rl_malloc(u2_ray ral_r,
c3_w sib_w);
/* u2_rl_malt():
**
** Initialize slab `sal` as an atom, internally measured.
*/
u2_atom // transfer
u2_rl_malt(u2_rail ral_r,
u2_ray sal_r);
/* u2_rl_mint():
**
** Initialize slab `sal` as an atom, externally measured.
*/
u2_atom // transfer
u2_rl_mint(u2_rail ral_r,
u2_ray sal_r,
c3_w len_w);
/* u2_rl_moot():
**
** Initialize slab `sal` as an atom, originally measured.
*/
u2_atom // transfer
u2_rl_moot(u2_rail ral_r,
u2_ray sal_r);
/* u2_rl_open():
**
** Yes iff [a] more words remain in the pad.
*/
u2_bean
u2_rl_open(u2_ray ral_r,
c3_w a_w);
/* u2_rl_ralloc():
**
** Allocate `siz_w` words of raw ray storage.
*/
u2_ray
u2_rl_ralloc(u2_ray ral_r,
c3_w siz_w);
/* u2_rl_rfree():
**
** Free raw ray storage allocated by `u2_rl_ralloc()`.
*/
void
u2_rl_rfree(u2_ray ral_r,
u2_ray nov_r);
/* u2_rl_senior():
**
** Yes iff `dus` is senior in `ral` - ie, does not
** require reference counting.
*/
u2_bean
u2_rl_senior(u2_ray ral_r,
u2_noun dus); // retain
/* u2_rl_slab():
**
** Create a blank atomic slab of `len` words.
*/
u2_ray
u2_rl_slab(u2_rail ral_r,
c3_w len_w);
/* u2_rl_slaq():
**
** Create a blank atomic slab of `len` bloqs of size `met`.
*/
u2_ray
u2_rl_slaq(u2_wire wir_r,
c3_g met_g,
c3_w len_w);
/* u2_rl_refs():
**
** Return the reference count of (som). For debugging, etc.
*/
c3_w
u2_rl_refs(u2_ray ral_r,
u2_noun som);
/* u2_rl_copy():
**
** Copy indirect noun `fiz` into main storage, preserving dags.
** Must be followed by `rl_wash(fiz)` if `fiz` is to be preserved.
*/
u2_weak // transfer
u2_rl_copy(u2_ray ral_r,
u2_dog fiz); // retain
/* u2_rl_take():
**
** Produce `a`, as eligible result. Copy juniors; reference peers.
*/
u2_weak // transfer
u2_rl_take(u2_ray ral_r,
u2_weak a); // retain
# define u2_rl_ice(ral_r, a) \
u2_rl_take(ral_r, a)
/* u2_rl_tamp():
**
** Tamp, eliding the segment from `net` up to `bat`,
** preserving the root `lef`.
**
** Assumes u2_rl_clear() with the same arguments.
*/
u2_noun
u2_rl_tamp(u2_ray ral_r,
u2_noun lef,
u2_ray net_r,
u2_ray bat_r);
/* u2_rl_valid():
**
** Validate rail for memory bugs.
*/
void
u2_rl_valid(u2_ray ral_r);
/* u2_rl_water():
**
** Return east and west watermarks, respectively.
*/
void
u2_rl_water(u2_ray ral_r,
c3_w* maz_w,
c3_w* buc_w);
/** Basic noun fabrication.
**/
/* u2_rl_bytes():
**
** Copy `a` bytes from `b` to an LSB first atom.
*/
u2_weak // transfer
u2_rl_bytes(u2_ray ral_r,
c3_w a_w,
const c3_y* b_y);
/* u2_rl_cell():
**
** Produce the cell `[a b]`.
*/
u2_weak // transfer
u2_rl_cell(u2_ray ral_r,
u2_weak a, // transfer
u2_weak b); // transfer
/* u2_rl_list():
**
** Produce a null-terminated list, terminating `...` with `u2_none`.
*/
u2_weak // transfer
u2_rl_list(u2_rail ral_r,
...); // transfer
/* u2_rl_lone():
**
** Create the unit `[0 a]`.
*/
#if 0
u2_weak // transfer
u2_rl_lone(u2_rail ral_r,
u2_weak a); // transfer
#else
# define u2_rl_lone(ral_r, a) \
u2_rc(ral_r, a, u2_nul)
#endif
/* u2_rl_molt():
**
** Mutate `som` with a 0-terminated list of axis, noun pairs.
** Axes must be cats (31 bit).
*/
u2_weak // transfer
u2_rl_molt(u2_rail ral_r,
u2_weak som, // retain
...); // transfer
/* u2_rl_molv():
**
** As u2_rl_molt(), by argument pointer.
*/
u2_weak // transfer
u2_rl_molv(u2_rail ral_r,
u2_weak som, // retain
va_list vap); // transfer
/* u2_rl_mp():
**
** Copy the GMP integer [a] into an atom.
*/
u2_weak // transfer
u2_rl_mp(u2_ray ral_r,
mpz_t a_mp); // transfer
/* u2_rl_qual():
**
** Produce the triple `[a b c d]`.
*/
#if 0
u2_weak // transfer
u2_rl_qual(u2_rail ral_r,
u2_weak a, // transfer
u2_weak b, // transfer
u2_weak c, // transfer
u2_weak d); // transfer
#else
# define u2_rl_qual(ral_r, a, b, c, d) \
u2_rc(ral_r, a, u2_rt(ral_r, b, c, d))
#endif
/* u2_rl_rack():
**
** Produce an n-tuple, terminating `...` with `u2_none`.
*/
u2_weak // transfer
u2_rl_rack(u2_rail ral_r,
...); // transfer
/* u2_rl_string():
**
** Produce an LSB-first atom from the C string `a`.
*/
u2_weak // transfer
u2_rl_string(u2_ray ral_r,
const c3_c* a_c);
/* u2_rl_trel():
**
** Create the triple `[a b c]`.
*/
#if 0
u2_weak // transfer
u2_rl_trel(u2_rail ral_r,
u2_weak a, // transfer
u2_weak b, // transfer
u2_weak c); // transfer
#else
# define u2_rl_trel(ral_r, a, b, c) \
u2_rc(ral_r, a, u2_rc(ral_r, b, c))
#endif
/* u2_rl_unit():
**
** Create the unit `[0 a]`.
*/
#if 0
u2_weak // transfer
u2_rl_unit(u2_rail ral_r,
u2_weak a); // transfer
#else
# define u2_rl_unit(ral_r, a) \
u2_rc(ral_r, u2_nul, a)
#endif
/* u2_rl_vint():
**
** Create `a + 1`.
*/
u2_weak // transfer
u2_rl_vint(u2_rail ral_r,
u2_weak a); // transfer
/* u2_rl_words():
**
** Copy [a] words from [b] into an atom.
*/
u2_weak // transfer
u2_rl_words(u2_ray ral_r,
c3_w a_w,
const c3_w* b_w);
/** Caching.
**/
/* u2_rl_find():
**
** Cache search for function (0 means nock) and sample.
*/
u2_weak // transfer
u2_rl_find(u2_ray ral_r,
u2_mote fun_m,
u2_noun sam); // retain
/* u2_rl_save():
**
** Cache store for function (0 means nock), sample and product.
*/
u2_weak // transfer
u2_rl_save(u2_ray ral_r,
u2_mote fun_m, // retain
u2_noun sam, // retain
u2_noun pro); // transfer
/* u2_rl_uniq():
**
** Use cache to render object unique.
*/
u2_noun // produce
u2_rl_uniq(u2_ray ral_r,
u2_noun som); // submit
/* u2_rl_find_cell(): as u2_rl_find(), for `sam=[a b]`.
** u2_rl_find_trel(): as u2_rl_find(), for `sam=[a b c]`.
** u2_rl_find_qual(): as u2_rl_find(), for `sam=[a b d]`.
** u2_rl_find_quil(): as u2_rl_find(), for `sam=[a b c d e]`.
**
** Extend as needed...
*/
u2_weak // transfer
u2_rl_find_cell(u2_ray, u2_mote, u2_noun, // retain
u2_noun); // retain
u2_weak // transfer
u2_rl_find_trel(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun); // retain
u2_weak // transfer
u2_rl_find_qual(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun); // retain
u2_weak // transfer
u2_rl_find_quil(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun); // retain
/* u2_rl_save_cell(): as u2_rl_save(), for `sam=[a b]`.
** u2_rl_save_trel(): as u2_rl_save(), for `sam=[a b c]`.
** u2_rl_save_qual(): as u2_rl_save(), for `sam=[a b c d]`.
** u2_rl_save_quil(): as u2_rl_save(), for `sam=[a b c d e]`.
**
** Extended
*/
u2_weak // transfer
u2_rl_save_cell(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun); // transfer
u2_weak // transfer
u2_rl_save_trel(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun); // transfer
u2_weak // transfer
u2_rl_save_qual(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun); // transfer
u2_weak // transfer
u2_rl_save_quil(u2_ray, u2_mote, u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun, // retain
u2_noun); // transfer