mirror of
https://github.com/urbit/shrub.git
synced 2024-12-17 07:14:52 +03:00
674 lines
23 KiB
C
674 lines
23 KiB
C
/* 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
|