mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-25 07:52:59 +03:00
Update some jet stuff, and docs
This commit is contained in:
parent
ec15c99566
commit
bdebf8f657
113
Spec/u3.md
113
Spec/u3.md
@ -93,8 +93,9 @@ modularize the definitions. Keep them alphabetical, though.
|
||||
### c3: variables and variable naming
|
||||
|
||||
The C3 style uses Hoon style TLV variable names, with a quasi
|
||||
Hungarian syntax. This is weird, but works really well, as
|
||||
long as what you're doing isn't hideous.
|
||||
Hungarian syntax. This is weird, but works really well, as long
|
||||
as what you're doing isn't hideously complicated. (Then it works
|
||||
badly, but we shouldn't need anything hideous in u3.)
|
||||
|
||||
A TLV variable name is a random pronounceable three-letter
|
||||
string, sometimes with some vague relationship to its meaning,
|
||||
@ -295,7 +296,7 @@ nouns, which is obviously what most functions do.
|
||||
|
||||
In general, though, in most places it's not worth thinking about
|
||||
what your function does. There is a convention for it, which
|
||||
depends on where it is, not what it is. Follow the convention.
|
||||
depends on where it is, not what it does. Follow the convention.
|
||||
|
||||
### u3: reference conventions
|
||||
|
||||
@ -653,7 +654,9 @@ debugging printfs: `u3m_pretty()`, `u3m_p()`, `u3m_tape()` and
|
||||
|
||||
It's sometimes nice to run a mark-and-sweep garbage collector,
|
||||
`u3m_grab()`, which collects the world from a list of roots,
|
||||
and asserts if it finds any leaks or incorrect refcounts.
|
||||
and asserts if it finds any leaks or incorrect refcounts. This
|
||||
tool is for debugging and long-term maintenance only; refcounts
|
||||
should never err.
|
||||
|
||||
### u3j: jets
|
||||
|
||||
@ -662,9 +665,9 @@ a useful computing environment. Except perhaps `u3a` (there is
|
||||
really no such thing as a trivial allocator, though `u3a` is
|
||||
dumber than most) - `u3j` is the most interesting code in `u3`.
|
||||
|
||||
Let's consider the minor miracle of jet binding which lets `u3j`
|
||||
work - and decrement not be `O(n)` - without violating the
|
||||
precisely defined semantics of pure Nock, *ever*.
|
||||
Let's consider the minor miracle of driver-to-battery binding
|
||||
which lets `u3j` work - and decrement not be `O(n)` - without
|
||||
violating the precisely defined semantics of pure Nock, *ever*.
|
||||
|
||||
It's easy to assume that jets represent an architectural coupling
|
||||
between Hoon language semantics and Nock interpreter internals.
|
||||
@ -682,7 +685,29 @@ itself.
|
||||
Except for the arbitrary decision to make a core `[code data]`,
|
||||
(or as we sometimes say, `[battery payload]`), instead of `[data
|
||||
code]`, any high-level language transforming itself to Nock would
|
||||
use this design. So jets are in fact fully general.
|
||||
use this design.
|
||||
|
||||
So jets are in fact fully general. Broadly speaking, the jet
|
||||
system works by matching a C *driver* to a battery. When the
|
||||
battery is invoked with Nock operator `9`, it must be found in
|
||||
associative memory and linked to its driver. Then we link the
|
||||
formula axis of the operation (`a` in `[9 a b]`) to a specific
|
||||
function in the driver.
|
||||
|
||||
To validate this jet binding, we need to know two things. One,
|
||||
we need to know the C function actually is a perfect semantic
|
||||
match for the Nock formula. This can be developed with driver
|
||||
test flags, which work, and locked down with a secure formula
|
||||
hash in the driver, which we haven't bothered with just yet.
|
||||
(You could also try to develop a formal method for verifying
|
||||
that C functions and Nock formulas are equivalent, but this is
|
||||
a research problem for the future.)
|
||||
|
||||
Two, we need to validate that the payload is appropriate for the
|
||||
battery. We should note that jets are a Nock feature and have no
|
||||
reference to Hoon. A driver which relies on the Hoon type system
|
||||
to only pair it with valid payloads is a broken driver, and
|
||||
breaks the Nock compliance of the system as a whole. So don't.
|
||||
|
||||
Now, a casual observer might look at `[battery payload]` and
|
||||
expect the simplest case of it to be `[formula subject]`. That
|
||||
@ -764,7 +789,7 @@ numbering itself on process initialization. This structure -
|
||||
which embeds function pointers to all the jets - is defined
|
||||
in `j/tree.c`. The data structures:
|
||||
|
||||
/* u3j_harm: jet arm.
|
||||
/* u3j_harm: driver arm.
|
||||
*/
|
||||
typedef struct _u3j_harm {
|
||||
c3_c* fcs_c; // `.axe` or name
|
||||
@ -774,7 +799,7 @@ in `j/tree.c`. The data structures:
|
||||
c3_o liv; // live (enabled)
|
||||
} u3j_harm;
|
||||
|
||||
/* u3j_core: driver definition.
|
||||
/* u3j_core: C core driver.
|
||||
*/
|
||||
typedef struct _u3j_core {
|
||||
c3_c* cos_c; // control string
|
||||
@ -788,9 +813,9 @@ in `j/tree.c`. The data structures:
|
||||
*/
|
||||
typedef struct _u3e_dash {
|
||||
u3j_core* dev_u; // null-terminated static list
|
||||
c3_l len_l; // dynamic array length
|
||||
c3_l all_l; // allocated length
|
||||
u3j_core* ray_u; // dynamic array by axis
|
||||
c3_l len_l; // ray_u filled length
|
||||
c3_l all_l; // ray_u allocated length
|
||||
u3j_core* ray_u; // dynamic driver array
|
||||
} u3j_dash;
|
||||
|
||||
Warm and cold state is *per road*. In other words, as we nest
|
||||
@ -805,12 +830,13 @@ In case you understand Hoon, `das` (cold state) is a `++dash`,
|
||||
and `har_p` (warm state) is a map from battery to `++calx`:
|
||||
|
||||
++ bane ,@tas :: battery name
|
||||
++ bash ,@uvH :: ctx identity hash
|
||||
++ bash ,@uvH :: label hash
|
||||
++ bosh ,@uvH :: local battery hash
|
||||
++ batt ,* :: battery
|
||||
++ calf ::
|
||||
$: jax=,@ud :: hot core index
|
||||
hap=(map ,@ud ,@ud) :: axis/hot arm index
|
||||
lab=path :: label as path
|
||||
jit=* :: arbitrary data
|
||||
== ::
|
||||
++ calx (trel calf (pair bash cope) club) :: cached by battery
|
||||
@ -821,7 +847,7 @@ and `har_p` (warm state) is a map from battery to `++calx`:
|
||||
++ corp (each core batt) :: parent or static
|
||||
++ dash (map bash clog) :: jet system
|
||||
|
||||
The jet index `jax` in a `++calx` is an index into `ray_u` in the
|
||||
The driver index `jax` in a `++calx` is an index into `ray_u` in the
|
||||
dashboard - ie, a pointer into hot state. This is why the warm
|
||||
state has to be reset when we reload the pier in a new process.
|
||||
|
||||
@ -897,9 +923,22 @@ instance, if the core is a Hoon gate - a function - we will call
|
||||
### u3j: the cold jet dashboard
|
||||
|
||||
For even more fun, the jet tree is not actually a tree of
|
||||
batteries. Rather, *multiple batteries* may share any location
|
||||
in the jet tree. For instance, it's normal to have two
|
||||
equivalent Nock batteries at the same time in one pier: one
|
||||
batteries. It's a tree of battery *labels*, where a label is
|
||||
an [axis term] path from the root of the tree. (At the root,
|
||||
if the core pattern is always followed properly, is a core whose
|
||||
payload is an atomic constant, conventionally the Hoon version.)
|
||||
|
||||
Under each of these labels, it's normal to have an arbitrary
|
||||
number of different Nock batteries (not just multiple copies
|
||||
of the same noun, a situation we *do* strive to avoid). For
|
||||
instance, one might be compiled with debugging hints, one not.
|
||||
|
||||
We might even have changed the semantics of the battery without
|
||||
changing the label - so long as those semantics don't invalidate
|
||||
any attached driver.
|
||||
|
||||
et tree. For instance, it's normal to have
|
||||
two equivalent Nock batteries at the same time in one pier: one
|
||||
battery compiled with debugging hints, one not.
|
||||
|
||||
Rather, the jet tree is a semantic hierarchy. The root of the
|
||||
@ -981,11 +1020,12 @@ from battery to `++calx`.
|
||||
A `calx` is a triple of a `++calf`, a `[bash cope]` cell, and a
|
||||
`club`. The latter two are all straight from cold state.
|
||||
|
||||
The `calf` contains data dependent on hot state. It's a triple
|
||||
of `jax`, the hot jet index (in `ray_u` in `u3j_dash`); `hap`, a
|
||||
table from arm axis (ie, the axis of each formula within the
|
||||
battery) to jet arm index (into `arm_u` in `u3j_core`); and
|
||||
`jit`, any other dynamic data that may speed up execution.
|
||||
The `calf` contains warm data dependent on hot state. It's a
|
||||
quadruple: of `jax`, the hot driver index (in `ray_u` in
|
||||
`u3j_dash`); `hap`, a table from arm axis (ie, the axis of each
|
||||
formula within the battery) to driver arm index (into `arm_u` in
|
||||
`u3j_core`); `lab`, the complete label path; and `jit`, any
|
||||
other dynamic data that may speed up execution.
|
||||
|
||||
We construct `hap`, when we create the calx, by iterating through
|
||||
the arms registered in the `u3j_core`. Note the way a `u3j_harm`
|
||||
@ -999,8 +1039,8 @@ an `fcs_c` with a named arm, it's sufficient to make sure the
|
||||
name is bound to a formula `[0 axis]` in the hook table.
|
||||
|
||||
`jit`, as its name suggests, is a stub where any sort of
|
||||
optimization data computed on jet registration might go.
|
||||
To use it, fill in the `_cj_jit()` function.
|
||||
optimization data computed on battery registration might go. To
|
||||
use it, fill in the `_cj_jit()` function.
|
||||
|
||||
### u3j: the hot dashboard
|
||||
|
||||
@ -1012,21 +1052,22 @@ will try to execute them.
|
||||
Because nouns with a reference count of 1 are precious,
|
||||
`u3j_kick()` has a tricky reference control definition. It
|
||||
reserves the right to return `u3_none` in the case where there is
|
||||
no jet, or the jet does not apply for this case; in this case, it
|
||||
does not consume its argument `cor`. Otherwise, it does.
|
||||
no driver, or the driver does not apply for this case; in this
|
||||
case, it retains argument `cor`. If it succeeds, though, it
|
||||
transfers `cor`.
|
||||
|
||||
`u3j_kick()` searches for the battery (always the head of the
|
||||
core, of course) in the hot dashboard. If the battery is
|
||||
registered, it searches for the axis in `hap` in the `calx`.
|
||||
If it exists, the core has a driver and the driver has a jet for
|
||||
this arm, which we can try to call. If not, we return `u3_none`.
|
||||
If it exists, the core matches a driver and the driver jets this
|
||||
arm. If not, we return `u3_none`.
|
||||
|
||||
Otherwise, we call `fun_f` in our `u3j_harm`. This obeys the
|
||||
same protocol as `u3j_kick()`; it can refuse to function by
|
||||
returning `u3_none`, or consume the noun.
|
||||
|
||||
Besides the actual function pointer `fun_f`, we have some flags
|
||||
in the `u3j_harm` which tell us how to call the jet.
|
||||
in the `u3j_harm` which tell us how to call the arm function.
|
||||
|
||||
If `ice` is yes (`&`, `0`), the jet is known to be perfect and we
|
||||
can just trust the product of `fun_f`. Otherwise, we need to run
|
||||
@ -1039,13 +1080,13 @@ When auto-testing jets in this way, the principle is that the
|
||||
test is on the outermost layer of recursion.)
|
||||
|
||||
(Note also that anyone who multi-threads this execution
|
||||
environment has a slight locking problem with these flags if jet
|
||||
environment has a slight locking problem with these flags if arm
|
||||
testing is multi-threaded.)
|
||||
|
||||
If `tot` is yes, (`&`, `0`), the jet is *total* and has to return
|
||||
properly (though it can still return *u3_none*). Otherwise, it
|
||||
is *partial* and can `u3_cm_bail()` out with c3__punt. This
|
||||
feature has a cost: the jet runs in a subroad.
|
||||
If `tot` is yes, (`&`, `0`), the arm function is *total* and has
|
||||
to return properly (though it can still return *u3_none*).
|
||||
Otherwise, it is *partial* and can `u3_cm_bail()` out with
|
||||
c3__punt. This feature has a cost: the jet runs in a subroad.
|
||||
|
||||
Finally, if `liv` is no (`|`, 1), the jet is off and doesn't run.
|
||||
|
||||
@ -1061,7 +1102,7 @@ then appears ready for action.
|
||||
|
||||
### u3j: jet functions
|
||||
|
||||
At present, all jets are compiled statically into `u3`. This is
|
||||
At present, all drivers are compiled statically into `u3`. This is
|
||||
not a long-term permanent solution or anything. However, it will
|
||||
always be the case with a certain amount of core functionality.
|
||||
|
||||
|
7
i/n/j.h
7
i/n/j.h
@ -6,16 +6,17 @@
|
||||
**/
|
||||
#if 0
|
||||
++ bane ,@tas :: battery name
|
||||
++ bash ,@uvH :: ctx identity hash
|
||||
++ bosh ,@uvH :: local battery hash
|
||||
++ bash ,@uvH :: label hash
|
||||
++ bosh ,@uvH :: battery hash
|
||||
++ batt ,* :: battery
|
||||
++ calf ::
|
||||
$: jax=,@ud :: hot core index
|
||||
hap=(map ,@ud ,@ud) :: axis/hot arm index
|
||||
lab=path :: label as path
|
||||
jit=* :: arbitrary data
|
||||
== ::
|
||||
++ calx (trel calf (pair bash cope) club) :: cached by battery
|
||||
++ clog (pair cope (map batt club)) :: identity record
|
||||
++ clog (pair cope (map batt club)) :: label record
|
||||
++ club (pair corp (map term nock)) :: battery pattern
|
||||
++ cope (trel bane axis (each bash noun)) :: core pattern
|
||||
++ core ,*
|
||||
|
83
i/n/o.h
Normal file
83
i/n/o.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* i/n/o.h
|
||||
**
|
||||
** This file is in the public domain.
|
||||
*/
|
||||
/** Data structures.
|
||||
**/
|
||||
/* u3o_config: process / system configuration.
|
||||
*/
|
||||
|
||||
/* u3e_line: control line.
|
||||
*/
|
||||
typedef struct _u3e_line {
|
||||
c3_w pag_w;
|
||||
c3_w mug_w;
|
||||
} u3e_line;
|
||||
|
||||
/* u3e_control: memory change, control file.
|
||||
*/
|
||||
typedef struct _u3e_control {
|
||||
c3_d evt_d; // event number
|
||||
c3_w nor_w; // new page count north
|
||||
c3_w sou_w; // new page count south
|
||||
c3_w pgs_w; // number of changed pages
|
||||
u3e_line mem_u[0]; // per page
|
||||
} u3e_control;
|
||||
|
||||
/* u3_cs_patch: memory change, top level.
|
||||
*/
|
||||
typedef struct _u3_cs_patch {
|
||||
c3_i ctl_i;
|
||||
c3_i mem_i;
|
||||
u3e_control* con_u;
|
||||
} u3_ce_patch;
|
||||
|
||||
/* u3e_image: memory segment, open file.
|
||||
*/
|
||||
typedef struct _u3e_image {
|
||||
c3_c* nam_c; // segment name
|
||||
c3_i fid_i; // open file, or 0
|
||||
c3_w pgs_w; // length in pages
|
||||
} u3e_image;
|
||||
|
||||
/* u3e_pool: entire memory system.
|
||||
*/
|
||||
typedef struct _u3e_pool {
|
||||
c3_c* dir_c; // path to
|
||||
c3_d evt_d; // last patch written at event
|
||||
c3_w dit_w[u3a_pages >> 5]; // touched since last save
|
||||
u3e_image nor_u; // north segment
|
||||
u3e_image sou_u; // south segment
|
||||
} u3e_pool;
|
||||
|
||||
|
||||
/** Globals.
|
||||
**/
|
||||
/* u3_Pool / u3P: global memory control.
|
||||
*/
|
||||
c3_global u3e_pool u3e_Pool;
|
||||
# define u3P u3e_Pool
|
||||
|
||||
|
||||
/** Functions.
|
||||
**/
|
||||
/* u3e_fault(): handle a memory event with libsigsegv protocol.
|
||||
*/
|
||||
c3_i
|
||||
u3e_fault(void* adr_v, c3_i ser_i);
|
||||
|
||||
/* u3e_save():
|
||||
*/
|
||||
void
|
||||
u3e_save(void);
|
||||
|
||||
/* u3e_live(): start the persistence system. Return c3y if no image.
|
||||
*/
|
||||
c3_o
|
||||
u3e_live(c3_o nuu_o, c3_c* dir_c);
|
||||
|
||||
/* u3e_dirty(): count dirty pages.
|
||||
*/
|
||||
c3_w
|
||||
u3e_dirty(void);
|
||||
|
287
n/j.c
287
n/j.c
@ -305,6 +305,7 @@ _cj_hot_mean(c3_l par_l, u3_noun mop, u3_noun bat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* _cj_hot_mine(): in hoting state, declare a core. RETAINS.
|
||||
*/
|
||||
static c3_l
|
||||
@ -331,144 +332,6 @@ _cj_hot_mine(u3_noun mop, u3_noun cor)
|
||||
}
|
||||
}
|
||||
|
||||
static c3_l _cj_warm_ream_at(u3_noun soh, u3_noun* lab, u3_noun cag);
|
||||
|
||||
/* _cj_warm_ream_be(): install battery; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_be(c3_l jax_l,
|
||||
u3_noun soh,
|
||||
u3_noun lab,
|
||||
u3_noun mop,
|
||||
u3_noun bat,
|
||||
u3_noun cuz)
|
||||
{
|
||||
u3h_put(u3R->jed.har_p,
|
||||
bat,
|
||||
u3nt(u3nq(jax_l,
|
||||
_cj_warm_hump(jax_l, u3t(cuz)),
|
||||
u3k(lab),
|
||||
u3_nul),
|
||||
u3nc(u3k(soh), u3k(mop)),
|
||||
u3k(cuz)));
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_is(): reream battery; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_is(c3_l jax_l,
|
||||
u3_noun soh,
|
||||
u3_noun lab,
|
||||
u3_noun mop,
|
||||
u3_noun sab)
|
||||
{
|
||||
if ( u3_nul != sab ) {
|
||||
u3_noun n_sab, l_sab, r_sab, pn_sab, qn_sab;
|
||||
|
||||
u3x_trel(sab, &n_sab, &l_sab, &r_sab);
|
||||
u3x_cell(n_sab, &pn_sab, &qn_sab);
|
||||
|
||||
_cj_warm_ream_be(jax_l, soh, lab, mop, pn_sab, qn_sab);
|
||||
_cj_warm_ream_is(jax_l, soh, lab, mop, l_sab);
|
||||
_cj_warm_ream_is(jax_l, soh, lab, mop, r_sab);
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_un(): reream under `soh`; RETAINS, transfers `*lab`.
|
||||
*/
|
||||
static c3_l
|
||||
_cj_warm_ream_un(u3_noun soh, u3_noun* lab)
|
||||
{
|
||||
u3_noun cag = u3kdb_got(u3k(u3R->jed.das), u3k(soh));
|
||||
u3_noun sab = u3t(cag);
|
||||
u3_noun cax;
|
||||
c3_l jax_l;
|
||||
|
||||
if ( u3_none != (cax = u3h_get(u3R->jed.har_p, u3h(u3h(sab)))) ) {
|
||||
jax_l = u3h(u3h(cax));
|
||||
*lab = u3k(u3h(u3t(u3t(u3h(cax)))));
|
||||
u3z(cax);
|
||||
}
|
||||
else {
|
||||
jax_l = _cj_warm_ream_at(soh, lab, cag);
|
||||
}
|
||||
u3z(cag);
|
||||
return jax_l;
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_at(): reream at `soh` and `cag`; RETAINS, transfers `*lab`.
|
||||
*/
|
||||
static c3_l
|
||||
_cj_warm_ream_at(u3_noun soh, u3_noun* lab, u3_noun cag)
|
||||
{
|
||||
u3_noun mop = u3h(cag);
|
||||
u3_noun sab = u3t(cag);
|
||||
u3_noun p_mop, q_mop, r_mop, hr_mop, tr_mop;
|
||||
|
||||
u3x_trel(mop, &p_mop, &q_mop, &r_mop);
|
||||
u3x_cell(r_mop, &hr_mop, &tr_mop);
|
||||
{
|
||||
c3_l par_l, jax_l;
|
||||
u3_noun pal = u3_nul;
|
||||
|
||||
if ( c3y == hr_mop ) {
|
||||
par_l = _cj_warm_ream_un(tr_mop, &pal);
|
||||
}
|
||||
else {
|
||||
par_l = 0;
|
||||
pal = u3_nul;
|
||||
}
|
||||
*lab = u3nc(u3k(p_mop), pal);
|
||||
u3m_p("lab", *lab);
|
||||
jax_l = _cj_hot_mean(par_l, mop, 0);
|
||||
|
||||
_cj_warm_ream_is(jax_l, soh, *lab, mop, sab);
|
||||
return jax_l;
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_in(): reream in `taw`; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_in(u3_noun taw)
|
||||
{
|
||||
if ( u3_nul != taw ) {
|
||||
u3_noun n_taw, l_taw, r_taw, pn_taw, qn_taw;
|
||||
u3_noun lab;
|
||||
|
||||
u3x_trel(taw, &n_taw, &l_taw, &r_taw);
|
||||
u3x_cell(n_taw, &pn_taw, &qn_taw);
|
||||
|
||||
_cj_warm_ream_at(pn_taw, &lab, qn_taw);
|
||||
u3z(lab);
|
||||
|
||||
_cj_warm_ream_in(l_taw);
|
||||
_cj_warm_ream_in(r_taw);
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream(): reream warm from cold state.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream(void)
|
||||
{
|
||||
c3_assert(u3R == &(u3H->rod_u));
|
||||
{
|
||||
_cj_warm_ream_in(u3R->jed.das);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3j_ream(): reream after restoring from checkpoint.
|
||||
*/
|
||||
void
|
||||
u3j_ream(void)
|
||||
{
|
||||
u3h_free(u3R->jed.har_p);
|
||||
u3R->jed.har_p = u3h_new();
|
||||
|
||||
_cj_warm_ream();
|
||||
}
|
||||
|
||||
/* u3j_boot(): initialize jet system.
|
||||
*/
|
||||
void
|
||||
@ -799,7 +662,7 @@ u3j_kink(u3_noun cor,
|
||||
/* _cj_jit(): generate arbitrary warm jet-associated data. RETAIN.
|
||||
*/
|
||||
static u3_noun
|
||||
_cj_jit(c3_l jax_l, u3_noun cor)
|
||||
_cj_jit(c3_l jax_l, u3_noun bat)
|
||||
{
|
||||
return u3_nul;
|
||||
}
|
||||
@ -820,10 +683,12 @@ _cj_mine(u3_noun cey, u3_noun cor)
|
||||
u3_noun cup; // ++corp
|
||||
u3_noun soh; // ++bash
|
||||
u3_noun cuz; // ++club
|
||||
u3_noun lab; // ++path
|
||||
|
||||
if ( 0 == q_cey ) {
|
||||
mop = u3nq(u3k(p_cey), 3, c3n, u3k(u3t(cor)));
|
||||
cup = u3nc(c3n, u3k(cor));
|
||||
lab = u3_nul;
|
||||
}
|
||||
else {
|
||||
u3_weak rah = u3r_at(q_cey, cor);
|
||||
@ -854,6 +719,7 @@ _cj_mine(u3_noun cey, u3_noun cor)
|
||||
else {
|
||||
cup = u3nc(c3n, u3k(tab));
|
||||
}
|
||||
lab = u3k(u3h(u3t(u3t(cax))));
|
||||
u3z(cax);
|
||||
}
|
||||
}
|
||||
@ -885,9 +751,10 @@ _cj_mine(u3_noun cey, u3_noun cor)
|
||||
|
||||
u3h_put(u3R->jed.har_p,
|
||||
bat,
|
||||
u3nt(u3nt(jax_l,
|
||||
u3nt(u3nq(jax_l,
|
||||
_cj_warm_hump(jax_l, r_cey),
|
||||
_cj_jit(jax_l, cor)),
|
||||
u3nc(u3k(p_cey), lab),
|
||||
_cj_jit(jax_l, bat)),
|
||||
u3nc(soh, mop),
|
||||
cuz));
|
||||
}
|
||||
@ -1012,3 +879,141 @@ u3j_reap(u3_noun das, u3p(u3h_root) har_p)
|
||||
_cj_cold_reap_in(das);
|
||||
u3h_walk(har_p, _cj_warm_reap);
|
||||
}
|
||||
|
||||
static c3_l _cj_warm_ream_at(u3_noun soh, u3_noun* lab, u3_noun cag);
|
||||
|
||||
/* _cj_warm_ream_be(): install battery; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_be(c3_l jax_l,
|
||||
u3_noun soh,
|
||||
u3_noun lab,
|
||||
u3_noun mop,
|
||||
u3_noun bat,
|
||||
u3_noun cuz)
|
||||
{
|
||||
u3h_put(u3R->jed.har_p,
|
||||
bat,
|
||||
u3nt(u3nq(jax_l,
|
||||
_cj_warm_hump(jax_l, u3t(cuz)),
|
||||
u3k(lab),
|
||||
_cj_jit(jax_l, bat)),
|
||||
u3nc(u3k(soh), u3k(mop)),
|
||||
u3k(cuz)));
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_is(): reream battery; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_is(c3_l jax_l,
|
||||
u3_noun soh,
|
||||
u3_noun lab,
|
||||
u3_noun mop,
|
||||
u3_noun sab)
|
||||
{
|
||||
if ( u3_nul != sab ) {
|
||||
u3_noun n_sab, l_sab, r_sab, pn_sab, qn_sab;
|
||||
|
||||
u3x_trel(sab, &n_sab, &l_sab, &r_sab);
|
||||
u3x_cell(n_sab, &pn_sab, &qn_sab);
|
||||
|
||||
_cj_warm_ream_be(jax_l, soh, lab, mop, pn_sab, qn_sab);
|
||||
_cj_warm_ream_is(jax_l, soh, lab, mop, l_sab);
|
||||
_cj_warm_ream_is(jax_l, soh, lab, mop, r_sab);
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_un(): reream under `soh`; RETAINS, transfers `*lab`.
|
||||
*/
|
||||
static c3_l
|
||||
_cj_warm_ream_un(u3_noun soh, u3_noun* lab)
|
||||
{
|
||||
u3_noun cag = u3kdb_got(u3k(u3R->jed.das), u3k(soh));
|
||||
u3_noun sab = u3t(cag);
|
||||
u3_noun cax;
|
||||
c3_l jax_l;
|
||||
|
||||
if ( u3_none != (cax = u3h_get(u3R->jed.har_p, u3h(u3h(sab)))) ) {
|
||||
jax_l = u3h(u3h(cax));
|
||||
*lab = u3k(u3h(u3t(u3t(u3h(cax)))));
|
||||
u3z(cax);
|
||||
}
|
||||
else {
|
||||
jax_l = _cj_warm_ream_at(soh, lab, cag);
|
||||
}
|
||||
u3z(cag);
|
||||
return jax_l;
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_at(): reream at `soh` and `cag`; RETAINS, transfers `*lab`.
|
||||
*/
|
||||
static c3_l
|
||||
_cj_warm_ream_at(u3_noun soh, u3_noun* lab, u3_noun cag)
|
||||
{
|
||||
u3_noun mop = u3h(cag);
|
||||
u3_noun sab = u3t(cag);
|
||||
u3_noun p_mop, q_mop, r_mop, hr_mop, tr_mop;
|
||||
|
||||
u3x_trel(mop, &p_mop, &q_mop, &r_mop);
|
||||
u3x_cell(r_mop, &hr_mop, &tr_mop);
|
||||
{
|
||||
c3_l par_l, jax_l;
|
||||
u3_noun pal = u3_nul;
|
||||
|
||||
if ( c3y == hr_mop ) {
|
||||
par_l = _cj_warm_ream_un(tr_mop, &pal);
|
||||
}
|
||||
else {
|
||||
par_l = 0;
|
||||
pal = u3_nul;
|
||||
}
|
||||
*lab = u3nc(u3k(p_mop), pal);
|
||||
jax_l = _cj_hot_mean(par_l, mop, 0);
|
||||
|
||||
_cj_warm_ream_is(jax_l, soh, *lab, mop, sab);
|
||||
return jax_l;
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream_in(): reream in `taw`; RETAINS.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream_in(u3_noun taw)
|
||||
{
|
||||
if ( u3_nul != taw ) {
|
||||
u3_noun n_taw, l_taw, r_taw, pn_taw, qn_taw;
|
||||
u3_noun lab;
|
||||
|
||||
u3x_trel(taw, &n_taw, &l_taw, &r_taw);
|
||||
u3x_cell(n_taw, &pn_taw, &qn_taw);
|
||||
|
||||
_cj_warm_ream_at(pn_taw, &lab, qn_taw);
|
||||
u3z(lab);
|
||||
|
||||
_cj_warm_ream_in(l_taw);
|
||||
_cj_warm_ream_in(r_taw);
|
||||
}
|
||||
}
|
||||
|
||||
/* _cj_warm_ream(): reream warm from cold state.
|
||||
*/
|
||||
static void
|
||||
_cj_warm_ream(void)
|
||||
{
|
||||
c3_assert(u3R == &(u3H->rod_u));
|
||||
{
|
||||
_cj_warm_ream_in(u3R->jed.das);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3j_ream(): reream after restoring from checkpoint.
|
||||
*/
|
||||
void
|
||||
u3j_ream(void)
|
||||
{
|
||||
u3h_free(u3R->jed.har_p);
|
||||
u3R->jed.har_p = u3h_new();
|
||||
|
||||
_cj_warm_ream();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user