Various fixes and improvements.

This commit is contained in:
C. Guy Yarvin 2014-09-30 23:34:30 -07:00
parent 9f7d3f43b4
commit 3dcd76e477
6 changed files with 277 additions and 219 deletions

77
g/a.c
View File

@ -54,7 +54,7 @@ _box_attach(u3_cs_box* box_u)
{
c3_assert(box_u->siz_w >= (1 + c3_wiseof(u3_cs_fbox)));
u3R->fre_w += box_u->siz_w;
u3R->all.fre_w += box_u->siz_w;
{
c3_w sel_w = _box_slot(box_u->siz_w);
u3_cs_fbox* fre_u = (void *)box_u;
@ -79,7 +79,7 @@ _box_detach(u3_cs_box* box_u)
u3_cs_fbox* pre_u = fre_u->pre_u;
u3_cs_fbox* nex_u = fre_u->nex_u;
u3R->fre_w -= box_u->siz_w;
u3R->all.fre_w -= box_u->siz_w;
if ( nex_u ) {
c3_assert(nex_u->pre_u == fre_u);
@ -97,7 +97,7 @@ _box_detach(u3_cs_box* box_u)
}
}
/* _me_road_all_hat(): in u3R, allocate directly on the hat_w.
/* _me_road_all_hat(): in u3R, allocate directly on the hat.
*/
static c3_w*
_me_road_all_hat(c3_w len_w)
@ -652,10 +652,10 @@ _me_copy_south(u3_noun dog)
}
}
/* _me_gain_north(): gain on a north road.
/* _me_take_north(): take on a north road.
*/
static u3_noun
_me_gain_north(u3_noun dog)
_me_take_north(u3_noun dog)
{
if ( u3_yes == u3_co_north_is_senior(dog) ) {
/* senior pointers are not refcounted
@ -678,10 +678,32 @@ _me_gain_north(u3_noun dog)
}
}
/* _me_gain_south(): gain on a south road.
/* _me_gain_north(): gain on a north road.
*/
static u3_noun
_me_gain_south(u3_noun dog)
_me_gain_north(u3_noun dog)
{
if ( u3_yes == u3_co_north_is_senior(dog) ) {
/* senior pointers are not refcounted
*/
return dog;
}
else {
/* junior nouns are disallowed
*/
c3_assert(u3_ne(u3_co_north_is_junior(dog)));
/* normal pointers are refcounted
*/
_me_gain_use(dog);
return dog;
}
}
/* _me_take_south(): take on a south road.
*/
static u3_noun
_me_take_south(u3_noun dog)
{
if ( u3_yes == u3_co_south_is_senior(dog) ) {
/* senior pointers are not refcounted
@ -704,6 +726,28 @@ _me_gain_south(u3_noun dog)
}
}
/* _me_gain_south(): gain on a south road.
*/
static u3_noun
_me_gain_south(u3_noun dog)
{
if ( u3_yes == u3_co_south_is_senior(dog) ) {
/* senior pointers are not refcounted
*/
return dog;
}
else {
/* junior nouns are disallowed
*/
c3_assert(u3_ne(u3_co_south_is_junior(dog)));
/* normal nouns are refcounted
*/
_me_gain_use(dog);
return dog;
}
}
/* _me_lose_north(): lose on a north road.
*/
static void
@ -784,7 +828,24 @@ top:
}
}
/* u3_ca_gain(): gain a reference count, and/or copy juniors.
/* u3_ca_take(): gain, copying juniors.
*/
u3_noun
u3_ca_take(u3_noun som)
{
c3_assert(u3_none != som);
if ( u3_so(u3_co_is_cat(som)) ) {
return som;
}
else {
return u3_so(u3_co_is_north)
? _me_take_north(som)
: _me_take_south(som);
}
}
/* u3_ca_gain(): gain a reference count in normal space.
*/
u3_noun
u3_ca_gain(u3_noun som)

262
g/m.c
View File

@ -49,6 +49,7 @@ _find_north(c3_w* mem_w, c3_w siz_w, c3_w len_w)
return (void *) ((mem_w + len_w) - siz_w);
}
#if 0
/* _find_south(): in restored image, point to a south home.
*/
static u3_road*
@ -56,6 +57,7 @@ _find_south(c3_w* mem_w, c3_w siz_w, c3_w len_w)
{
return (void *)(mem_w + siz_w);
}
#endif
static u3_road*
_boot_north(c3_w* mem_w, c3_w siz_w, c3_w len_w)
@ -174,6 +176,7 @@ u3_cm_dump(void)
}
}
#if 0
/* _cm_punt(): crudely print trace.
*/
static void
@ -185,6 +188,7 @@ _cm_punt(void)
u3_cm_p("&", u3h(xat));
}
}
#endif
/* u3_cm_bail(): bail out. Does not return.
**
@ -207,7 +211,7 @@ _cm_punt(void)
** ==
*/
c3_i
u3_cm_bail(u2_noun how)
u3_cm_bail(u3_noun how)
{
/* Printf some metadata.
*/
@ -215,10 +219,10 @@ u3_cm_bail(u2_noun how)
if ( u3_so(u3ud(how)) ) {
c3_c str_c[5];
str_c[0] = ((how_m >> 0) & 0xff);
str_c[1] = ((how_m >> 8) & 0xff);
str_c[2] = ((how_m >> 16) & 0xff);
str_c[3] = ((how_m >> 24) & 0xff);
str_c[0] = ((how >> 0) & 0xff);
str_c[1] = ((how >> 8) & 0xff);
str_c[2] = ((how >> 16) & 0xff);
str_c[3] = ((how >> 24) & 0xff);
str_c[4] = 0;
printf("bail: %s (at %llu)\r\n", str_c, u3N);
}
@ -251,7 +255,7 @@ u3_cm_bail(u2_noun how)
/* Longjmp, with an underscore.
*/
_longjmp(u3R->esc.buf, how_m);
_longjmp(u3R->esc.buf, how);
return 0;
}
@ -269,27 +273,68 @@ u3_cm_error(c3_c* str_c)
/* u3_cm_leap(): in u3R, create a new road within the existing one.
*/
void
u3_cm_leap()
u3_cm_leap(c3_w pad_w)
{
c3_w len_w;
u3_road* rod_u;
if ( u3_yes == u3_co_is_north ) {
rod_u = _boot_south(u3R->hat_w,
c3_wiseof(u3_cs_road),
(u3R->cap_w - u3R->hat_w));
}
else {
rod_u = _boot_north(u3R->cap_w,
c3_wiseof(u3_cs_road),
(u3R->hat_w - u3R->cap_w));
/* Measure the pad - we'll need it.
*/
{
if ( pad_w < u3R->all.fre_w ) {
pad_w = 0;
}
else {
pad_w -= u3R->all.fre_w;
}
if ( (pad_w + c3_wiseof(u3_cs_road)) <= u3_co_open ) {
u3_cm_bail(c3__meme);
}
len_w = u3_co_open - (pad_w + c3_wiseof(u3_cs_road));
}
c3_assert(0 == u3R->kid_u);
rod_u->par_u = u3R;
u3R->kid_u = rod_u;
/* Allocate a region on the cap.
*/
{
c3_w* bot_w;
u3R = rod_u;
_boot_parts();
if ( u3_yes == u3_co_is_north ) {
bot_w = (u3R->cap_w - len_w);
u3R->cap_w -= len_w;
rod_u = _boot_south(bot_w, c3_wiseof(u3_cs_road), len_w);
printf("leap: from north %p (cap %p), to south %p\r\n",
u3R,
u3R->cap_w + len_w,
rod_u);
}
else {
bot_w = u3R->cap_w;
u3R->cap_w += len_w;
rod_u = _boot_north(bot_w, c3_wiseof(u3_cs_road), len_w);
printf("leap: from north %p (cap %p), to south %p\r\n",
u3R,
u3R->cap_w - len_w,
rod_u);
}
}
/* Attach the new road to its parents.
*/
{
c3_assert(0 == u3R->kid_u);
rod_u->par_u = u3R;
u3R->kid_u = rod_u;
}
/* Set up the new road.
*/
{
u3R = rod_u;
_boot_parts();
}
}
/* u3_cm_fall(): in u3R, return an inner road to its parent.
@ -299,8 +344,22 @@ u3_cm_fall()
{
c3_assert(0 != u3R->par_u);
printf("leap: from %s %p, to %s %p (cap %p, was %p)\r\n",
u3_so(u3_co_is_north) ? "north" : "south",
u3R,
u3_so(u3_co_is_north) ? "north" : "south",
u3R->par_u,
u3R->hat_w,
u3R->rut_w);
/* The new cap is the old hat - it's as simple as that.
*/
u3R->par_u->cap_w = u3R->hat_w;
/* And, we're back home.
*/
u3R = u3R->par_u;
u3R->kid_u = 0;
}
/* u3_cm_golf(): record cap_w length for u3_flog().
@ -339,7 +398,7 @@ u3_cm_water(c3_w* low_w, c3_w* hig_w)
*hig_w = (u3H->rod_u.mat_w - u3H->rod_u.cap_w) + c3_wiseof(u3_cs_home);
}
/* u3_cm_soft_top(): top-level wrapper.
/* u3_cm_soft_top(): top-level safety wrapper.
*/
u3_noun
u3_cm_soft_top(c3_w pad_w,
@ -387,7 +446,7 @@ u3_cm_soft_top(c3_w pad_w,
/* Produce success, on the old road.
*/
pro = u3nc(0, u3k(pro));
pro = u3nc(0, u3_ca_take(pro));
}
else {
/* Test stack correctness assertions, and restore.
@ -405,11 +464,11 @@ u3_cm_soft_top(c3_w pad_w,
/* Produce the error result.
*/
pro = u3k(why);
pro = u3_ca_take(why);
}
/* Clean up temporary memory.
*/
u3_cm_golf(gof_w);
u3_cm_flog(gof_w);
/* Return the product.
*/
@ -424,20 +483,9 @@ u3_cm_soft_run(u3_noun fly,
u3_noun aga,
u3_noun agb)
{
u3_noun why, don, flu, tax, pro;
u3_noun why, pro;
c3_w gof_w;
/* Record all stacks; clear the trace; push the fly.
*/
{
don = u3R->pro.don;
flu = u3R->ski.flu;
tax = u3R->bug.tax;
u3R->bug.tax = 0;
u3R->ski.flu = u3nc(fly, u3k(flu));
}
/* Record the cap, and leap.
*/
{
@ -445,43 +493,28 @@ u3_cm_soft_run(u3_noun fly,
u3_cm_leap(32768);
}
/* Configure the new road.
*/
{
u3R->ski.flu = u3nc(fly, u3R->par_u->ski.flu);
u3R->pro.don = u3R->par_u->pro.don;
u3R->bug.tax = 0;
}
/* Trap for exceptions.
*/
if ( 0 == (why = u3_cm_trap()) ) {
u3_noun pro = fun_f(aga, agb);
/* Test stack correctness assertions, and restore.
*/
{
c3_assert(0 == u3R->bug.tax); // trace is clean
c3_assert(flu == u3t(u3R->ski.flu)); // namespaces are clean
c3_assert(don == u3R->pro.don); // profile is clean
u3R->bug.tax = tax; // restore trace
u3z(u3R->ski.flu); // free namespace stack
u3R->ski.flu = flu; // reset namespaces
}
/* Fall back to the old road, leaving temporary memory intact.
*/
u3_cm_fall();
/* Produce success, on the old road.
*/
pro = u3nc(0, u3k(pro));
pro = u3nc(0, u3_ca_take(pro));
}
else {
/* Test stack correctness assertions, and restore.
*/
{
c3_assert(flu == u3t(u3R->ski.flu)); // namespaces are clean
u3R->pro.don = don; // restore profile
u3R->bug.tax = tax; // restore trace
u3z(u3R->ski.flu); // free namespace stack
u3R->ski.flu = flu; // reset namespaces
}
/* Fall back to the old road, leaving temporary memory intact.
*/
u3_cm_fall();
@ -494,57 +527,62 @@ u3_cm_soft_run(u3_noun fly,
default: c3_assert(0); return 0;
case 0: { // unusual: bail with success.
pro = u3k(why);
pro = u3_ca_take(why);
} break;
case 1: { // blocking request
pro = u3k(why);
pro = u3_ca_take(why);
} break;
case 2: { // true exit
pro = u3k(why);
pro = u3_ca_take(why);
} break;
case 3: { // super-exit; rebail
case 3: { // failure; rebail w/trace
u3_cm_bail
(u3nt(3,
u3h(u3t(why)),
u3_ckb_weld(u3t(u3t(why)), u3k(tax)));
u3_ca_take(u3h(u3t(why))),
u3_ckb_weld(u3_ca_take(u3t(u3t(why))),
u3k(u3R->bug.tax))));
} break;
case 4: { // meta-bail
u3_cm_bail(u3t(why));
u3_cm_bail(u3_ca_take(u3t(why)));
} break;
}
}
}
/* Clean up temporary memory.
*/
u3_cm_golf(gof_w);
u3_cm_flog(gof_w);
/* Release the arguments.
*/
{
u3z(fly);
u3z(aga);
u3z(agb);
}
/* Return the product.
*/
return pro;
}
/* u3_cm_nock_soft_esc(): compute with fly.
/* u3_cm_soft_esc(): namespace lookup. Produces direct result.
*/
u3_noun
u3_cm_nock_soft_esc(u3_noun sam)
u3_cm_soft_esc(u3_noun sam)
{
u3_noun why, don, flu, tax, pro;
u3_noun why, fly, pro;
c3_w gof_w;
/* Record all stacks; clear the trace; pop the fly.
/* Assert preconditions.
*/
c3_assert(0 != u3R->ski.flu);
{
don = u3R->pro.don;
flu = u3R->ski.flu;
tax = u3R->bug.tax;
u3R->bug.tax = 0;
u3R->ski.flu = u3k(u3t(flu));
c3_assert(0 != u3R->ski.flu);
fly = u3h(u3R->ski.flu);
}
/* Record the cap, and leap.
@ -554,22 +592,18 @@ u3_cm_nock_soft_esc(u3_noun sam)
u3_cm_leap(32768);
}
/* Configure the new road.
*/
{
u3R->ski.flu = u3t(u3R->par_u->ski.flu);
u3R->pro.don = u3R->par_u->pro.don;
u3R->bug.tax = 0;
}
/* Trap for exceptions.
*/
if ( 0 == (why = u3_cm_trap()) ) {
u3_noun pro = fun_f(aga, agb);
/* Test stack correctness assertions, and restore.
*/
{
c3_assert(0 == u3R->bug.tax); // trace is clean
c3_assert(u3t(flu) == u3R->ski.flu); // namespaces are clean
c3_assert(don == u3R->pro.don); // profile is clean
u3R->bug.tax = tax; // restore trace
u3z(u3R->ski.flu); // free namespace stack
u3R->ski.flu = flu; // reset namespaces
}
pro = u3_cn_slam_on(fly, sam);
/* Fall back to the old road, leaving temporary memory intact.
*/
@ -577,39 +611,51 @@ u3_cm_nock_soft_esc(u3_noun sam)
/* Produce success, on the old road.
*/
pro = u3nc(0, u3k(pro));
pro = u3_ca_take(pro);
}
else {
/* Test stack correctness assertions, and restore.
*/
{
c3_assert(flu == u3t(u3R->ski.flu)); // namespaces are clean
u3R->pro.don = don; // restore profile
u3R->bug.tax = tax; // restore trace
u3z(u3R->ski.flu); // free namespace stack
u3R->ski.flu = flu; // reset namespaces
}
/* Fall back to the old road, leaving temporary memory intact.
*/
u3_cm_fall();
/* Push the error back up to the calling context - not the run we
** are in, but the caller of the run.
** are in, but the caller of the run, matching pure nock semantics.
*/
return u3_cm_bail(u3nc(4, u3k(why)));
return u3_cm_bail(u3nc(4, u3_ca_take(why)));
}
/* Clean up temporary memory.
*/
u3_cm_golf(gof_w);
u3_cm_flog(gof_w);
/* Release the sample.
*/
u3z(sam);
/* Return the product.
*/
return pro;
}
/* u3_cm_soft(): wrapper for old calls.
*/
u3_noun
u3_cm_soft(c3_w sec_w,
u3_funk fun_f,
u3_noun arg)
{
u3_noun why = u3_cm_soft_top(0, fun_f, arg);
u3_noun pro;
switch ( u3h(why) ) {
default: c3_assert(0); break;
case 0: pro = why; break;
case 2: pro = u3nc(c3__exit, u3k(u3t(why))); u3z(why); break;
case 3: pro = u3k(u3t(why)); u3z(why); break;
}
return pro;
}
/* _cm_is_tas(): yes iff som (RETAIN) is @tas.
*/
static c3_o

122
g/n.c
View File

@ -297,7 +297,21 @@ u3_cn_nock_on(u3_noun bus, u3_noun fol)
}
case 11: {
c3_assert(!"11 remains stubbed out");
u3_noun gof = u3_cn_nock_on(bus, u3k(gal));
u3_noun val = u3_cm_soft_esc(u3nc(u3k(gof), 0));
if ( u3_ne(u3du(val)) ) {
u3_cm_bail(u3nt(1, gof, 0));
}
else {
u3_noun pro;
u3z(fol);
pro = u3k(u3t(val));
u3z(val);
return pro;
}
}
c3_assert(!"not reached");
}
@ -323,78 +337,14 @@ u3_cn_slam_on(u3_noun gat, u3_noun sam)
return u3_cn_kick_on(cor);
}
/* u3_cn_nock_it_top(): full virtualization, no fly, set pad.
**
** Produces [0 result], [1 paths] == wait, [2 trace] == exit,
** or [term trace] for an internal error.
*/
u3_noun
u3_cn_nock_it_flat(c3_w pad_w,
u3_noun bus,
u3_noun fol)
{
c3_w gof_w;
c3_l why_l;
gof_w = u3_cm_golf();
u3_cm_leap(pad_w);
if ( u3_blip != (why_l = u3_cm_trap()) ) {
/* Collect information to be preserved.
*/
if ( (why_l == c3__need) || (why_l == c3__exit) ) {
u3_noun ton;
if ( 0 != u3R->net.nyd ) {
c3_assert(c3__need == why_l);
ton = u3nc(1, u3R->net.nyd);
}
}
u3_cm_fall();
/* Collect infora
if ( 0 != u3R->net.nyd ) {
c3_assert(c3__need == why_l);
}
}
else {
}
/* u3_cn_nock_un(): produce .*(bus fol), as ++toon.
*/
u3_noun
u3_cn_nock_un(u3_noun bus, u3_noun fol)
{
u3_noun why_l;
c3_w gof_w;
u3_noun ton;
u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
// u3_cm_leap();
if ( u3_blip != (why_l = u3_cm_trap()) ) {
u3_noun ton;
if ( 0 != u3R->net.nyd ) {
ton = u3nc(1, u3R->net.nyd);
u3R->net.nyd = 0;
}
else {
ton = u3nc(2, u3R->bug.tax);
u3R->bug.tax = 0;
}
// u3_cm_fall();
ton = u3_ca_gain(ton);
// u3_cm_flog(0);
}
else {
u3_noun pro = u3_cn_nock_on(bus, fol);
// u3_cm_fall();
ton = u3nc(0, u3_ca_gain(pro));
}
// u3z(bus); u3z(fol); return ton;
return ton;
return u3_cn_nock_in(fly, bus, fol);
}
/* u3_cn_slam_un(): produce (gat sam), as ++toon.
@ -402,31 +352,9 @@ u3_cn_nock_un(u3_noun bus, u3_noun fol)
u3_noun
u3_cn_slam_un(u3_noun gat, u3_noun sam)
{
u3_noun ton;
u3_noun fly = u3nt(u3nt(11, 0, 6), 0, 0); // |=(a=* .^(a))
// u3_cm_leap();
if ( u3_blip != u3_cm_trap() ) {
u3_noun ton;
if ( 0 != u3R->net.nyd ) {
ton = u3nc(1, u3R->net.nyd);
u3R->net.nyd = 0;
} else {
ton = u3nc(2, u3R->bug.tax);
u3R->bug.tax = 0;
}
// u3_cm_fall();
ton = u3_ca_gain(ton);
// u3_cm_flog(0);
}
else {
u3_noun pro = u3_cn_slam_on(gat, sam);
// u3_cm_fall();
ton = u3nc(0, u3_ca_gain(pro));
}
// u3z(gat); u3z(sam); return ton;
return ton;
return u3_cn_slam_in(fly, gat, sam);
}
/* u3_cn_nock_in(): produce .*(bus fol), as ++toon, in namespace.
@ -434,9 +362,7 @@ u3_cn_slam_un(u3_noun gat, u3_noun sam)
u3_noun
u3_cn_nock_in(u3_noun fly, u3_noun bus, u3_noun fol)
{
// XX implement 11
//
u3z(fly); return u3_cn_nock_un(bus, fol);
return u3_cm_soft_run(fly, u3_cn_nock_on, bus, fol);
}
/* u3_cn_slam_in(): produce (gat sam), as ++toon, in namespace.
@ -444,9 +370,7 @@ u3_cn_nock_in(u3_noun fly, u3_noun bus, u3_noun fol)
u3_noun
u3_cn_slam_in(u3_noun fly, u3_noun gat, u3_noun sam)
{
// XX implement 11
//
u3z(fly); return u3_cn_slam_un(gat, sam);
return u3_cm_soft_run(fly, u3_cn_slam_on, gat, sam);
}
/* u3_cn_nock_an(): as slam_in(), but with empty fly.
@ -454,5 +378,7 @@ u3_cn_slam_in(u3_noun fly, u3_noun gat, u3_noun sam)
u3_noun
u3_cn_nock_an(u3_noun bus, u3_noun fol)
{
return u3_cn_nock_un(bus, fol);
u3_noun fly = u3nt(u3nc(1, 0), 0, 0); // |=(a=* ~)
return u3_cn_nock_in(fly, bus, fol);
}

View File

@ -35,11 +35,16 @@
/* Reference and arena control.
*/
/* u3_ca_gain(): gain and/or copy juniors.
/* u3_ca_gain(): gain a reference count in normal space.
*/
u3_weak
u3_ca_gain(u3_weak som);
/* u3_ca_take(): gain, copying juniors.
*/
u3_noun
u3_ca_take(u3_noun som);
/* u3_ca_lose(): lose a reference.
*/
void

View File

@ -68,10 +68,10 @@
void
u3_cm_fall(void);
/* u3_cm_leap(): advance to inner road.
/* u3_cm_leap(): in u3R, create a new road within the existing one.
*/
void
u3_cm_leap(void);
u3_cm_leap(c3_w pad_w);
/* u3_cm_wash(): wash all lazy mugs. RETAIN.
*/
@ -106,6 +106,26 @@
u3_noun
u3_cm_soft(c3_w sec_w, u3_funk fun_f, u3_noun arg);
/* u3_cm_soft_top(): top-level safety wrapper.
*/
u3_noun
u3_cm_soft_top(c3_w pad_w,
u3_funk fun_f,
u3_noun arg);
/* u3_cm_soft_run(): descend into virtualization context.
*/
u3_noun
u3_cm_soft_run(u3_noun fly,
u3_funq fun_f,
u3_noun aga,
u3_noun agb);
/* u3_cm_soft_esc(): namespace lookup. Produces direct result.
*/
u3_noun
u3_cm_soft_esc(u3_noun sam);
/* u3_cm_water(): produce high and low watermarks. Asserts u3R == u3H.
*/
void

View File

@ -149,7 +149,7 @@
} coy;
struct { // jet dashboard
u3_ch_root* har_u; // jet index by
u3_ch_root* har_u; // jet index
} jed;
struct { // namespace