mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 04:52:06 +03:00
Various fixes and improvements.
This commit is contained in:
parent
604c65e58e
commit
4f1377a91c
1
Makefile
1
Makefile
@ -78,6 +78,7 @@ CWFLAGS=-Wall
|
||||
|
||||
F_OFILES=\
|
||||
f/rail.o \
|
||||
f/meme.o \
|
||||
f/loom.o \
|
||||
f/wire.o \
|
||||
f/chad.o \
|
||||
|
593
f/meme.c
593
f/meme.c
@ -2,14 +2,7 @@
|
||||
**
|
||||
** This file is in the public domain.
|
||||
*/
|
||||
#include "all.h"
|
||||
#include <sys/uio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sigsegv.h>
|
||||
#include <termios.h>
|
||||
#include <uv.h>
|
||||
#include "v/vere.h"
|
||||
#include "f/meme.h"
|
||||
|
||||
/* _me_boot_north(): install a north road.
|
||||
*/
|
||||
@ -63,49 +56,70 @@ u2_me_boot(void* mem_v, c3_w len_w)
|
||||
u2H = u2R = _me_boot_north(mem_v, len_w);
|
||||
}
|
||||
|
||||
/* _me_road_all_hat(): in u2R, allocate directly on the hat.
|
||||
/* _me_road_all_hat(): in u2R, allocate directly on the hat_w.
|
||||
*/
|
||||
static c3_w*
|
||||
_me_road_all_hat(c3_w len_w)
|
||||
{
|
||||
if ( len_w > u2_me_open ) {
|
||||
return u2_me_bail(c3__meme);
|
||||
u2_me_bail(c3__meme); return 0;
|
||||
}
|
||||
|
||||
if ( u2_yes == u2_me_is_north ) {
|
||||
c3_w* all_w;
|
||||
|
||||
all_w = u2R->hat;
|
||||
u2R->hat += len_w;
|
||||
all_w = u2R->hat_w;
|
||||
u2R->hat_w += len_w;
|
||||
return all_w;
|
||||
}
|
||||
else {
|
||||
u2R->hat -= len_w;
|
||||
return u2R->hat;
|
||||
u2R->hat_w -= len_w;
|
||||
return u2R->hat_w;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // not yet used
|
||||
/* _me_road_all_cap(): in u2R, allocate directly on the cap.
|
||||
*/
|
||||
static c3_w*
|
||||
_me_road_all_hat(c3_w len_w)
|
||||
_me_road_all_cap(c3_w len_w)
|
||||
{
|
||||
if ( len_w > u2_me_open ) {
|
||||
return u2_me_bail(c3__meme);
|
||||
u2_me_bail(c3__meme); return 0;
|
||||
}
|
||||
|
||||
if ( u2_yes == u2_me_is_north ) {
|
||||
u2R->cap -= len_w;
|
||||
return u2R->cap;
|
||||
u2R->cap_w -= len_w;
|
||||
return u2R->cap_w;
|
||||
}
|
||||
else {
|
||||
c3_w* all_w;
|
||||
|
||||
all_w = u2R->cap;
|
||||
u2R->cap += len_w;
|
||||
all_w = u2R->cap_w;
|
||||
u2R->cap_w += len_w;
|
||||
return all_w;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u2_me_bail(): bail out. Does not return.
|
||||
**
|
||||
** Bail motes:
|
||||
**
|
||||
** %evil :: erroneous cryptography
|
||||
** %exit :: semantic failure
|
||||
** %oops :: assertion failure
|
||||
** %intr :: interrupt
|
||||
** %fail :: computability failure
|
||||
** %need :: namespace block
|
||||
** %meme :: out of memory
|
||||
*/
|
||||
c3_i
|
||||
u2_me_bail(c3_m how_m)
|
||||
{
|
||||
_longjmp(u2R->esc.buf, how_m);
|
||||
return how_m;
|
||||
}
|
||||
|
||||
/* u2_me_leap(): in u2R, create a new road within the existing one.
|
||||
*/
|
||||
@ -134,40 +148,40 @@ u2_me_fall()
|
||||
{
|
||||
c3_assert(0 != u2R->par_u);
|
||||
|
||||
u2R->par_u->cap_w = u2R->hat_u;
|
||||
u2R->par_u->cap_w = u2R->hat_w;
|
||||
u2R = u2R->par_u;
|
||||
}
|
||||
|
||||
|
||||
/* u2_me_golf(): record cap length for u2_flog().
|
||||
/* u2_me_golf(): record cap_w length for u2_flog().
|
||||
*/
|
||||
c3_w
|
||||
u2_me_golf(void)
|
||||
{
|
||||
if ( u2_yes == u2_me_is_north ) {
|
||||
return u2R->mat - u2R->cap;
|
||||
return u2R->mat_w - u2R->cap_w;
|
||||
}
|
||||
else {
|
||||
return u2R->cap - u2R->mat;
|
||||
return u2R->cap_w - u2R->mat_w;
|
||||
}
|
||||
}
|
||||
|
||||
/* u2_me_flog(): reset cap.
|
||||
/* u2_me_flog(): reset cap_w.
|
||||
*/
|
||||
void
|
||||
u2_me_flog(c3_w gof_w)
|
||||
{
|
||||
if ( u2_yes == u2_me_is_north ) {
|
||||
u2R->cap = u2R->mat - gof_w;
|
||||
u2R->cap_w = u2R->mat_w - gof_w;
|
||||
} else {
|
||||
u2R->cap = u2R->mat + gof_w;
|
||||
u2R->cap_w = u2R->mat_w + gof_w;
|
||||
}
|
||||
}
|
||||
|
||||
/* u2_me_water(): produce watermarks.
|
||||
*/
|
||||
void
|
||||
u2_me_water(c3_w* low_w, c3_w* hig_w);
|
||||
u2_me_water(c3_w* low_w, c3_w* hig_w)
|
||||
{
|
||||
c3_assert(u2R == u2H);
|
||||
|
||||
@ -187,7 +201,7 @@ _me_box_slot(c3_w siz_w)
|
||||
c3_w i_w = 1;
|
||||
|
||||
while ( 1 ) {
|
||||
if ( i_w == u2_me_free_no ) {
|
||||
if ( i_w == u2_me_fbox_no ) {
|
||||
return (i_w - 1);
|
||||
}
|
||||
if ( siz_w < 16 ) {
|
||||
@ -202,19 +216,19 @@ _me_box_slot(c3_w siz_w)
|
||||
/* _me_box_make(): construct a box.
|
||||
*/
|
||||
u2_me_box*
|
||||
_me_box_make(c3_v* box_v, c3_w siz_w, c3_w use_w)
|
||||
_me_box_make(void* box_v, c3_w siz_w, c3_w use_w)
|
||||
{
|
||||
u2_me_box* box_u = box_v;
|
||||
c3_w* box_w = box_v;
|
||||
|
||||
box_w[0] = siz_w;
|
||||
box_w[siz_w - 1] = siz_w;
|
||||
|
||||
#ifdef U2_MEMORY_DEBUG
|
||||
box_u->cod_w = COD_w;
|
||||
#endif
|
||||
box_u->use_w = use_w;
|
||||
|
||||
# ifdef U2_MEMORY_DEBUG
|
||||
box_u->cod_w = COD_w;
|
||||
# endif
|
||||
|
||||
return box_u;
|
||||
}
|
||||
|
||||
@ -223,11 +237,11 @@ _me_box_make(c3_v* box_v, c3_w siz_w, c3_w use_w)
|
||||
void
|
||||
_me_box_attach(u2_me_box* box_u)
|
||||
{
|
||||
c3_assert(box_u->siz_w >= (1 + c3_wiseof(u2_me_free)));
|
||||
c3_assert(box_u->siz_w >= (1 + c3_wiseof(u2_me_fbox)));
|
||||
{
|
||||
c3_w sel_w = _me_box_slot(box_u->siz_w);
|
||||
u2_me_free* fre_u = (void *)box_u;
|
||||
u2_me_free** pfr_u = &u2R->all.fre_u[sel_w];
|
||||
u2_me_fbox* fre_u = (void *)box_u;
|
||||
u2_me_fbox** pfr_u = &u2R->all.fre_u[sel_w];
|
||||
|
||||
fre_u->pre_u = 0;
|
||||
fre_u->nex_u = (*pfr_u);
|
||||
@ -240,7 +254,7 @@ _me_box_attach(u2_me_box* box_u)
|
||||
void
|
||||
_me_box_detach(u2_me_box* box_u)
|
||||
{
|
||||
u2_me_free* fre_u = (void*) box_u;
|
||||
u2_me_fbox* fre_u = (void*) box_u;
|
||||
|
||||
if ( fre_u->pre_u ) {
|
||||
fre_u->pre_u->nex_u = fre_u->nex_u;
|
||||
@ -252,7 +266,7 @@ _me_box_detach(u2_me_box* box_u)
|
||||
}
|
||||
}
|
||||
|
||||
/* u2_me_walloc(): allocate storage words on hat.
|
||||
/* u2_me_walloc(): allocate storage words on hat_w.
|
||||
*/
|
||||
void*
|
||||
u2_me_walloc(c3_w len_w)
|
||||
@ -262,27 +276,27 @@ u2_me_walloc(c3_w len_w)
|
||||
|
||||
// XX: this logic is totally bizarre, but preserve it.
|
||||
//
|
||||
if ( (sel_w != 0) && (sel_w != u2_me_free_no - 1) ) {
|
||||
if ( (sel_w != 0) && (sel_w != u2_me_fbox_no - 1) ) {
|
||||
sel_w += 1;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
u2_me_free** pfr_u = &u2R->all.fre_u[sel_w];
|
||||
u2_me_fbox** pfr_u = &u2R->all.fre_u[sel_w];
|
||||
|
||||
while ( 1 ) {
|
||||
if ( 0 == *pfr_u ) {
|
||||
if ( sel_w < (u2_me_free_no - 1) ) {
|
||||
if ( sel_w < (u2_me_fbox_no - 1) ) {
|
||||
sel_w += 1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Nothing in top free list. Chip away at the hat.
|
||||
/* Nothing in top free list. Chip away at the hat_w.
|
||||
*/
|
||||
return u2_me_boxto(_me_box_make(_me_road_all_hat(siz_w), siz_w, 1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( siz_w > (*pfr_u)->box_u->siz_w ) {
|
||||
if ( siz_w > (*pfr_u)->box_u.siz_w ) {
|
||||
/* This free block is too small. Continue searching.
|
||||
*/
|
||||
pfr_u = &((*pfr_u)->nex_u);
|
||||
@ -309,10 +323,10 @@ u2_me_walloc(c3_w len_w)
|
||||
|
||||
/* If we can chop off another block, do it.
|
||||
*/
|
||||
if ( (siz_w + c3_wiseof(u2_me_free) + 1) <= box_u->siz_w ) {
|
||||
if ( (siz_w + c3_wiseof(u2_me_fbox) + 1) <= box_u->siz_w ) {
|
||||
/* Split the block.
|
||||
*/
|
||||
c3_w* box_w = ((c3_w *)(void *)box_uy);
|
||||
c3_w* box_w = ((c3_w *)(void *)box_u);
|
||||
c3_w* end_w = box_w + siz_w;
|
||||
c3_w lef_w = (box_u->siz_w - siz_w);
|
||||
|
||||
@ -325,13 +339,13 @@ u2_me_walloc(c3_w len_w)
|
||||
box_u->cod_w = COD_w;
|
||||
#endif
|
||||
return u2_me_boxto(box_u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* u2_me_malloc(): allocate storage measured in bytes.
|
||||
*/
|
||||
void*
|
||||
@ -343,7 +357,7 @@ u2_me_malloc(c3_w len_w)
|
||||
/* u2_me_free(): free storage.
|
||||
*/
|
||||
void
|
||||
u2_me_free(void* tox_v);
|
||||
u2_me_free(void* tox_v)
|
||||
{
|
||||
u2_me_box* box_u = u2_me_botox(tox_v);
|
||||
c3_w* box_w = (c3_w *)(void *)box_u;
|
||||
@ -363,10 +377,7 @@ u2_me_free(void* tox_v);
|
||||
}
|
||||
|
||||
if ( u2_yes == u2_me_is_north ) {
|
||||
c3_w* bot_w = u2R->rut_w;
|
||||
c3_w* top_w = u2R->hat_w;
|
||||
|
||||
/* Try to coalesce with the previous block.
|
||||
/* Try to coalesce with the block below.
|
||||
*/
|
||||
if ( box_w != u2R->rut_w ) {
|
||||
c3_w laz_w = *(box_w - 1);
|
||||
@ -377,124 +388,440 @@ u2_me_free(void* tox_v);
|
||||
_me_box_make(pox_u, (laz_w + box_u->siz_w), 0);
|
||||
|
||||
box_u = pox_u;
|
||||
box_w = (c3_w*)(void *)box_u;
|
||||
box_w = (c3_w*)(void *)pox_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to coalesce with the next block, or the wilderness.
|
||||
/* Try to coalesce with the block above, or the wilderness.
|
||||
*/
|
||||
if ( (box_w + siz_w) == u2R->hat_w ) {
|
||||
if ( (box_w + box_u->siz_w) == u2R->hat_w ) {
|
||||
u2R->hat_w = box_w;
|
||||
}
|
||||
else {
|
||||
u2_me_box* nox_u = (u2_me_box*)(void *)(box_w + box_u->siz_w);
|
||||
|
||||
if ( 0 == nox_u->use_w ) {
|
||||
_me_nox_detach(nox_u);
|
||||
_me_box_make(box_u, (nox_u->siz_w + box_u->siz_w));
|
||||
_me_box_detach(nox_u);
|
||||
_me_box_make(box_u, (box_u->siz_w + nox_u->siz_w), 0);
|
||||
}
|
||||
_me_box_attach(box_u);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (
|
||||
}
|
||||
/* Try to coalesce with the block above.
|
||||
*/
|
||||
if ( (box_w + box_u->siz_w) != u2R->rut_w ) {
|
||||
u2_me_box* nox_u = (u2_me_box*)(void *)(box_w + box_u->siz_w);
|
||||
|
||||
if ( ((c3_w*) tox_v) == u2
|
||||
if ( box_r != beg_r ) {
|
||||
c3_w las_w = *u2_at_ray(box_r - 1);
|
||||
u2_ray tod_r = (box_r - las_w);
|
||||
if ( 0 == nox_u->use_w ) {
|
||||
_me_box_detach(nox_u);
|
||||
_me_box_make(box_u, (box_u->siz_w + nox_u->siz_w), 0);
|
||||
|
||||
if ( 0 == u2_rail_hut_use(tod_r) ) {
|
||||
_rl_bloq_detach(ral_r, tod_r);
|
||||
_rl_bloq_make(ral_r, tod_r, (las_w + u2_rail_hut_siz(box_r)), 0);
|
||||
box_r = tod_r;
|
||||
box_u = nox_u;
|
||||
box_w = (c3_w*)(void *)nox_u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to coalesce with the next block, or with the wilderness.
|
||||
*/
|
||||
{
|
||||
c3_w siz_w = u2_rail_hut_siz(box_r);
|
||||
|
||||
if ( (box_r + siz_w == hat_r) ) {
|
||||
u2_rail_hat_r(ral_r) = box_r;
|
||||
/* Try to coalesce with the block below, or with the wilderness.
|
||||
*/
|
||||
if ( box_w == u2R->hat_w ) {
|
||||
u2R->hat_w = (box_w + box_u->siz_w);
|
||||
}
|
||||
else {
|
||||
u2_ray hob_r = (box_r + siz_w);
|
||||
c3_w laz_w = *(box_w - 1);
|
||||
u2_me_box* pox_u = (u2_me_box*)(void *)(box_w - laz_w);
|
||||
|
||||
if ( 0 == u2_rail_hut_use(hob_r) ) {
|
||||
_rl_bloq_detach(ral_r, hob_r);
|
||||
_rl_bloq_make(ral_r, box_r, (siz_w + u2_rail_hut_siz(hob_r)), 0);
|
||||
if ( 0 == pox_u->use_w ) {
|
||||
_me_box_detach(pox_u);
|
||||
_me_box_make(pox_u, (laz_w + box_u->siz_w), 0);
|
||||
}
|
||||
|
||||
/* Add to the appropriate free list.
|
||||
*/
|
||||
_rl_bloq_attach(ral_r, box_r);
|
||||
_me_box_attach(box_u);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////// Atoms from proto-atoms.
|
||||
|
||||
/* Basic allocation.
|
||||
*/
|
||||
/* u2_me_walloc(): allocate storage measured in words.
|
||||
*/
|
||||
void*
|
||||
u2_me_walloc(c3_w len_w);
|
||||
|
||||
/* u2_me_malloc(): allocate storage measured in bytes.
|
||||
*/
|
||||
void*
|
||||
u2_me_malloc(c3_w len_w);
|
||||
|
||||
/* u2_me_free(): free storage.
|
||||
*/
|
||||
void
|
||||
u2_me_free(void* lag_v);
|
||||
|
||||
|
||||
|
||||
/* u2_me_slab(): create a length-bounded proto-atom.
|
||||
/* _me_north_senior(): yes iff only in the senior region.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slab(c3_w len_w)
|
||||
static u2_bean
|
||||
_me_north_senior(u2_noun dog)
|
||||
{
|
||||
u2_ray nov_r = u2_rl_ralloc(ral_r, (len_w + c3_wiseof(u2_loom_atom)));
|
||||
u2_atom nov = u2_pug_of(nov_r, 0);
|
||||
c3_w* dog_w = u2_me_to_ptr(dog);
|
||||
|
||||
*u2_at_dog_mug(nov) = 0;
|
||||
*u2_at_pug_len(nov) = len_w;
|
||||
return u2_say((dog_w < u2R->rut_w) || (dog_w >= u2R->mat_w));
|
||||
}
|
||||
|
||||
/* Clear teh slab.
|
||||
*/
|
||||
/* _me_north_junior(): yes iff only in the junior section.
|
||||
*/
|
||||
static u2_bean
|
||||
_me_north_junior(u2_noun dog)
|
||||
{
|
||||
c3_w* dog_w = u2_me_to_ptr(dog);
|
||||
|
||||
return u2_say((dog_w >= u2R->cap_w) && (dog_w < u2R->mat_w));
|
||||
}
|
||||
/* _me_north_normal(): yes iff only in the normal heap.
|
||||
*/
|
||||
static u2_bean
|
||||
_me_north_normal(u2_noun dog)
|
||||
{
|
||||
return u2_and(u2_not(_me_north_senior(dog)),
|
||||
u2_not(_me_north_junior(dog)));
|
||||
}
|
||||
|
||||
/* _me_south_senior(): yes iff only in the senior region.
|
||||
*/
|
||||
static u2_bean
|
||||
_me_south_senior(u2_noun dog)
|
||||
{
|
||||
c3_w* dog_w = u2_me_to_ptr(dog);
|
||||
|
||||
return u2_say((dog_w >= u2R->mat_w) || (dog_w < u2R->cap_w));
|
||||
}
|
||||
/* _me_south_junior(): yes iff only in the junior section.
|
||||
*/
|
||||
static u2_bean
|
||||
_me_south_junior(u2_noun dog)
|
||||
{
|
||||
c3_w* dog_w = u2_me_to_ptr(dog);
|
||||
|
||||
return u2_say((dog_w >= u2R->cap_w) && (dog_w < u2R->mat_w));
|
||||
}
|
||||
/* _me_south_normal(): yes iff only in the normal heap.
|
||||
*/
|
||||
static u2_bean
|
||||
_me_south_normal(u2_noun dog)
|
||||
{
|
||||
return u2_and(u2_not(_me_south_senior(dog)),
|
||||
u2_not(_me_south_junior(dog)));
|
||||
}
|
||||
|
||||
/* _me_wash_north(): clean up mug slots after copy.
|
||||
*/
|
||||
static void _me_wash_north(u2_noun dog);
|
||||
static void
|
||||
_me_wash_north_in(u2_noun som)
|
||||
{
|
||||
if ( u2_so(u2_me_is_cat(som)) ) return;
|
||||
if ( u2_ne(_me_north_junior(som)) ) return;
|
||||
|
||||
_me_wash_north(som);
|
||||
}
|
||||
static void
|
||||
_me_wash_north(u2_noun dog)
|
||||
{
|
||||
c3_assert(u2_me_is_dog(dog));
|
||||
c3_assert(u2_yes == _me_north_junior(dog));
|
||||
{
|
||||
c3_w i_w;
|
||||
u2_me_noun* dog_u = u2_me_to_ptr(dog);
|
||||
|
||||
for ( i_w=0; i_w < len_w; i_w++ ) {
|
||||
*u2_at_pug_buf(nov, i_w) = 0;
|
||||
if ( dog_u->mug_w >> 31 ) { dog_u->mug_w = 0; }
|
||||
|
||||
if ( u2_so(u2_me_is_pom(dog)) ) {
|
||||
u2_me_cell* god_u = (u2_me_cell *)(void *)dog_u;
|
||||
|
||||
_me_wash_north_in(god_u->hed);
|
||||
_me_wash_north_in(god_u->tel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_wash_south(): clean up mug slots after copy.
|
||||
*/
|
||||
static void _me_wash_south(u2_noun dog);
|
||||
static void
|
||||
_me_wash_south_in(u2_noun som)
|
||||
{
|
||||
if ( u2_so(u2_me_is_cat(som)) ) return;
|
||||
if ( u2_ne(_me_south_junior(som)) ) return;
|
||||
|
||||
_me_wash_south(som);
|
||||
}
|
||||
static void
|
||||
_me_wash_south(u2_noun dog)
|
||||
{
|
||||
c3_assert(u2_me_is_dog(dog));
|
||||
c3_assert(u2_yes == _me_south_junior(dog));
|
||||
{
|
||||
u2_me_noun* dog_u = u2_me_to_ptr(dog);
|
||||
|
||||
if ( dog_u->mug_w >> 31 ) { dog_u->mug_w = 0; }
|
||||
|
||||
if ( u2_so(u2_me_is_pom(dog)) ) {
|
||||
u2_me_cell* god_u = (u2_me_cell *)(void *)dog_u;
|
||||
|
||||
_me_wash_south_in(god_u->hed);
|
||||
_me_wash_south_in(god_u->tel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_gain_use(): increment use count.
|
||||
*/
|
||||
static void
|
||||
_me_gain_use(u2_noun dog)
|
||||
{
|
||||
c3_w* dog_w = u2_me_to_ptr(dog);
|
||||
u2_me_box* box_u = u2_me_botox(dog_w);
|
||||
|
||||
box_u = u2_me_botox(dog_w);
|
||||
if ( 0xffffffff == box_u->use_w ) {
|
||||
u2_me_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
box_u->use_w += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_copy_north_in(): copy subjuniors on a north road.
|
||||
*/
|
||||
static u2_noun _me_copy_north(u2_noun);
|
||||
static u2_noun
|
||||
_me_copy_north_in(u2_noun som)
|
||||
{
|
||||
c3_assert(u2_none != som);
|
||||
if ( u2_so(u2_me_is_cat(som)) ) {
|
||||
return som;
|
||||
}
|
||||
else {
|
||||
u2_noun dog = som;
|
||||
|
||||
if ( u2_so(_me_north_senior(dog)) ) {
|
||||
return dog;
|
||||
}
|
||||
else if ( u2_so(_me_north_junior(dog)) ) {
|
||||
return _me_copy_north(dog);
|
||||
}
|
||||
else {
|
||||
_me_gain_use(dog);
|
||||
return dog;
|
||||
}
|
||||
}
|
||||
return (nov_r + c3_wiseof(u2_loom_atom));
|
||||
|
||||
/* u2_me_slaq(): u2_me_slaq() with a defined blocksize.
|
||||
}
|
||||
/* _me_copy_north(): copy juniors on a north road.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slaq(c3_g met_g, c3_w len_w);
|
||||
static u2_noun
|
||||
_me_copy_north(u2_noun dog)
|
||||
{
|
||||
c3_assert(u2_yes == _me_north_junior(dog));
|
||||
|
||||
/* u2_me_malt(): measure and finish a proto-atom.
|
||||
if ( u2_ne(_me_north_junior(dog)) ) {
|
||||
if ( u2_ne(_me_north_senior(dog)) ) {
|
||||
_me_gain_use(dog);
|
||||
}
|
||||
return dog;
|
||||
}
|
||||
else {
|
||||
u2_me_noun* dog_u = u2_me_to_ptr(dog);
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
if ( dog_u->mug_w >> 31 ) {
|
||||
u2_noun nov = (u2_noun) dog_u->mug_w;
|
||||
|
||||
c3_assert(u2_so(_me_north_normal(nov)));
|
||||
_me_gain_use(nov);
|
||||
|
||||
return nov;
|
||||
}
|
||||
else {
|
||||
if ( u2_yes == u2_me_is_pom(dog) ) {
|
||||
u2_me_cell* old_u = u2_me_to_ptr(dog);
|
||||
c3_w* new_w = u2_me_walloc(c3_wiseof(u2_me_cell));
|
||||
u2_noun new = u2_me_de_twin(dog, new_w);
|
||||
u2_me_cell* new_u = (u2_me_cell*)(void *)new_w;
|
||||
|
||||
new_u->mug_w = old_u->mug_w;
|
||||
new_u->hed = _me_copy_north_in(old_u->hed);
|
||||
new_u->tel = _me_copy_north_in(old_u->tel);
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
old_u->mug_w = new;
|
||||
return new;
|
||||
}
|
||||
else {
|
||||
u2_me_atom* old_u = u2_me_to_ptr(dog);
|
||||
c3_w* new_w = u2_me_walloc(old_u->len_w + c3_wiseof(u2_me_atom));
|
||||
u2_noun new = u2_me_de_twin(dog, new_w);
|
||||
u2_me_atom* new_u = (u2_me_atom*)(void *)new_w;
|
||||
|
||||
new_u->mug_w = old_u->mug_w;
|
||||
new_u->len_w = old_u->len_w;
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w=0; i_w < old_u->len_w; i_w++ ) {
|
||||
new_u->buf_w[i_w] = old_u->buf_w[i_w];
|
||||
}
|
||||
}
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
old_u->mug_w = new;
|
||||
return new;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_copy_south_in(): copy subjuniors on a south road.
|
||||
*/
|
||||
static u2_noun _me_copy_south(u2_noun);
|
||||
static u2_noun
|
||||
_me_copy_south_in(u2_noun som)
|
||||
{
|
||||
c3_assert(u2_none != som);
|
||||
if ( u2_so(u2_me_is_cat(som)) ) {
|
||||
return som;
|
||||
}
|
||||
else {
|
||||
u2_noun dog = som;
|
||||
|
||||
if ( u2_so(_me_south_senior(dog)) ) {
|
||||
return dog;
|
||||
}
|
||||
else if ( u2_so(_me_south_junior(dog)) ) {
|
||||
return _me_copy_south(dog);
|
||||
}
|
||||
else {
|
||||
_me_gain_use(dog);
|
||||
return dog;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* _me_copy_south(): copy juniors on a south road.
|
||||
*/
|
||||
static u2_noun
|
||||
_me_copy_south(u2_noun dog)
|
||||
{
|
||||
c3_assert(u2_yes == _me_south_junior(dog));
|
||||
|
||||
if ( u2_ne(_me_south_junior(dog)) ) {
|
||||
if ( u2_ne(_me_south_senior(dog)) ) {
|
||||
_me_gain_use(dog);
|
||||
}
|
||||
return dog;
|
||||
}
|
||||
else {
|
||||
u2_me_noun* dog_u = u2_me_to_ptr(dog);
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
if ( dog_u->mug_w >> 31 ) {
|
||||
u2_noun nov = (u2_noun) dog_u->mug_w;
|
||||
|
||||
c3_assert(u2_so(_me_south_normal(nov)));
|
||||
_me_gain_use(nov);
|
||||
|
||||
return nov;
|
||||
}
|
||||
else {
|
||||
if ( u2_yes == u2_me_is_pom(dog) ) {
|
||||
u2_me_cell* old_u = u2_me_to_ptr(dog);
|
||||
c3_w* new_w = u2_me_walloc(c3_wiseof(u2_me_cell));
|
||||
u2_noun new = u2_me_de_twin(dog, new_w);
|
||||
u2_me_cell* new_u = (u2_me_cell*)(void *)new_w;
|
||||
|
||||
new_u->mug_w = old_u->mug_w;
|
||||
new_u->hed = _me_copy_south_in(old_u->hed);
|
||||
new_u->tel = _me_copy_south_in(old_u->tel);
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
old_u->mug_w = new;
|
||||
return new;
|
||||
}
|
||||
else {
|
||||
u2_me_atom* old_u = u2_me_to_ptr(dog);
|
||||
c3_w* new_w = u2_me_walloc(old_u->len_w + c3_wiseof(u2_me_atom));
|
||||
u2_noun new = u2_me_de_twin(dog, new_w);
|
||||
u2_me_atom* new_u = (u2_me_atom*)(void *)new_w;
|
||||
|
||||
new_u->mug_w = old_u->mug_w;
|
||||
new_u->len_w = old_u->len_w;
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w=0; i_w < old_u->len_w; i_w++ ) {
|
||||
new_u->buf_w[i_w] = old_u->buf_w[i_w];
|
||||
}
|
||||
}
|
||||
|
||||
/* Borrow mug slot to record new destination.
|
||||
*/
|
||||
old_u->mug_w = new;
|
||||
return new;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_gain_north(): gain on a north road.
|
||||
*/
|
||||
static u2_noun
|
||||
_me_gain_north(u2_noun dog)
|
||||
{
|
||||
c3_assert(u2_none != dog);
|
||||
if ( u2_yes == _me_north_senior(dog) ) {
|
||||
/* senior pointers are not refcounted
|
||||
*/
|
||||
return dog;
|
||||
}
|
||||
else if ( u2_yes == _me_north_junior(dog) ) {
|
||||
/* junior pointers are copied
|
||||
*/
|
||||
u2_noun mos = _me_copy_north(dog);
|
||||
|
||||
_me_wash_north(dog);
|
||||
return mos;
|
||||
}
|
||||
else {
|
||||
/* normal pointers are refcounted
|
||||
*/
|
||||
_me_gain_use(dog);
|
||||
return dog;
|
||||
}
|
||||
}
|
||||
|
||||
/* _me_gain_south(): gain on a south road.
|
||||
*/
|
||||
static u2_noun
|
||||
_me_gain_south(u2_noun dog)
|
||||
{
|
||||
if ( u2_yes == _me_south_senior(dog) ) {
|
||||
/* senior pointers are not refcounted
|
||||
*/
|
||||
return dog;
|
||||
}
|
||||
else if ( u2_yes == _me_south_junior(dog) ) {
|
||||
/* junior pointers are copied
|
||||
*/
|
||||
u2_noun mos = _me_copy_south(dog);
|
||||
|
||||
_me_wash_south(dog);
|
||||
return mos;
|
||||
}
|
||||
else {
|
||||
/* normal pointers are refcounted
|
||||
*/
|
||||
_me_gain_use(dog);
|
||||
return dog;
|
||||
}
|
||||
}
|
||||
|
||||
/* u2_me_gain(): gain and/or copy juniors.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_malt(c3_w* sal_w);
|
||||
u2_me_gain(u2_noun som)
|
||||
{
|
||||
c3_assert(u2_none != som);
|
||||
|
||||
/* u2_me_moot(): finish a pre-measured proto-atom; dangerous.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_moot(c3_w* sal_w);
|
||||
|
||||
/* u2_me_mint(): finish a measured proto-atom.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_mint(c3_w* sal_w, c3_w len_w);
|
||||
if ( u2_so(u2_me_is_cat(som)) ) {
|
||||
return som;
|
||||
}
|
||||
else {
|
||||
return u2_so(u2_me_is_north)
|
||||
? _me_gain_north(som)
|
||||
: _me_gain_south(som);
|
||||
}
|
||||
}
|
||||
|
@ -647,6 +647,7 @@
|
||||
# define c3__meh c3_s3('m','e','h')
|
||||
# define c3__meld c3_s4('m','e','l','d')
|
||||
# define c3__melt c3_s4('m','e','l','t')
|
||||
# define c3__meme c3_s4('m','e','m','e')
|
||||
# define c3__memo c3_s4('m','e','m','o')
|
||||
# define c3__menu c3_s4('m','e','n','u')
|
||||
# define c3__mesh c3_s4('m','e','s','h')
|
||||
|
@ -387,6 +387,7 @@
|
||||
|
||||
/* Tools for Martian booleans.
|
||||
*/
|
||||
# define u2_na(x) (u2_no == (x))
|
||||
# define u2_so(x) (u2_yes == (x))
|
||||
# define u2_say(x) ( (x) ? u2_yes : u2_no )
|
||||
# define u2_not(x) ( (x == u2_yes) ? u2_no : u2_yes )
|
||||
|
581
include/f/meme.h
581
include/f/meme.h
@ -2,9 +2,21 @@
|
||||
**
|
||||
** This file is in the public domain.
|
||||
*/
|
||||
/** Subordinate includes.
|
||||
**/
|
||||
/** c3: the C layer.
|
||||
**/
|
||||
# include "c/portable.h"
|
||||
# include "c/tune.h"
|
||||
# include "c/types.h"
|
||||
# include "c/defs.h"
|
||||
# include "c/motes.h"
|
||||
# include "c/comd.h"
|
||||
|
||||
|
||||
/** Tuning and configuration.
|
||||
**/
|
||||
# define u2_me_free_no 28
|
||||
# define u2_me_fbox_no 28
|
||||
|
||||
# undef U2_MEMORY_DEBUG
|
||||
# ifdef U2_MEMORY_DEBUG
|
||||
@ -16,6 +28,84 @@
|
||||
|
||||
/** Data structures.
|
||||
**/
|
||||
/* u2_noun: tagged pointer.
|
||||
**
|
||||
** If bit 31 is 0, a u2_noun is a direct 31-bit atom ("cat").
|
||||
** If bit 31 is 1 and bit 30 0, an indirect atom ("pug").
|
||||
** If bit 31 is 1 and bit 30 1, an indirect cell ("pom").
|
||||
**
|
||||
** Bits 0-29 are a word offset against u2_Loom.
|
||||
*/
|
||||
typedef c3_w u2_noun;
|
||||
|
||||
/* u2_none - out-of-band noun.
|
||||
*/
|
||||
# define u2_none (u2_noun)0xffffffff
|
||||
|
||||
/* u2_atom, u2_cell: logical atom and cell structures.
|
||||
*/
|
||||
typedef struct {
|
||||
c3_w mug_w;
|
||||
} u2_me_noun;
|
||||
|
||||
typedef struct {
|
||||
c3_w mug_w;
|
||||
c3_w len_w;
|
||||
c3_w buf_w[0];
|
||||
} u2_me_atom;
|
||||
|
||||
typedef struct _u2_loom_cell {
|
||||
c3_w mug_w;
|
||||
u2_noun hed;
|
||||
u2_noun tel;
|
||||
} u2_me_cell;
|
||||
|
||||
/* u2_yes, u2_no, u2_nul;
|
||||
**
|
||||
** Our Martian booleans and list terminator; empty string; not a nonu.
|
||||
*/
|
||||
# define u2_yes 0
|
||||
# define u2_no 1
|
||||
# define u2_nul 0
|
||||
# define u2_blip 0
|
||||
|
||||
/* Tools for Martian booleans.
|
||||
*/
|
||||
# define u2_so(x) (u2_yes == (x))
|
||||
# define u2_ne(x) (u2_no == (x))
|
||||
# define u2_say(x) ( (x) ? u2_yes : u2_no )
|
||||
# define u2_not(x) ( (x == u2_yes) ? u2_no : u2_yes )
|
||||
# define u2_and(x, y) ( (u2_so(x) && u2_so(y)) ? u2_yes : u2_no )
|
||||
# define u2_or(x, y) ( (u2_so(x) || u2_so(y)) ? u2_yes : u2_no )
|
||||
|
||||
/* Inside a noun.
|
||||
*/
|
||||
# define u2_me_is_cat(som) (((som) >> 31) ? u2_no : u2_yes)
|
||||
# define u2_me_is_dog(som) (((som) >> 31) ? u2_yes : u2_no)
|
||||
|
||||
# define u2_me_is_pug(som) (2 == (som >> 30))
|
||||
# define u2_me_is_pom(som) (3 == (som >> 30))
|
||||
# define u2_me_to_ptr(som) ((void *)(u2_me_into(som & 0x3fffffff)))
|
||||
|
||||
# define u2_me_is_atom(som) u2_or(u2_noun_is_cat(som), \
|
||||
u2_noun_is_pug(som))
|
||||
# define u2_me_is_cell(som) u2_noun_is_pom(som)
|
||||
# define u2_me_de_twin(dog, dog_w) ((dog & 0xc0000000) | u2_me_outa(dog_w))
|
||||
|
||||
|
||||
/* More typedefs.
|
||||
*/
|
||||
typedef u2_noun u2_atom; // must be atom
|
||||
typedef u2_noun u2_term; // @tas
|
||||
typedef u2_noun u2_mote; // @tas
|
||||
typedef u2_noun u2_cell; // must be cell
|
||||
typedef u2_noun u2_trel; // must be triple
|
||||
typedef u2_noun u2_qual; // must be quadruple
|
||||
typedef u2_noun u2_quin; // must be quintuple
|
||||
typedef u2_noun u2_bean; // loobean: 0 == u2_yes, 1 == u2_no
|
||||
typedef u2_noun u2_weak; // may be u2_none
|
||||
|
||||
|
||||
/* u2_me_box: classic allocation box.
|
||||
**
|
||||
** The box size is also stored at the end of the box in classic
|
||||
@ -40,7 +130,6 @@
|
||||
} u2_me_box;
|
||||
|
||||
# define u2_me_boxed(len_w) (len_w + c3_wiseof(u2_me_box) + 1)
|
||||
# define u2_me_boxof(box_v) ( (void *) \
|
||||
# define u2_me_boxto(box_v) ( (void *) \
|
||||
( ((c3_w *)(void*)(box_v)) + \
|
||||
c3_wiseof(u2_me_box) ) )
|
||||
@ -49,18 +138,16 @@
|
||||
( ((c3_w *)(void*)(tox_v)) - \
|
||||
c3_wiseof(u2_me_box) ) )
|
||||
|
||||
((box_w) + c3_wiseof(u2_me_box))
|
||||
|
||||
/* u2_me_free: free node in heap. Sets minimum node size.
|
||||
/* u2_me_fbox: free node in heap. Sets minimum node size.
|
||||
**
|
||||
*/
|
||||
typedef struct _u2_me_free {
|
||||
typedef struct _u2_me_fbox {
|
||||
u2_me_box box_u;
|
||||
struct _u2_me_free* pre_u;
|
||||
struct _u2_me_free* nex_u;
|
||||
} u2_me_free;
|
||||
struct _u2_me_fbox* pre_u;
|
||||
struct _u2_me_fbox* nex_u;
|
||||
} u2_me_fbox;
|
||||
|
||||
# define u2_me_minimum (c3_wiseof(u2_me_free))
|
||||
# define u2_me_minimum (c3_wiseof(u2_me_fbox))
|
||||
|
||||
/* u2_me_road: contiguous allocation and execution context.
|
||||
**
|
||||
@ -103,17 +190,16 @@
|
||||
struct _u2_me_road* kid_u; // child road list
|
||||
struct _u2_me_road* nex_u; // sibling road
|
||||
|
||||
struct { // layout information
|
||||
c3_w* cap_w; // top of transient region
|
||||
c3_w* hat_w; // top of durable region
|
||||
c3_w* mat_w; // bottom of transient region
|
||||
c3_w* rut_w; // bottom of durable region
|
||||
|
||||
c3_w* cap_w; // top of transient region
|
||||
c3_w* hat_w; // top of durable region
|
||||
c3_w* mat_w; // bottom of transient region
|
||||
c3_w* rut_w; // bottom of durable region
|
||||
#if 0
|
||||
c3_w* gar_w; // bottom of guard region (future)
|
||||
c3_w* rag_w; // top of guard region (future)
|
||||
|
||||
c3_w pad_w[4]; // future interesting info
|
||||
} lay;
|
||||
#endif
|
||||
|
||||
struct { // escape buffer
|
||||
union {
|
||||
@ -123,7 +209,7 @@
|
||||
} esc;
|
||||
|
||||
struct { // allocation pools
|
||||
u2_me_free* fre_u[u2_me_free_no]; // heap by node size log
|
||||
u2_me_fbox* fre_u[u2_me_fbox_no]; // heap by node size log
|
||||
# ifdef U2_MEMORY_DEBUG
|
||||
c3_w liv_w; // number of live words
|
||||
# endif
|
||||
@ -175,15 +261,15 @@
|
||||
|
||||
/** Macros.
|
||||
**/
|
||||
# define u2_me_is_north ((u2R->cap > u2R->hat) ? u2_yes : u2_no)
|
||||
# define u2_me_is_north ((u2R->cap_w > u2R->hat_w) ? u2_yes : u2_no)
|
||||
# define u2_me_is_south ((u2_yes == u2_me_is_north) ? u2_no : u2_yes)
|
||||
|
||||
# define u2_me_open ( (u2_yes == u2_me_is_north) \
|
||||
? (c3_w)(u2R->cap - u2R->hat) \
|
||||
: (c3_w)(u2R->hat - u2R->cap) )
|
||||
? (c3_w)(u2R->cap_w - u2R->hat_w) \
|
||||
: (c3_w)(u2R->hat_w - u2R->cap_w) )
|
||||
|
||||
# define u2_me_into(x) (((c3_w*)(void*)u2H) + (x))
|
||||
# define u2_me_outa(p) (((c3_w*)(void*)(p)) - (c3w*)(void*)u2H)
|
||||
# define u2_me_into(x) (u2_Loom + (x))
|
||||
# define u2_me_outa(p) (((c3_w*)(void*)(p)) - u2_Loom)
|
||||
|
||||
|
||||
/** Functions.
|
||||
@ -196,10 +282,10 @@
|
||||
/* u2_me_trap(): setjmp within road.
|
||||
*/
|
||||
#if 0
|
||||
u2_noun
|
||||
u2_bean
|
||||
u2_me_trap(void);
|
||||
#else
|
||||
# define u2_me_trap() (u2_noun)(setjmp(u2R->esc.buf))
|
||||
# define u2_me_trap() (u2_bean)(setjmp(u2R->esc.buf))
|
||||
#endif
|
||||
|
||||
/* u2_me_bail(): bail out. Does not return.
|
||||
@ -228,7 +314,7 @@
|
||||
/* u2_me_fall(): return to parent road.
|
||||
*/
|
||||
void
|
||||
u2_me_fall(void):
|
||||
u2_me_fall(void);
|
||||
|
||||
/* u2_me_leap(): advance to inner road.
|
||||
*/
|
||||
@ -249,18 +335,19 @@
|
||||
** // allocate some inner stuff...
|
||||
** u2_me_fall();
|
||||
** // inner stuff is still valid, but on cap
|
||||
** u2_me_
|
||||
** u2_me_flog(gof_w);
|
||||
**
|
||||
** u2_me_flog(0) simply clears the cap.
|
||||
*/
|
||||
void
|
||||
u2_me_flog(void);
|
||||
u2_me_flog(c3_w gof_w);
|
||||
|
||||
/* u2_me_water(): produce high and low watermarks. Asserts u2R == u2H.
|
||||
*/
|
||||
void
|
||||
u2_me_water(c3_w *low_w, c3_w *hig_w);
|
||||
|
||||
|
||||
/** Allocation.
|
||||
**/
|
||||
/* Basic allocation.
|
||||
@ -283,11 +370,6 @@
|
||||
|
||||
/* Reference and arena control.
|
||||
*/
|
||||
/* u2_me_open(): u2_yes iff a free block is available.
|
||||
*/
|
||||
u2_bean
|
||||
u2_me_open(c3_w len_w);
|
||||
|
||||
/* u2_me_gain(): gain and/or copy juniors.
|
||||
*/
|
||||
u2_weak
|
||||
@ -415,436 +497,3 @@
|
||||
u2_weak
|
||||
u2_me_uniq(u2_noun som);
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
/** 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.
|
||||
**/
|
||||
|
||||
/* 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_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_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
|
||||
|
12
v/cttp.c
12
v/cttp.c
@ -32,6 +32,8 @@
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
#define CTTP_NO_PIPELINE
|
||||
|
||||
/* Forward declarations.
|
||||
*/
|
||||
static void _cttp_ccon_kick(u2_ccon* coc_u);
|
||||
@ -638,6 +640,7 @@ _cttp_message_complete(http_parser* par_u)
|
||||
if ( u2_yes == coc_u->sec ) {
|
||||
SSL_shutdown(coc_u->ssl.ssl_u);
|
||||
_cttp_ccon_cryp_rout(coc_u);
|
||||
uL(fprintf(uH, "cttp: close b: %p\n", coc_u));
|
||||
uv_close((uv_handle_t*)&coc_u->wax_u, _cttp_ccon_fail_cb);
|
||||
}
|
||||
return 0;
|
||||
@ -806,6 +809,7 @@ _cttp_ccon_reboot(u2_ccon* coc_u)
|
||||
|
||||
/* Begin again.
|
||||
*/
|
||||
uL(fprintf(uH, "ccon: rekick\r\n"));
|
||||
_cttp_ccon_kick(coc_u);
|
||||
}
|
||||
break;
|
||||
@ -836,6 +840,7 @@ _cttp_ccon_fail(u2_ccon* coc_u, u2_bean say)
|
||||
_cttp_ccon_reboot(coc_u);
|
||||
}
|
||||
else {
|
||||
uL(fprintf(uH, "cttp: close: %p\n", coc_u));
|
||||
uv_close((uv_handle_t*)&coc_u->wax_u, _cttp_ccon_fail_cb);
|
||||
}
|
||||
}
|
||||
@ -1319,6 +1324,7 @@ _cttp_ccon_new(u2_bean sec, c3_s por_s, c3_c* hot_c)
|
||||
return coc_u;
|
||||
}
|
||||
|
||||
#ifndef CTTP_NO_PIPELINE
|
||||
/* _cttp_ccon_find(): find existing connection for remote server.
|
||||
*/
|
||||
static u2_ccon*
|
||||
@ -1335,19 +1341,23 @@ _cttp_ccon_find(u2_bean sec, c3_s por_s, c3_c* hot_c)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* _cttp_ccon(): create or find persistent client connection.
|
||||
*/
|
||||
static u2_ccon*
|
||||
_cttp_ccon(u2_bean sec, c3_s por_s, c3_c* hot_c)
|
||||
{
|
||||
#ifndef CTTP_NO_PIPELINE
|
||||
u2_ccon* coc_c = _cttp_ccon_find(sec, por_s, hot_c);
|
||||
|
||||
if ( 0 != coc_c ) {
|
||||
free(hot_c);
|
||||
return coc_c;
|
||||
}
|
||||
else return _cttp_ccon_new(sec, por_s, hot_c);
|
||||
else
|
||||
#endif
|
||||
return _cttp_ccon_new(sec, por_s, hot_c);
|
||||
}
|
||||
|
||||
/* _cttp_creq(): cttp request from noun.
|
||||
|
Loading…
Reference in New Issue
Block a user