From bd0432f84e1dc83dbe1bd3e2b2d07d021eda8074 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 11:54:57 -0700 Subject: [PATCH 01/23] ur: adds initialization/finalization to bitstream-write api --- pkg/urbit/include/ur/bitstream.h | 12 ++++++++++++ pkg/urbit/noun/serial.c | 10 ++-------- pkg/urbit/ur/bitstream.c | 27 +++++++++++++++++++++++++++ pkg/urbit/ur/serial.c | 14 +++----------- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/pkg/urbit/include/ur/bitstream.h b/pkg/urbit/include/ur/bitstream.h index 66781f569..8e7ae7f94 100644 --- a/pkg/urbit/include/ur/bitstream.h +++ b/pkg/urbit/include/ur/bitstream.h @@ -130,6 +130,12 @@ ur_bsr_log(ur_bsr_t *bsr, uint8_t *out); ur_cue_res_e ur_bsr_rub_len(ur_bsr_t *bsr, uint64_t *out); +/* +** initialize bitstream-writer with prev/size for fibonacci growth. +*/ +void +ur_bsw_init(ur_bsw_t *bsw, uint64_t prev, uint64_t size); + /* ** reallocate bitstream write buffer with max(fibonacci, step) growth. */ @@ -142,6 +148,12 @@ ur_bsw_grow(ur_bsw_t *bsw, uint64_t step); ur_bool_t ur_bsw_sane(ur_bsw_t *bsw); +/* +** return bit-length, produce byte-buffer. +*/ +uint64_t +ur_bsw_done(ur_bsw_t *bsw, uint64_t *len, uint8_t **byt); + /* ** write a bit */ diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index 79208801a..15c946699 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -290,13 +290,10 @@ c3_d u3s_jam_xeno(u3_noun a, c3_d* len_d, c3_y** byt_y) { _jam_xeno_t jam_u = {0}; + ur_bsw_init(&jam_u.rit_u, ur_fib11, ur_fib12); jam_u.har_p = u3h_new(); - jam_u.rit_u.prev = ur_fib11; - jam_u.rit_u.size = ur_fib12; - jam_u.rit_u.bytes = c3_calloc(jam_u.rit_u.size); - // as this is a hot path, we unsafely elide overflow checks // // a page-fault overflow detection system is urgently needed ... @@ -304,12 +301,9 @@ u3s_jam_xeno(u3_noun a, c3_d* len_d, c3_y** byt_y) u3a_walk_fore_unsafe(a, &jam_u, _cs_jam_xeno_atom, _cs_jam_xeno_cell); - *len_d = jam_u.rit_u.fill + !!jam_u.rit_u.off; - *byt_y = jam_u.rit_u.bytes; - u3h_free(jam_u.har_p); - return jam_u.rit_u.bits; + return ur_bsw_done(&jam_u.rit_u, len_d, byt_y); } #define CUE_ROOT 0 diff --git a/pkg/urbit/ur/bitstream.c b/pkg/urbit/ur/bitstream.c index 31f485b85..146f5e33d 100644 --- a/pkg/urbit/ur/bitstream.c +++ b/pkg/urbit/ur/bitstream.c @@ -702,6 +702,20 @@ ur_bsr_rub_len(ur_bsr_t *bsr, uint64_t *out) ** of reallocating the output buffer. */ +void +ur_bsw_init(ur_bsw_t *bsw, uint64_t prev, uint64_t size) +{ + bsw->prev = prev; + bsw->size = size; + bsw->bytes = calloc(size, 1); + + if ( !bsw->bytes ) { + fprintf(stderr, + "ur: bitstream-init allocation failed, out of memory\r\n"); + abort(); + } +} + void ur_bsw_grow(ur_bsw_t *bsw, uint64_t step) { @@ -729,6 +743,19 @@ ur_bsw_sane(ur_bsw_t *bsw) && ((bsw->fill << 3) + bsw->off == bsw->bits) ); } +uint64_t +ur_bsw_done(ur_bsw_t *bsw, uint64_t *len, uint8_t **byt) +{ + uint64_t bits = bsw->bits; + + *len = bsw->fill + !!bsw->off; + *byt = bsw->bytes; + + memset(bsw, 0, sizeof(*bsw)); + + return bits; +} + static inline void _bsw_bit_unsafe(ur_bsw_t *bsw, uint8_t bit) { diff --git a/pkg/urbit/ur/serial.c b/pkg/urbit/ur/serial.c index a2d111e91..7f922f539 100644 --- a/pkg/urbit/ur/serial.c +++ b/pkg/urbit/ur/serial.c @@ -87,20 +87,12 @@ ur_jam_unsafe(ur_root_t *r, uint64_t *len, uint8_t **byt) { - _jam_t j = {0}; - - j.dict = dict; - - j.bsw.prev = ur_fib11; - j.bsw.size = ur_fib12; - j.bsw.bytes = _oom("jam", calloc(j.bsw.size, 1)); + _jam_t j = { .dict = dict }; + ur_bsw_init(&j.bsw, ur_fib11, ur_fib12); ur_walk_fore(r, ref, &j, _jam_atom, _jam_cell); - *len = j.bsw.fill + !!j.bsw.off; - *byt = j.bsw.bytes; - - return j.bsw.bits; + return ur_bsw_done(&j.bsw, len, byt); } uint64_t From 06cf6386aadf16c73c5bac027c472df3583d2aff Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 11:55:31 -0700 Subject: [PATCH 02/23] ur: renames bitstream-write reinit test helper for clarity --- pkg/urbit/tests/ur_tests.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/urbit/tests/ur_tests.c b/pkg/urbit/tests/ur_tests.c index 56e8f2dc1..f8d6ae1e0 100644 --- a/pkg/urbit/tests/ur_tests.c +++ b/pkg/urbit/tests/ur_tests.c @@ -11,7 +11,7 @@ ** initialize helper for bitstream-writer tests. */ static void -_bsw_init(ur_bsw_t *bsw, uint64_t prev, uint64_t size) +_bsw_reinit(ur_bsw_t *bsw, uint64_t prev, uint64_t size) { bsw->prev = prev; bsw->size = size; @@ -58,7 +58,7 @@ _test_bsw_bit_ones(void) { int ret = 1; ur_bsw_t bsw = {0}; - _bsw_init(&bsw, 1, 1); + _bsw_reinit(&bsw, 1, 1); ret &= _bsw_bit_check("bsw ones init", &bsw, 0x0, 0); @@ -104,7 +104,7 @@ _test_bsw_bit_zeros(void) { int ret = 1; ur_bsw_t bsw = {0}; - _bsw_init(&bsw, 1, 1); + _bsw_reinit(&bsw, 1, 1); ret &= _bsw_bit_check("bsw zeros init", &bsw, 0x0, 0); @@ -150,7 +150,7 @@ _test_bsw_bit_alt(void) { int ret = 1; ur_bsw_t bsw = {0}; - _bsw_init(&bsw, 1, 1); + _bsw_reinit(&bsw, 1, 1); ret &= _bsw_bit_check("bsw alt init", &bsw, 0x0, 0); @@ -286,8 +286,8 @@ _test_bsw8_loop(const char* cap, uint8_t val) for ( i = 0; i < 8; i++) { for ( j = 0; j <= 8; j++ ) { - _bsw_init(&a, 1, 1); - _bsw_init(&b, 1, 1); + _bsw_reinit(&a, 1, 1); + _bsw_reinit(&b, 1, 1); a.off = a.bits = b.off = b.bits = i; _bsw8_slow(&a, j, val); @@ -338,8 +338,8 @@ _test_bsw32_loop(const char* cap, uint32_t val) for ( i = 0; i < 8; i++) { for ( j = 0; j <= 32; j++ ) { - _bsw_init(&a, 1, 1); - _bsw_init(&b, 1, 1); + _bsw_reinit(&a, 1, 1); + _bsw_reinit(&b, 1, 1); a.off = a.bits = b.off = b.bits = i; _bsw32_slow(&a, j, val); @@ -390,8 +390,8 @@ _test_bsw64_loop(const char* cap, uint64_t val) for ( i = 0; i < 8; i++) { for ( j = 0; j <= 64; j++ ) { - _bsw_init(&a, 1, 1); - _bsw_init(&b, 1, 1); + _bsw_reinit(&a, 1, 1); + _bsw_reinit(&b, 1, 1); a.off = a.bits = b.off = b.bits = i; _bsw64_slow(&a, j, val); @@ -447,8 +447,8 @@ _test_bsw_bytes_loop(const char* cap, uint64_t len, uint8_t val) for ( i = 0; i < 8; i++) { for ( j = 0; j < len_bit; j++ ) { - _bsw_init(&a, 1, 1); - _bsw_init(&b, 1, 1); + _bsw_reinit(&a, 1, 1); + _bsw_reinit(&b, 1, 1); a.off = a.bits = b.off = b.bits = i; _bsw_bytes_slow(&a, j, byt); @@ -506,8 +506,8 @@ _test_bsw_bex() for ( i = 0; i < 8; i++) { for ( j = 0; j < 256; j++ ) { - _bsw_init(&a, 1, 1); - _bsw_init(&b, 1, 1); + _bsw_reinit(&a, 1, 1); + _bsw_reinit(&b, 1, 1); a.off = a.bits = b.off = b.bits = i; _bsw_bex_slow(&a, j); From efe4479f23769584a0e3f1bd1cfe5fecd090dd31 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 15:12:30 -0700 Subject: [PATCH 03/23] ur: refactors unsafe cue variants into a handle-based api --- pkg/urbit/bench/ur_bench.c | 12 +- pkg/urbit/include/ur/serial.h | 54 +++++++-- pkg/urbit/ur/serial.c | 199 +++++++++++++++++++++++++--------- 3 files changed, 194 insertions(+), 71 deletions(-) diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index 8a29de65a..36be84cec 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -261,8 +261,7 @@ _cue_bench(void) gettimeofday(&b4, 0); { - ur_dict_t dic_u = {0}; - u3_noun out; + ur_cue_test_t *t = ur_cue_test_init(); c3_w len_w = u3r_met(3, vat); // XX assumes little-endian @@ -271,20 +270,17 @@ _cue_bench(void) ? (c3_y*)&vat : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; - ur_dict_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); - for ( i_w = 0; i_w < max_w; i_w++ ) { - ur_cue_test_unsafe(&dic_u, len_w, byt_y); - ur_dict_wipe(&dic_u); + ur_cue_test_with(t, len_w, byt_y); } - ur_dict_free(&dic_u); + ur_cue_test_done(t); } gettimeofday(&f2, 0); timersub(&f2, &b4, &d0); mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " cue test unsafe: %u ms\r\n", mil_w); + fprintf(stderr, " cue test with: %u ms\r\n", mil_w); } { diff --git a/pkg/urbit/include/ur/serial.h b/pkg/urbit/include/ur/serial.h index dde11ee67..677851f8a 100644 --- a/pkg/urbit/include/ur/serial.h +++ b/pkg/urbit/include/ur/serial.h @@ -29,28 +29,58 @@ ur_jam(ur_root_t *r, ur_nref ref, uint64_t *len, uint8_t **byt); ** supports up to 62-bits of bit-addressed input (511 PiB). ** returns [ur_cue_good] on success. ** -** unsafe variant is unsafe wrt its [dict] parameter, which must be empty, -** (present in order to skip reallocation inside hot loops). +** cue_with factors out stack/dict (re)allocation, +** for better performance of hot loops. ** -** test variant does not allocate nouns, but merely parses the input. +** cue_test does not allocate nouns, but merely parses the input; +** cue_test_with* api factors out stack/dict (re)allocation, +** for better performance of repeated tests. ** */ -ur_cue_res_e -ur_cue_unsafe(ur_root_t *r, - ur_dict64_t *dict, - uint64_t len, - const uint8_t *byt, - ur_nref *out); + +typedef struct ur_cue_test_s ur_cue_test_t; +typedef struct ur_cue_s ur_cue_t; ur_cue_res_e ur_cue(ur_root_t *r, uint64_t len, const uint8_t *byt, ur_nref *out); +ur_cue_t* +ur_cue_init_with(ur_root_t *r, + uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size); + +ur_cue_t* +ur_cue_init(ur_root_t *r); + ur_cue_res_e -ur_cue_test_unsafe(ur_dict_t *dict, - uint64_t len, - const uint8_t *byt); +ur_cue_with(ur_cue_t *c, + uint64_t len, + const uint8_t *byt, + ur_nref *out); + +void +ur_cue_done(ur_cue_t *c); ur_bool_t ur_cue_test(uint64_t len, const uint8_t *byt); +ur_cue_test_t* +ur_cue_test_init_with(uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size); + +ur_cue_test_t* +ur_cue_test_init(void); + +ur_bool_t +ur_cue_test_with(ur_cue_test_t *t, + uint64_t len, + const uint8_t *byt); + +void +ur_cue_test_done(ur_cue_test_t *t); + #endif diff --git a/pkg/urbit/ur/serial.c b/pkg/urbit/ur/serial.c index 7f922f539..dfe5dcb25 100644 --- a/pkg/urbit/ur/serial.c +++ b/pkg/urbit/ur/serial.c @@ -216,15 +216,25 @@ _cue_next(ur_root_t *r, } } -ur_cue_res_e -ur_cue_unsafe(ur_root_t *r, - ur_dict64_t *dict, - uint64_t len, - const uint8_t *byt, - ur_nref *out) +/* +** define opaque struct ur_cue_s (ie, ur_cue_t) +*/ +struct ur_cue_s { + ur_root_t *r; + _cue_stack_t s; + ur_dict64_t dict; +}; + +static ur_cue_res_e +_cue(ur_cue_t *c, + uint64_t len, + const uint8_t *byt, + ur_nref *out) { - ur_bsr_t bsr = {0}; - _cue_stack_t s = {0}; + ur_bsr_t bsr = {0}; + ur_root_t *r = c->r; + _cue_stack_t *s = &c->s; + ur_dict64_t *dict = &c->dict; ur_cue_res_e res; ur_nref ref; @@ -239,58 +249,99 @@ ur_cue_unsafe(ur_root_t *r, return ur_cue_meme; } - // setup stack - // - s.prev = ur_fib10; - s.size = ur_fib11; - s.f = _oom("cue stack", malloc(s.size * sizeof(*s.f))); - // advance into stream // - res = _cue_next(r, &s, &bsr, dict, &ref); + res = _cue_next(r, s, &bsr, dict, &ref); // process result // - while ( s.fill && (ur_cue_good == res) ) { + while ( s->fill && (ur_cue_good == res) ) { // peek at the top of the stack // - _cue_frame_t *f = &(s.f[s.fill - 1]); + _cue_frame_t *f = &(s->f[s->fill - 1]); // f is a head-frame; stash result and read the tail from the stream // if ( CUE_HEAD == f->ref ) { f->ref = ref; - res = _cue_next(r, &s, &bsr, dict, &ref); + res = _cue_next(r, s, &bsr, dict, &ref); } // f is a tail-frame; pop the stack and continue // else { ref = ur_cons(r, f->ref, ref); ur_dict64_put(r, dict, f->bits, (uint64_t)ref); - s.fill--; + s->fill--; } } - free(s.f); - if ( ur_cue_good == res ) { *out = ref; } return res; } +ur_cue_t* +ur_cue_init_with(ur_root_t *r, + uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size) +{ + ur_cue_t* c = _oom("cue_init", calloc(sizeof(*c), 1)); + c->r = r; + + ur_dict64_grow(r, &c->dict, d_prev, d_size); + + c->s.prev = s_prev; + c->s.size = s_size; + c->s.f = _oom("cue_test_init", malloc(s_size * sizeof(*c->s.f))); + + return c; +} + +ur_cue_t* +ur_cue_init(ur_root_t *r) +{ + return ur_cue_init_with(r, ur_fib11, ur_fib12, // dict sizes + ur_fib10, ur_fib11); // stack sizes +} + +ur_cue_res_e +ur_cue_with(ur_cue_t *c, + uint64_t len, + const uint8_t *byt, + ur_nref *out) +{ + ur_cue_res_e res = _cue(c, len, byt, out); + + // XX check size, shrink if above threshold + // + ur_dict64_wipe(&c->dict); + c->s.fill = 0; + + return res; +} + +void +ur_cue_done(ur_cue_t *c) +{ + + ur_dict_free((ur_dict_t*)&c->dict); + free(c->s.f); + free(c); +} + ur_cue_res_e ur_cue(ur_root_t *r, uint64_t len, const uint8_t *byt, ur_nref *out) { - ur_dict64_t dict = {0}; - ur_dict64_grow(r, &dict, ur_fib11, ur_fib12); + ur_cue_t *c = ur_cue_init(r); + ur_cue_res_e res = _cue(c, len, byt, out); - ur_cue_res_e res = ur_cue_unsafe(r, &dict, len, byt, out); - - ur_dict_free((ur_dict_t*)&dict); + ur_cue_done(c); return res; } @@ -378,14 +429,23 @@ _cue_test_next(_cue_test_stack_t *s, } } -ur_cue_res_e -ur_cue_test_unsafe(ur_dict_t *dict, - uint64_t len, - const uint8_t *byt) +/* +** define opaque struct ur_cue_test_s (ie, ur_cue_test_t) +*/ +struct ur_cue_test_s { + _cue_test_stack_t s; + ur_dict_t dict; +}; + +static ur_cue_res_e +_cue_test(ur_cue_test_t *t, + uint64_t len, + const uint8_t *byt) { - ur_bsr_t bsr = {0}; - _cue_test_stack_t s = {0}; - ur_cue_res_e res; + ur_bsr_t bsr = {0}; + _cue_test_stack_t *s = &t->s; + ur_dict_t *dict = &t->dict; + ur_cue_res_e res; // init bitstream-reader // @@ -398,50 +458,87 @@ ur_cue_test_unsafe(ur_dict_t *dict, return ur_cue_meme; } - // setup stack - // - s.prev = ur_fib10; - s.size = ur_fib11; - s.f = _oom("cue_test", malloc(s.size * sizeof(*s.f))); - // advance into stream // - res = _cue_test_next(&s, &bsr, dict); + res = _cue_test_next(s, &bsr, dict); // process result // - while ( s.fill && (ur_cue_good == res) ) { + while ( s->fill && (ur_cue_good == res) ) { // peek at the top of the stack // - _cue_test_frame_t *f = &(s.f[s.fill - 1]); + _cue_test_frame_t *f = &(s->f[s->fill - 1]); // f is a head-frame; stash result and read the tail from the stream // if ( !f->tal ) { f->tal = 1; - res = _cue_test_next(&s, &bsr, dict); + res = _cue_test_next(s, &bsr, dict); } // f is a tail-frame; pop the stack and continue // else { ur_dict_put((ur_root_t*)0, dict, f->bits); - s.fill--; + s->fill--; } } - free(s.f); - return res; } +ur_cue_test_t* +ur_cue_test_init_with(uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size) +{ + ur_cue_test_t* t = _oom("cue_test_init", calloc(sizeof(*t), 1)); + + ur_dict_grow((ur_root_t*)0, &t->dict, d_prev, d_size); + + t->s.prev = s_prev; + t->s.size = s_size; + t->s.f = _oom("cue_test_init", malloc(s_size * sizeof(*t->s.f))); + + return t; +} + +ur_cue_test_t* +ur_cue_test_init(void) +{ + return ur_cue_test_init_with(ur_fib11, ur_fib12, // dict sizes + ur_fib10, ur_fib11); // stack sizes +} + +ur_bool_t +ur_cue_test_with(ur_cue_test_t *t, + uint64_t len, + const uint8_t *byt) +{ + ur_bool_t ret = ur_cue_good == _cue_test(t, len, byt); + + // XX check size, shrink if above threshold + // + ur_dict_wipe(&t->dict); + t->s.fill = 0; + + return ret; +} + +void +ur_cue_test_done(ur_cue_test_t *t) +{ + ur_dict_free(&t->dict); + free(t->s.f); + free(t); +} + ur_bool_t ur_cue_test(uint64_t len, const uint8_t *byt) { - ur_dict_t dict = {0}; - ur_dict_grow((ur_root_t*)0, &dict, ur_fib11, ur_fib12); + ur_cue_test_t *t = ur_cue_test_init(); + ur_bool_t ret = ur_cue_good == _cue_test(t, len, byt); - ur_bool_t ret = ur_cue_good == ur_cue_test_unsafe(&dict, len, byt); - - ur_dict_free(&dict); + ur_cue_test_done(t); return ret; } From 6b10dd0f7e6b3ca2238f002d11e480c62ef850f0 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 15:59:18 -0700 Subject: [PATCH 04/23] ur: adds walk_fore variant with a handle-based api for repeated traversal --- pkg/urbit/include/ur/hashcons.h | 29 ++++++- pkg/urbit/ur/hashcons.c | 132 ++++++++++++++++++++++---------- 2 files changed, 116 insertions(+), 45 deletions(-) diff --git a/pkg/urbit/include/ur/hashcons.h b/pkg/urbit/include/ur/hashcons.h index c8a8e4ba5..ea047e13f 100644 --- a/pkg/urbit/include/ur/hashcons.h +++ b/pkg/urbit/include/ur/hashcons.h @@ -111,6 +111,11 @@ typedef struct ur_nvec_s { ur_nref* refs; } ur_nvec_t; +/* +** opaque handle for repeated traversal. +*/ +typedef struct ur_walk_fore_s ur_walk_fore_t; + /* ** type-specific dictionary operations. ** @@ -225,10 +230,28 @@ ur_nvec_free(ur_nvec_t *v); ** depth-first, pre-order noun traversal, cells can short-circuit. */ void -ur_walk_fore(ur_root_t *r, - ur_nref ref, - void *v, +ur_walk_fore(ur_root_t *r, + ur_nref ref, + void *v, void (*atom)(ur_root_t*, ur_nref, void*), ur_bool_t (*cell)(ur_root_t*, ur_nref, void*)); +ur_walk_fore_t* +ur_walk_fore_init_with(ur_root_t *r, + uint32_t s_prev, + uint32_t s_size); + +ur_walk_fore_t* +ur_walk_fore_init(ur_root_t *r); + +void +ur_walk_fore_with(ur_walk_fore_t *w, + ur_nref ref, + void *v, + void (*atom)(ur_root_t*, ur_nref, void*), + ur_bool_t (*cell)(ur_root_t*, ur_nref, void*)); + +void +ur_walk_fore_done(ur_walk_fore_t *w); + #endif diff --git a/pkg/urbit/ur/hashcons.c b/pkg/urbit/ur/hashcons.c index f00a8be5a..3360ed3e9 100644 --- a/pkg/urbit/ur/hashcons.c +++ b/pkg/urbit/ur/hashcons.c @@ -894,6 +894,93 @@ ur_nvec_init(ur_nvec_t *v, uint64_t size) v->refs = _oom("nvec_init", calloc(size, sizeof(ur_nref))); } +/* +** define opaque struct ur_walk_fore_s (ie, ur_walk_fore_t) +*/ +struct ur_walk_fore_s { + ur_root_t *r; + uint32_t prev; + uint32_t size; + uint32_t fill; + ur_nref *top; +}; + +ur_walk_fore_t* +ur_walk_fore_init_with(ur_root_t *r, + uint32_t s_prev, + uint32_t s_size) +{ + ur_walk_fore_t *w = _oom("walk_fore", malloc(sizeof(*w))); + w->top = _oom("walk_fore", malloc(s_size * sizeof(*w->top))); + w->prev = s_prev; + w->size = s_size; + w->fill = 0; + w->r = r; + + return w; +} + +ur_walk_fore_t* +ur_walk_fore_init(ur_root_t *r) +{ + return ur_walk_fore_init_with(r, ur_fib10, ur_fib11); +} + +void +ur_walk_fore_with(ur_walk_fore_t *w, + ur_nref ref, + void *v, + void (*atom)(ur_root_t*, ur_nref, void*), + ur_bool_t (*cell)(ur_root_t*, ur_nref, void*)) +{ + ur_root_t *r = w->r; + ur_nref *don = w->top; + + w->top += ++w->fill; + *w->top = ref; + + while ( w->top != don ) { + // visit atom, pop stack + // + if ( !ur_deep(ref) ) { + atom(r, ref, v); + w->top--; w->fill--; + } + // visit cell, pop stack if false + // + else if ( !cell(r, ref, v) ) { + w->top--; w->fill--; + } + // push the tail, continue into the head + // + else { + *w->top = ur_tail(r, ref); + + // reallocate "stack" if full + // + if ( w->size == w->fill ) { + uint32_t next = w->prev + w->size; + don = _oom("walk_fore", realloc(don, next * sizeof(*don))); + w->top = don + w->fill; + w->prev = w->size; + w->size = next; + } + + w->top++; w->fill++; + *w->top = ur_head(r, ref); + } + + ref = *w->top; + } +} + +void +ur_walk_fore_done(ur_walk_fore_t *w) +{ + free(w->top); + free(w); +} + void ur_walk_fore(ur_root_t *r, ur_nref ref, @@ -901,46 +988,7 @@ ur_walk_fore(ur_root_t *r, void (*atom)(ur_root_t*, ur_nref, void*), ur_bool_t (*cell)(ur_root_t*, ur_nref, void*)) { - uint64_t prev = ur_fib11, size = ur_fib12, fill = 0; - ur_nref *top, *don; - - don = _oom("walk_fore", malloc(size * sizeof(*don))); - top = don + ++fill; - *top = ref; - - while ( top != don ) { - // visit atom, pop stack - // - if ( !ur_deep(ref) ) { - atom(r, ref, v); - top--; fill--; - } - // visit cell, pop stack if false - // - else if ( !cell(r, ref, v) ) { - top--; fill--; - } - // push the tail, continue into the head - // - else { - *top = ur_tail(r, ref); - - // reallocate "stack" if full - // - if ( size == fill ) { - uint64_t next = prev + size; - don = _oom("walk_fore", realloc(don, next * sizeof(*don))); - top = don + fill; - prev = size; - size = next; - } - - top++; fill++; - *top = ur_head(r, ref); - } - - ref = *top; - } - - free(don); + ur_walk_fore_t *w = ur_walk_fore_init(r); + ur_walk_fore_with(w, ref, v, atom, cell); + ur_walk_fore_done(w); } From 8b5bc77565f729087cf121c25c69a869760921d0 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 16:17:00 -0700 Subject: [PATCH 05/23] ur: refactors unsafe jam into a handle-based api --- pkg/urbit/bench/ur_bench.c | 15 +++--- pkg/urbit/include/ur/serial.h | 30 ++++++++++-- pkg/urbit/ur/serial.c | 92 +++++++++++++++++++++++++---------- 3 files changed, 100 insertions(+), 37 deletions(-) diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index 36be84cec..a0cb7a433 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -117,25 +117,22 @@ _jam_bench(void) gettimeofday(&b4, 0); { - ur_dict64_t dic_u = {0}; - c3_d len_d; - c3_y* byt_y; - - ur_dict64_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); + ur_jam_t *jam_u = ur_jam_init(rot_u); + c3_d len_d; + c3_y* byt_y; for ( i_w = 0; i_w < max_w; i_w++ ) { - ur_jam_unsafe(rot_u, ref, &dic_u, &len_d, &byt_y); + ur_jam_with(jam_u, ref, &len_d, &byt_y); c3_free(byt_y); - ur_dict64_wipe(&dic_u); } - ur_dict_free((ur_dict_t*)&dic_u); + ur_jam_done(jam_u); } gettimeofday(&f2, 0); timersub(&f2, &b4, &d0); mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " jam cons unsafe: %u ms\r\n", mil_w); + fprintf(stderr, " jam cons with: %u ms\r\n", mil_w); } ur_root_free(rot_u); diff --git a/pkg/urbit/include/ur/serial.h b/pkg/urbit/include/ur/serial.h index 677851f8a..61e91daf9 100644 --- a/pkg/urbit/include/ur/serial.h +++ b/pkg/urbit/include/ur/serial.h @@ -10,10 +10,13 @@ ** supports up to 64-bits of bit-addressed output (nearly 2 EiB). ** (as this is an impractical volume data, cursor overflow is not checked.) ** -** unsafe variant is unsafe wrt its [dict] parameter, which must be empty, -** but can be passed in order to skip reallocation inside hot loops. +** jam_with* api factors out stack/dict (re)allocation, +** for better performance inside hot loops. ** */ + +typedef struct ur_jam_s ur_jam_t; + uint64_t ur_jam_unsafe(ur_root_t *r, ur_nref ref, @@ -22,7 +25,28 @@ ur_jam_unsafe(ur_root_t *r, uint8_t **byt); uint64_t -ur_jam(ur_root_t *r, ur_nref ref, uint64_t *len, uint8_t **byt); +ur_jam(ur_root_t *r, + ur_nref ref, + uint64_t *len, + uint8_t **byt); + +ur_jam_t* +ur_jam_init_with(ur_root_t *r, + uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size); + +ur_jam_t* +ur_jam_init(ur_root_t *r); + +uint64_t +ur_jam_with(ur_jam_t *j, + ur_nref ref, + uint64_t *len, + uint8_t **byt); +void +ur_jam_done(ur_jam_t *j); /* ** bitwise deserialization of a byte-buffer into a noun. diff --git a/pkg/urbit/ur/serial.c b/pkg/urbit/ur/serial.c index dfe5dcb25..61eeca39c 100644 --- a/pkg/urbit/ur/serial.c +++ b/pkg/urbit/ur/serial.c @@ -30,16 +30,21 @@ _bsw_atom(ur_root_t *r, ur_nref ref, ur_bsw_t *bsw, uint64_t len) } } -typedef struct _jam_s { - ur_dict64_t *dict; +/* +** define opaque struct ur_jam_s (ie, ur_jam_t) +*/ +struct ur_jam_s { + ur_root_t *r; + ur_walk_fore_t *w; + ur_dict64_t dict; ur_bsw_t bsw; -} _jam_t; +}; static void _jam_atom(ur_root_t *r, ur_nref ref, void *ptr) { - _jam_t *j = ptr; - ur_dict64_t *dict = j->dict; + ur_jam_t *j = ptr; + ur_dict64_t *dict = &j->dict; ur_bsw_t *bsw = &j->bsw; uint64_t bak, len = ur_met(r, 0, ref); @@ -63,8 +68,8 @@ _jam_atom(ur_root_t *r, ur_nref ref, void *ptr) static ur_bool_t _jam_cell(ur_root_t *r, ur_nref ref, void *ptr) { - _jam_t *j = ptr; - ur_dict64_t *dict = j->dict; + ur_jam_t *j = ptr; + ur_dict64_t *dict = &j->dict; ur_bsw_t *bsw = &j->bsw; uint64_t bak; @@ -80,32 +85,69 @@ _jam_cell(ur_root_t *r, ur_nref ref, void *ptr) } } -uint64_t -ur_jam_unsafe(ur_root_t *r, - ur_nref ref, - ur_dict64_t *dict, - uint64_t *len, - uint8_t **byt) +static uint64_t +_jam(ur_jam_t *j, + ur_nref ref, + uint64_t *len, + uint8_t **byt) { - _jam_t j = { .dict = dict }; - ur_bsw_init(&j.bsw, ur_fib11, ur_fib12); + ur_bsw_init(&j->bsw, ur_fib11, ur_fib12); + ur_walk_fore_with(j->w, ref, j, _jam_atom, _jam_cell); + return ur_bsw_done(&j->bsw, len, byt); +} - ur_walk_fore(r, ref, &j, _jam_atom, _jam_cell); +ur_jam_t* +ur_jam_init_with(ur_root_t *r, + uint64_t d_prev, + uint64_t d_size, + uint32_t s_prev, + uint32_t s_size) +{ + ur_jam_t *j = _oom("jam_init", calloc(sizeof(*j), 1)); + j->w = ur_walk_fore_init_with(r, s_prev, s_size); + j->r = r; - return ur_bsw_done(&j.bsw, len, byt); + ur_dict64_grow(r, &j->dict, d_prev, d_size); + + return j; +} + +ur_jam_t* +ur_jam_init(ur_root_t *r) +{ + return ur_jam_init_with(r, ur_fib11, ur_fib12, // dict sizes + ur_fib10, ur_fib11); // stack sizes } uint64_t -ur_jam(ur_root_t *r, ur_nref ref, uint64_t *len, uint8_t **byt) +ur_jam_with(ur_jam_t *j, + ur_nref ref, + uint64_t *len, + uint8_t **byt) { - ur_dict64_t dict = {0}; - ur_dict64_grow(r, &dict, ur_fib11, ur_fib12); + uint64_t bits = _jam(j, ref, len, byt); + ur_dict64_wipe(&j->dict); + return bits; +} - { - uint64_t bits = ur_jam_unsafe(r, ref, &dict, len, byt); - ur_dict_free((ur_dict_t*)&dict); - return bits; - } +void +ur_jam_done(ur_jam_t *j) +{ + ur_dict_free((ur_dict_t*)&j->dict); + free(j->w); + free(j); +} + +uint64_t +ur_jam(ur_root_t *r, + ur_nref ref, + uint64_t *len, + uint8_t **byt) +{ + ur_jam_t *j = ur_jam_init(r); + uint64_t bits = _jam(j, ref, len, byt); + ur_jam_done(j); + return bits; } /* From bf20b93e4da8d3e2501368e10d833b1e7591db1b Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 22:01:41 -0700 Subject: [PATCH 06/23] ur: cleans up ur_met(), atom measurement --- pkg/urbit/ur/hashcons.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pkg/urbit/ur/hashcons.c b/pkg/urbit/ur/hashcons.c index 3360ed3e9..71f2568f9 100644 --- a/pkg/urbit/ur/hashcons.c +++ b/pkg/urbit/ur/hashcons.c @@ -526,15 +526,12 @@ ur_met(ur_root_t *r, uint8_t bloq, ur_nref ref) case 0: return m_bit; case 1: return ur_bloq_up1(m_bit); case 2: return ur_bloq_up2(m_bit); + case 3: return ur_bloq_up3(m_bit); - { + default: { uint64_t m_byt = ur_bloq_up3(m_bit); - - case 3: return m_byt; - default: { - uint8_t off = (bloq - 3); - return (m_byt + ((1ULL << off) - 1)) >> off; - } + uint8_t off = (bloq - 3); + return (m_byt + ((1ULL << off) - 1)) >> off; } } } From bc3c1eb0c7d4aa0d149f0ac32577824e946775c3 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 22:44:13 -0700 Subject: [PATCH 07/23] ur: cleans up ur_bsr_log() --- pkg/urbit/ur/bitstream.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pkg/urbit/ur/bitstream.c b/pkg/urbit/ur/bitstream.c index 146f5e33d..dfc42393b 100644 --- a/pkg/urbit/ur/bitstream.c +++ b/pkg/urbit/ur/bitstream.c @@ -615,7 +615,6 @@ ur_bsr_log(ur_bsr_t *bsr, uint8_t *out) } else { uint8_t off = bsr->off; - uint8_t rest = 8 - off; const uint8_t *b = bsr->bytes; uint8_t byt = b[0] >> off; uint8_t skip = 0; @@ -625,13 +624,11 @@ ur_bsr_log(ur_bsr_t *bsr, uint8_t *out) return _bsr_log_meme(bsr); } - skip++; + byt = b[++skip]; if ( skip == left ) { return _bsr_set_gone(bsr, (skip << 3) - off); } - - byt = b[skip]; } { @@ -646,10 +643,10 @@ ur_bsr_log(ur_bsr_t *bsr, uint8_t *out) left -= bytes; - bsr->bytes = left ? (b + bytes) : 0; - bsr->bits += 1 + zeros; - bsr->left = left; - bsr->off = ur_mask_3(bits); + bsr->bytes = left ? (b + bytes) : 0; + bsr->bits += 1 + zeros; + bsr->left = left; + bsr->off = ur_mask_3(bits); *out = zeros; return ur_cue_good; From 6ef6acbddcb7f6a8af0ba9d044be3a3bf5f1d7f3 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 22:44:40 -0700 Subject: [PATCH 08/23] ur: removes unused variables in tests --- pkg/urbit/tests/ur_tests.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/urbit/tests/ur_tests.c b/pkg/urbit/tests/ur_tests.c index f8d6ae1e0..1e590e572 100644 --- a/pkg/urbit/tests/ur_tests.c +++ b/pkg/urbit/tests/ur_tests.c @@ -501,8 +501,8 @@ _test_bsw_bex() int ret = 1; ur_bsw_t a = {0}; ur_bsw_t b = {0}; - uint8_t i, l; - uint32_t j, k; + uint8_t i; + uint32_t j; for ( i = 0; i < 8; i++) { for ( j = 0; j < 256; j++ ) { @@ -1363,7 +1363,7 @@ _test_bsr_skip_any_loop(const char *cap, uint8_t len, uint8_t val) uint64_t max = (len << 3) + 7; ur_bsr_t a, b; uint8_t *bytes, *c; - uint8_t i, j, k; + uint8_t i, j; c = malloc(1 + len); bytes = malloc(len); @@ -1510,7 +1510,7 @@ _test_bsr_log_loop(const char *cap, uint8_t len, uint8_t val) int ret = 1; ur_bsr_t a, b; uint8_t *bytes, c, d; - uint8_t i, j, k; + uint8_t i, j; ur_cue_res_e e, f; bytes = malloc(len); @@ -1602,7 +1602,7 @@ _test_bsr_tag_loop(const char *cap, uint8_t len, uint8_t val) ur_bsr_t a, b; uint8_t *bytes; ur_cue_tag_e c, d; - uint8_t i, j, k; + uint8_t i, j; ur_cue_res_e e, f; bytes = malloc(len); From 81e38c7b72bb166e0c7ba732c33599f144a79e8f Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 16:30:42 -0700 Subject: [PATCH 09/23] u3: refactors u3s_cue_bytes() to use road-stack api --- pkg/urbit/noun/serial.c | 99 ++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 61 deletions(-) diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index 15c946699..d22ca29d0 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -788,13 +788,12 @@ _cs_cue_put(u3p(u3h_root) har_p, c3_d key_d, u3_noun val) return val; } -/* _cs_cue_full_next(): read next value from bitstream. +/* _cs_cue_bytes_next(): read next value from bitstream. */ static inline u3_noun -_cs_cue_full_next(c3_ys mov, - c3_ys off, - u3p(u3h_root) har_p, - ur_bsr_t* red_u) +_cs_cue_bytes_next(u3a_pile* pil_u, + u3p(u3h_root) har_p, + ur_bsr_t* red_u) { while ( 1 ) { c3_d len_d, bit_d = red_u->bits; @@ -806,31 +805,11 @@ _cs_cue_full_next(c3_ys mov, default: c3_assert(0); case ur_jam_cell: { - // wind the stack - // - u3R->cap_p += mov; + _cue_frame_t* fam_u = u3a_push(pil_u); + u3a_pile_sane(pil_u); - // ensure we haven't overflowed (ie, run into the heap) - // (off==0 means we're on a north road) - // - if ( 0 == off ) { - if( !(u3R->cap_p > u3R->hat_p) ) { - u3m_bail(c3__meme); - } - } - else { - if( !(u3R->cap_p < u3R->hat_p) ) { - u3m_bail(c3__meme); - } - } - - // save a head-frame and read the head from the stream - // - { - _cue_frame_t* fam_u = u3to(_cue_frame_t, u3R->cap_p + off); - fam_u->ref = u3_none; - fam_u->bit_d = bit_d; - } + fam_u->ref = u3_none; + fam_u->bit_d = bit_d; continue; } @@ -889,23 +868,19 @@ _cs_cue_full_next(c3_ys mov, u3_noun u3s_cue_bytes(c3_d len_d, const c3_y* byt_y) { - ur_bsr_t red_u = {0}; - u3_noun ref; + ur_bsr_t red_u = {0}; + u3a_pile pil_u; + _cue_frame_t* fam_u; + u3p(u3h_root) har_p; + u3_noun ref; + + // initialize stack control + // + u3a_pile_prep(&pil_u, sizeof(*fam_u)); // initialize a hash table for dereferencing backrefs // - u3p(u3h_root) har_p = u3h_new(); - const u3_post top_p = u3R->cap_p; - - // initialize signed stack offsets (relative to north/south road) - // - c3_ys mov, off; - { - c3_o nor_o = u3a_is_north(u3R); - c3_y wis_y = c3_wiseof(_cue_frame_t); - mov = ( c3y == nor_o ? -wis_y : wis_y ); - off = ( c3y == nor_o ? 0 : -wis_y ); - } + har_p = u3h_new(); // init bitstream-reader // @@ -919,28 +894,30 @@ u3s_cue_bytes(c3_d len_d, const c3_y* byt_y) // advance into stream // - ref = _cs_cue_full_next(mov, off, har_p, &red_u); + ref = _cs_cue_bytes_next(&pil_u, har_p, &red_u); - // process result + // process cell results // - while ( top_p != u3R->cap_p ) { - // peek at the top of the stack - // - _cue_frame_t* fam_u = u3to(_cue_frame_t, u3R->cap_p + off); + if ( c3n == u3a_pile_done(&pil_u) ) { + fam_u = u3a_peek(&pil_u); - // f is a head-frame; stash result and read the tail from the stream - // - if ( u3_none == fam_u->ref ) { - fam_u->ref = ref; - ref = _cs_cue_full_next(mov, off, har_p, &red_u); - } - // f is a tail-frame; pop the stack and continue - // - else { - ref = u3nc(fam_u->ref, ref); - _cs_cue_put(har_p, fam_u->bit_d, ref); - u3R->cap_p -= mov; + do { + // f is a head-frame; stash result and read the tail from the stream + // + if ( u3_none == fam_u->ref ) { + fam_u->ref = ref; + ref = _cs_cue_bytes_next(&pil_u, har_p, &red_u); + fam_u = u3a_peek(&pil_u); + } + // f is a tail-frame; pop the stack and continue + // + else { + ref = u3nc(fam_u->ref, ref); + _cs_cue_put(har_p, fam_u->bit_d, ref); + fam_u = u3a_pop(&pil_u); + } } + while ( c3n == u3a_pile_done(&pil_u) ); } u3h_free(har_p); From 55c4fa2079f5b18272fe1bb41da41ee5e4c37415 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 18:07:34 -0700 Subject: [PATCH 10/23] u3: factors atoms/backrefs out of u3s_cue_xeno --- pkg/urbit/noun/serial.c | 133 ++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 52 deletions(-) diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index d22ca29d0..e6210ba4b 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -532,6 +532,82 @@ u3s_cue(u3_atom a) return pro; } +/* _cs_cue_xeno_back(): cue a backref, off-loom dictionary. +*/ +static inline ur_cue_res_e +_cs_cue_xeno_back(ur_bsr_t* red_u, + ur_dict32_t* dic_u, + u3_noun* out) +{ + ur_root_t* rot_u = 0; + ur_cue_res_e res_e; + c3_d len_d; + + if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { + return res_e; + } + else if ( 62 < len_d ) { + return ur_cue_meme; + } + else { + c3_d bak_d = ur_bsr64_any(red_u, len_d); + c3_w bak_w; + + if ( !ur_dict32_get(rot_u, dic_u, bak_d, &bak_w) ) { + return ur_cue_back; + } + + *out = u3k((u3_noun)bak_w); + return ur_cue_good; + } +} + +/* _cs_cue_xeno_atom(): cue an atom, off-loom dictionary. +*/ +static inline ur_cue_res_e +_cs_cue_xeno_atom(ur_bsr_t* red_u, + ur_dict32_t* dic_u, + c3_d bit_d, + u3_noun* out) +{ + ur_root_t* rot_u = 0; + ur_cue_res_e res_e; + c3_d len_d; + + if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { + return res_e; + } + + if ( 31 >= len_d ) { + *out = (u3_noun)ur_bsr32_any(red_u, len_d); + } + // XX need a ur_bsr_words_any() + // + else { + c3_w* wor_w; + c3_y* byt_y; + + { + c3_d byt_d = (len_d >> 3) + !!ur_mask_3(len_d); + + if ( 0xffffffffULL < byt_d) { + return u3m_bail(c3__meme); + } + + // XX assumes little-endian + // + wor_w = u3a_slaq(3, byt_d); + byt_y = (c3_y*)wor_w; + } + + ur_bsr_bytes_any(red_u, len_d, byt_y); + *out = u3a_malt(wor_w); + } + + ur_dict32_put(rot_u, dic_u, bit_d, *out); + return ur_cue_good; +} + /* ** stack frame for recording head vs tail iteration ** @@ -543,6 +619,8 @@ typedef struct _cue_frame_s { c3_d bit_d; } _cue_frame_t; +/* _cue_stack_t: heap-allocated struct, used to bypass the road stack. +*/ typedef struct _cue_stack_s { c3_w pre_w; c3_w siz_w; @@ -558,10 +636,8 @@ _cs_cue_xeno_next(_cue_stack_t* tac_u, ur_dict32_t* dic_u, u3_noun* out) { - ur_root_t* rot_u = 0; - while ( 1 ) { - c3_d len_d, bit_d = red_u->bits; + c3_d bit_d = red_u->bits; ur_cue_tag_e tag_e; ur_cue_res_e res_e; @@ -593,58 +669,11 @@ _cs_cue_xeno_next(_cue_stack_t* tac_u, } case ur_jam_back: { - if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { - return res_e; - } - else if ( 62 < len_d ) { - return ur_cue_meme; - } - else { - c3_d bak_d = ur_bsr64_any(red_u, len_d); - c3_w bak_w; - - if ( !ur_dict32_get(rot_u, dic_u, bak_d, &bak_w) ) { - return ur_cue_back; - } - - *out = u3k((u3_noun)bak_w); - return ur_cue_good; - } + return _cs_cue_xeno_back(red_u, dic_u, out); } case ur_jam_atom: { - if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { - return res_e; - } - - if ( 31 >= len_d ) { - *out = (u3_noun)ur_bsr32_any(red_u, len_d); - } - // XX need a ur_bsr_words_any() - // - else { - c3_w* wor_w; - c3_y* byt_y; - - { - c3_d byt_d = (len_d >> 3) + !!ur_mask_3(len_d); - - if ( 0xffffffffULL < byt_d) { - return u3m_bail(c3__meme); - } - - // XX assumes little-endian - // - wor_w = u3a_slaq(3, byt_d); - byt_y = (c3_y*)wor_w; - } - - ur_bsr_bytes_any(red_u, len_d, byt_y); - *out = u3a_malt(wor_w); - } - - ur_dict32_put(rot_u, dic_u, bit_d, *out); - return ur_cue_good; + return _cs_cue_xeno_atom(red_u, dic_u, bit_d, out); } } } From bf117f63a8845be7727578734e2ceecca81f1185 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Sep 2020 22:00:42 -0700 Subject: [PATCH 11/23] u3: adds u3s_cue_fill and handle-based api --- pkg/urbit/bench/ur_bench.c | 48 ++++++++ pkg/urbit/include/noun/serial.h | 34 ++++++ pkg/urbit/noun/serial.c | 202 +++++++++++++++++++++++++++++++- pkg/urbit/tests/jam_tests.c | 17 +++ 4 files changed, 295 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index a0cb7a433..c97fecfc1 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -177,6 +177,54 @@ _cue_bench(void) fprintf(stderr, " cue atom: %u ms\r\n", mil_w); } + { + gettimeofday(&b4, 0); + + { + c3_w len_w = u3r_met(3, vat); + // XX assumes little-endian + // + c3_y* byt_y = ( c3y == u3a_is_cat(vat) ) + ? (c3_y*)&vat + : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3z(u3s_cue_sill(len_w, byt_y)); + } + } + + gettimeofday(&f2, 0); + timersub(&f2, &b4, &d0); + mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); + fprintf(stderr, " cue sill: %u ms\r\n", mil_w); + } + + { + gettimeofday(&b4, 0); + + { + u3_cue_sill* sil_u = u3s_cue_sill_init(); + + c3_w len_w = u3r_met(3, vat); + // XX assumes little-endian + // + c3_y* byt_y = ( c3y == u3a_is_cat(vat) ) + ? (c3_y*)&vat + : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3z(u3s_cue_sill_with(sil_u, len_w, byt_y)); + } + + u3s_cue_sill_done(sil_u); + } + + gettimeofday(&f2, 0); + timersub(&f2, &b4, &d0); + mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); + fprintf(stderr, " cue sill with: %u ms\r\n", mil_w); + } + { gettimeofday(&b4, 0); diff --git a/pkg/urbit/include/noun/serial.h b/pkg/urbit/include/noun/serial.h index f7a06aa4a..b721d9c5a 100644 --- a/pkg/urbit/include/noun/serial.h +++ b/pkg/urbit/include/noun/serial.h @@ -1,6 +1,12 @@ /* i/n/serial.h ** */ + /* opaque handles + */ + /* u3_cue_sill: handle for cue-ing with an off-loom dictionary. + */ + typedef struct _u3_cue_sill u3_cue_sill; + /* forward declarations */ /* ur_dict32_s: off-loom 32-bit dictionary. @@ -28,6 +34,34 @@ u3_noun u3s_cue(u3_atom a); + /* u3s_cue_sill_init_with(): initialize a cue_sill handle as specified. + */ + u3_cue_sill* + u3s_cue_sill_init_with(c3_d pre_d, c3_d siz_d); + + /* u3s_cue_sill_init(): initialize a cue_sill handle. + */ + u3_cue_sill* + u3s_cue_sill_init(void); + + /* u3s_cue_sill_init(): cue on-loom, with off-loom dictionary in handle. + */ + u3_weak + u3s_cue_sill_with(u3_cue_sill* sil_u, + c3_d len_d, + const c3_y* byt_y); + + /* u3s_cue_sill_init(): dispose cue_sill handle. + */ + void + u3s_cue_sill_done(u3_cue_sill* sil_u); + + /* u3s_cue_sill(): cue on-loom, with off-loom dictionary. + */ + u3_weak + u3s_cue_sill(c3_d len_d, + const c3_y* byt_y); + /* u3s_cue_xeno_unsafe(): cue onto the loom, all bookkeeping off-loom. */ c3_o diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index e6210ba4b..8bde730ab 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -532,10 +532,10 @@ u3s_cue(u3_atom a) return pro; } -/* _cs_cue_xeno_back(): cue a backref, off-loom dictionary. +/* _cs_cue_sill_back(): cue a backref, off-loom dictionary. */ static inline ur_cue_res_e -_cs_cue_xeno_back(ur_bsr_t* red_u, +_cs_cue_sill_back(ur_bsr_t* red_u, ur_dict32_t* dic_u, u3_noun* out) { @@ -562,10 +562,10 @@ _cs_cue_xeno_back(ur_bsr_t* red_u, } } -/* _cs_cue_xeno_atom(): cue an atom, off-loom dictionary. +/* _cs_cue_sill_atom(): cue an atom, off-loom dictionary. */ static inline ur_cue_res_e -_cs_cue_xeno_atom(ur_bsr_t* red_u, +_cs_cue_sill_atom(ur_bsr_t* red_u, ur_dict32_t* dic_u, c3_d bit_d, u3_noun* out) @@ -619,6 +619,196 @@ typedef struct _cue_frame_s { c3_d bit_d; } _cue_frame_t; +/* _cs_cue_sill_next(): read next value from bitstream, dictionary off-loom. +** NB: this is _cs_cue_xeno_next, using the road stack. +*/ +static inline ur_cue_res_e +_cs_cue_sill_next(u3a_pile* pil_u, + ur_bsr_t* red_u, + ur_dict32_t* dic_u, + u3_noun* out) +{ + while ( 1 ) { + c3_d bit_d = red_u->bits; + ur_cue_tag_e tag_e; + ur_cue_res_e res_e; + + if ( ur_cue_good != (res_e = ur_bsr_tag(red_u, &tag_e)) ) { + return res_e; + } + + switch ( tag_e ) { + default: c3_assert(0); + + case ur_jam_cell: { + _cue_frame_t* fam_u = u3a_push(pil_u); + u3a_pile_sane(pil_u); + + fam_u->ref = u3_none; + fam_u->bit_d = bit_d; + continue; + } + + case ur_jam_back: { + return _cs_cue_sill_back(red_u, dic_u, out); + } + + case ur_jam_atom: { + return _cs_cue_sill_atom(red_u, dic_u, bit_d, out); + } + } + } +} + +struct _u3_cue_sill { + ur_dict32_t dic_u; +}; + +/* _cs_cue_sill(): cue on-loom, with off-loom dictionary in handle. +*/ +static u3_weak +_cs_cue_sill(u3_cue_sill* sil_u, + c3_d len_d, + const c3_y* byt_y) +{ + ur_bsr_t red_u = {0}; + ur_dict32_t* dic_u = &sil_u->dic_u; + u3a_pile pil_u; + _cue_frame_t* fam_u; + ur_cue_res_e res_e; + u3_noun ref; + + // initialize stack control + // + u3a_pile_prep(&pil_u, sizeof(*fam_u)); + + // init bitstream-reader + // + if ( ur_cue_good != (res_e = ur_bsr_init(&red_u, len_d, byt_y)) ) { + return c3n; + } + // bit-cursor (and backreferences) must fit in 62-bit direct atoms + // + else if ( 0x7ffffffffffffffULL < len_d ) { + return c3n; + } + + // advance into stream + // + res_e = _cs_cue_sill_next(&pil_u, &red_u, dic_u, &ref); + + // process cell results + // + if ( (c3n == u3a_pile_done(&pil_u)) + && (ur_cue_good == res_e) ) + { + fam_u = u3a_peek(&pil_u); + + do { + // f is a head-frame; stash result and read the tail from the stream + // + if ( u3_none == fam_u->ref ) { + fam_u->ref = ref; + res_e = _cs_cue_sill_next(&pil_u, &red_u, dic_u, &ref); + fam_u = u3a_peek(&pil_u); + } + // f is a tail-frame; pop the stack and continue + // + else { + ur_root_t* rot_u = 0; + + ref = u3nc(fam_u->ref, ref); + ur_dict32_put(rot_u, dic_u, fam_u->bit_d, ref); + fam_u = u3a_pop(&pil_u); + } + } + while ( (c3n == u3a_pile_done(&pil_u)) + && (ur_cue_good == res_e) ); + } + + if ( ur_cue_good == res_e ) { + return ref; + } + // on failure, unwind the stack and dispose of intermediate nouns + // + else if ( c3n == u3a_pile_done(&pil_u) ) { + do { + if ( u3_none != fam_u->ref ) { + u3z(fam_u->ref); + } + fam_u = u3a_pop(&pil_u); + } + while ( c3n == u3a_pile_done(&pil_u) ); + } + + return u3_none; +} + +/* u3s_cue_sill_init_with(): initialize a cue_sill handle as specified. +*/ +u3_cue_sill* +u3s_cue_sill_init_with(c3_d pre_d, c3_d siz_d) +{ + u3_cue_sill* sil_u; + + c3_assert( &(u3H->rod_u) == u3R ); + + sil_u = c3_calloc(sizeof(*sil_u)); + ur_dict32_grow((ur_root_t*)0, &sil_u->dic_u, pre_d, siz_d); + + return sil_u; +} + +/* u3s_cue_sill_init(): initialize a cue_sill handle. +*/ +u3_cue_sill* +u3s_cue_sill_init(void) +{ + return u3s_cue_sill_init_with(ur_fib10, ur_fib11); +} + +/* u3s_cue_sill_init(): cue on-loom, with off-loom dictionary in handle. +*/ +u3_weak +u3s_cue_sill_with(u3_cue_sill* sil_u, + c3_d len_d, + const c3_y* byt_y) +{ + u3_weak som; + + c3_assert( &(u3H->rod_u) == u3R ); + + som = _cs_cue_sill(sil_u, len_d, byt_y); + ur_dict32_wipe(&sil_u->dic_u); + return som; +} + +/* u3s_cue_sill_init(): dispose cue_sill handle. +*/ +void +u3s_cue_sill_done(u3_cue_sill* sil_u) +{ + ur_dict_free((ur_dict_t*)&sil_u->dic_u); + c3_free(sil_u); +} + +/* u3s_cue_sill(): cue on-loom, with off-loom dictionary. +*/ +u3_weak +u3s_cue_sill(c3_d len_d, + const c3_y* byt_y) +{ + u3_cue_sill* sil_u; + u3_weak som; + + c3_assert( &(u3H->rod_u) == u3R ); + + sil_u = u3s_cue_sill_init(); + som = _cs_cue_sill(sil_u, len_d, byt_y); + u3s_cue_sill_done(sil_u); + return som; +} + /* _cue_stack_t: heap-allocated struct, used to bypass the road stack. */ typedef struct _cue_stack_s { @@ -669,11 +859,11 @@ _cs_cue_xeno_next(_cue_stack_t* tac_u, } case ur_jam_back: { - return _cs_cue_xeno_back(red_u, dic_u, out); + return _cs_cue_sill_back(red_u, dic_u, out); } case ur_jam_atom: { - return _cs_cue_xeno_atom(red_u, dic_u, bit_d, out); + return _cs_cue_sill_atom(red_u, dic_u, bit_d, out); } } } diff --git a/pkg/urbit/tests/jam_tests.c b/pkg/urbit/tests/jam_tests.c index 41e5d767b..842c0d893 100644 --- a/pkg/urbit/tests/jam_tests.c +++ b/pkg/urbit/tests/jam_tests.c @@ -407,6 +407,23 @@ _test_cue_spec(const c3_c* cap_c, u3z(pro); } + { + u3_noun out; + + if ( u3_none == (out = u3s_cue_sill(len_w, byt_y)) ) { + fprintf(stderr, "\033[31mcue %s fail 5\033[0m\r\n", cap_c); + ret_i = 0; + } + else if ( c3n == u3r_sing(ref, out) ) { + fprintf(stderr, "\033[31mcue %s fail 6\033[0m\r\n", cap_c); + u3m_p("ref", ref); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + } + return ret_i; } From fe0169559421cb91706a2a52ebbe61384fec0b76 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 11:22:36 -0700 Subject: [PATCH 12/23] u3: use u3s_cue_sill_with() in u3u_uncram() --- pkg/urbit/noun/urth.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pkg/urbit/noun/urth.c b/pkg/urbit/noun/urth.c index 876e2d5dc..04b84bc44 100644 --- a/pkg/urbit/noun/urth.c +++ b/pkg/urbit/noun/urth.c @@ -860,23 +860,20 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d) // XX errors are fatal, barring a full "u3m_reboot"-type operation. // { - ur_dict32_t dic_u = {0}; - u3_noun roc, cod, ref; - // XX tune the initial dictionary size for less reallocation // - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib33, ur_fib34); + u3_cue_sill* sil_u = u3s_cue_sill_init_with(ur_fib33, ur_fib34); + u3_weak ref = u3s_cue_sill_with(sil_u, len_d, byt_y); + u3_noun roc, cod; - if ( c3n == u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, &ref) ) { + u3s_cue_sill_done(sil_u); + + if ( u3_none == ref ) { fprintf(stderr, "uncram: failed to cue rock\r\n"); - ur_dict_free((ur_dict_t*)&dic_u); c3_free(nam_c); return c3n; } - - ur_dict_free((ur_dict_t*)&dic_u); - - if ( c3n == u3r_pq(ref, c3__fast, &roc, &cod) ) { + else if ( c3n == u3r_pq(ref, c3__fast, &roc, &cod) ) { fprintf(stderr, "uncram: failed: invalid rock format\r\n"); u3z(ref); c3_free(nam_c); From a79a0e943733a57bfd69d7345ba4c1766bd336e8 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 11:23:12 -0700 Subject: [PATCH 13/23] serf: use u3s_cue_sill() for ipc $writ's --- pkg/urbit/worker/main.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index 536e46342..fe8bdaf4c 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -24,10 +24,10 @@ #include "ur/hashcons.h" -static u3_serf u3V; // one serf per process -static u3_moat inn_u; // input stream -static u3_mojo out_u; // output stream -static ur_dict32_t dic_u; // cue dictionary +static u3_serf u3V; // one serf per process +static u3_moat inn_u; // input stream +static u3_mojo out_u; // output stream +static u3_cue_sill* sil_u; // cue handle #undef SERF_TRACE_JAM #undef SERF_TRACE_CUE @@ -107,8 +107,8 @@ _cw_serf_step_trace(void) static void _cw_serf_writ(void* vod_p, c3_d len_d, c3_y* byt_y) { - u3_noun ret, jar; - c3_o ret_o; + u3_weak jar; + u3_noun ret; _cw_serf_step_trace(); @@ -116,16 +116,13 @@ _cw_serf_writ(void* vod_p, c3_d len_d, c3_y* byt_y) u3t_event_trace("serf ipc cue", 'B'); #endif - ret_o = u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, &jar); - // XX check if the dictionary grew too much and shrink? - // - ur_dict32_wipe(&dic_u); + jar = u3s_cue_sill_with(sil_u, len_d, byt_y); #ifdef SERF_TRACE_CUE u3t_event_trace("serf ipc cue", 'E'); #endif - if ( (c3n == ret_o) + if ( (u3_none == jar) || (c3n == u3_serf_writ(&u3V, jar, &ret)) ) { _cw_serf_fail(0, -1, "bad jar"); @@ -165,7 +162,7 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i) static void _cw_serf_exit(void) { - ur_dict_free((ur_dict_t*)&dic_u); + u3s_cue_sill_done(sil_u); u3t_trace_close(); } @@ -239,7 +236,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) uv_stream_set_blocking((uv_stream_t*)&out_u.pyp_u, 1); } - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); + sil_u = u3s_cue_sill_init(); // set up writing // From 830df0d86ead4056c9e4ef320b8d7169c113ead5 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 11:24:02 -0700 Subject: [PATCH 14/23] vere: use u3s_cue_sill for ipc $plea's --- pkg/urbit/include/vere/vere.h | 2 +- pkg/urbit/vere/lord.c | 25 ++++++++++--------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 516a1319b..e92a74044 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -470,7 +470,7 @@ uv_process_t cub_u; // process handle uv_process_options_t ops_u; // process configuration uv_stdio_container_t cod_u[3]; // process options - void* dic_u; // cue dictionary + u3_cue_sill* sil_u; // cue handle time_t wen_t; // process creation time u3_mojo inn_u; // client's stdin u3_moat out_u; // client's stdout diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index 9d5f5c37c..dd7b3224e 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -74,7 +74,7 @@ _lord_stop_cb(void* ptr_v, void (*exit_f)(void*) = god_u->cb_u.exit_f; void* exit_v = god_u->cb_u.ptr_v; - ur_dict_free((ur_dict_t*)god_u->dic_u); + u3s_cue_sill_done(god_u->sil_u); c3_free(god_u); if ( exit_f ) { @@ -674,27 +674,24 @@ _lord_plea_work(u3_lord* god_u, u3_noun dat) static void _lord_on_plea(void* ptr_v, c3_d len_d, c3_y* byt_y) { - u3_lord* god_u = ptr_v; - ur_dict32_t* dic_u = god_u->dic_u; - u3_noun tag, dat, jar = u3_blip; - c3_o ret_o; + u3_lord* god_u = ptr_v; + u3_noun tag, dat; + u3_weak jar; #ifdef LORD_TRACE_CUE u3t_event_trace("king ipc cue", 'B'); #endif - ret_o = u3s_cue_xeno_unsafe(dic_u, len_d, byt_y, &jar); - // XX check if the dictionary grew too much and shrink? - // - ur_dict32_wipe(dic_u); + jar = u3s_cue_sill_with(god_u->sil_u, len_d, byt_y); #ifdef LORD_TRACE_CUE u3t_event_trace("king ipc cue", 'E'); #endif - if ( (c3n == ret_o) - || (c3n == u3r_cell(jar, &tag, &dat)) ) - { + if ( u3_none == jar ) { + return _lord_plea_foul(god_u, 0, u3_blip); + } + else if ( c3n == u3r_cell(jar, &tag, &dat) ) { return _lord_plea_foul(god_u, 0, jar); } @@ -1172,9 +1169,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) #endif { - ur_dict32_t* dic_u = c3_calloc(sizeof(*dic_u)); - ur_dict32_grow((ur_root_t*)0, dic_u, ur_fib10, ur_fib11); - god_u->dic_u = dic_u; + god_u->sil_u = u3s_cue_sill_init(); } // start reading from proc From e4e8c4e9e83c394a1d8df591a6e5eefc6aa41233 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 11:24:20 -0700 Subject: [PATCH 15/23] vere: use u3s_cue_sill() for ivory pill --- pkg/urbit/vere/king.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index 9a7a113d9..dfa24e174 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -713,17 +713,15 @@ _king_boot_ivory(void) } { - ur_dict32_t dic_u = {0}; - u3_noun pil; + u3_cue_sill* sil_u = u3s_cue_sill_init_with(ur_fib27, ur_fib28); + u3_weak pil; - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib27, ur_fib28); - - if ( c3n == u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, &pil) ) { + if ( u3_none == (pil = u3s_cue_sill_with(sil_u, len_d, byt_y)) ) { u3l_log("lite: unable to cue ivory pill\r\n"); exit(1); } - ur_dict_free((ur_dict_t*)&dic_u); + u3s_cue_sill_done(sil_u); if ( c3n == u3v_boot_lite(pil)) { u3l_log("lite: boot failed\r\n"); From 77754c974ceeb4080af42cf2e797b6ea00aad387 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 11:35:36 -0700 Subject: [PATCH 16/23] u3: removes unused atom measurement function in urth.c --- pkg/urbit/noun/urth.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/pkg/urbit/noun/urth.c b/pkg/urbit/noun/urth.c index 04b84bc44..2124f20df 100644 --- a/pkg/urbit/noun/urth.c +++ b/pkg/urbit/noun/urth.c @@ -9,26 +9,6 @@ #include "all.h" #include "ur/ur.h" -/* _cu_met_3(): atom bytewidth a la u3r_met(3, ...) -*/ -static inline c3_w -_cu_met_3(u3a_atom* vat_u) -{ - c3_w len_w = vat_u->len_w; - c3_w* buf_w = vat_u->buf_w; - - if ( !len_w ) { - return 0; - } - else { - c3_w gal_w = len_w - 1; - c3_w daz_w = buf_w[gal_w]; - - return (gal_w << 2) - + ((daz_w >> 24) ? 4 : (daz_w >> 16) ? 3 : (daz_w >> 8) ? 2 : 1); - } -} - /* _cu_atom_to_ref(): allocate indirect atom off-loom. */ static inline ur_nref From 5f8dcecbe332367c09d78ce23810ad355486978a Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 12:02:38 -0700 Subject: [PATCH 17/23] u3: removes u3s_cue_xeno() --- pkg/urbit/bench/ur_bench.c | 55 ----------- pkg/urbit/include/noun/serial.h | 13 --- pkg/urbit/noun/serial.c | 162 -------------------------------- pkg/urbit/tests/jam_tests.c | 29 +----- 4 files changed, 4 insertions(+), 255 deletions(-) diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index c97fecfc1..1d82affa3 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -225,61 +225,6 @@ _cue_bench(void) fprintf(stderr, " cue sill with: %u ms\r\n", mil_w); } - { - gettimeofday(&b4, 0); - - { - u3_noun out; - c3_w len_w = u3r_met(3, vat); - // XX assumes little-endian - // - c3_y* byt_y = ( c3y == u3a_is_cat(vat) ) - ? (c3_y*)&vat - : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; - - for ( i_w = 0; i_w < max_w; i_w++ ) { - u3s_cue_xeno(len_w, byt_y, &out); - u3z(out); - } - } - - gettimeofday(&f2, 0); - timersub(&f2, &b4, &d0); - mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " cue xeno: %u ms\r\n", mil_w); - } - - { - gettimeofday(&b4, 0); - - { - ur_dict32_t dic_u = {0}; - u3_noun out; - - c3_w len_w = u3r_met(3, vat); - // XX assumes little-endian - // - c3_y* byt_y = ( c3y == u3a_is_cat(vat) ) - ? (c3_y*)&vat - : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; - - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); - - for ( i_w = 0; i_w < max_w; i_w++ ) { - u3s_cue_xeno_unsafe(&dic_u, len_w, byt_y, &out); - u3z(out); - ur_dict32_wipe(&dic_u); - } - - ur_dict_free((ur_dict_t*)&dic_u); - } - - gettimeofday(&f2, 0); - timersub(&f2, &b4, &d0); - mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " cue xeno unsafe: %u ms\r\n", mil_w); - } - { gettimeofday(&b4, 0); diff --git a/pkg/urbit/include/noun/serial.h b/pkg/urbit/include/noun/serial.h index b721d9c5a..bededd9e2 100644 --- a/pkg/urbit/include/noun/serial.h +++ b/pkg/urbit/include/noun/serial.h @@ -62,19 +62,6 @@ u3s_cue_sill(c3_d len_d, const c3_y* byt_y); - /* u3s_cue_xeno_unsafe(): cue onto the loom, all bookkeeping off-loom. - */ - c3_o - u3s_cue_xeno_unsafe(struct ur_dict32_s* dic_u, - c3_d len_d, - const c3_y* byt_y, - u3_noun* out); - - /* u3s_cue_xeno(): cue onto the loom, bookkeeping off the loom. - */ - c3_o - u3s_cue_xeno(c3_d len_d, const c3_y* byt_y, u3_noun* out); - /* u3s_cue_bytes(): cue bytes onto the loom. */ u3_noun diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index 8bde730ab..601488493 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -809,168 +809,6 @@ u3s_cue_sill(c3_d len_d, return som; } -/* _cue_stack_t: heap-allocated struct, used to bypass the road stack. -*/ -typedef struct _cue_stack_s { - c3_w pre_w; - c3_w siz_w; - c3_w fil_w; - _cue_frame_t* fam_u; -} _cue_stack_t; - -/* _cs_cue_xeno_next(): read next value from bitstream, bookkeeping off-loom. -*/ -static inline ur_cue_res_e -_cs_cue_xeno_next(_cue_stack_t* tac_u, - ur_bsr_t* red_u, - ur_dict32_t* dic_u, - u3_noun* out) -{ - while ( 1 ) { - c3_d bit_d = red_u->bits; - ur_cue_tag_e tag_e; - ur_cue_res_e res_e; - - if ( ur_cue_good != (res_e = ur_bsr_tag(red_u, &tag_e)) ) { - return res_e; - } - - switch ( tag_e ) { - default: c3_assert(0); - - case ur_jam_cell: { - // reallocate the stack if full - // - if ( tac_u->fil_w == tac_u->siz_w ) { - c3_w nex_w = tac_u->pre_w + tac_u->siz_w; - tac_u->fam_u = c3_realloc(tac_u->fam_u, nex_w * sizeof(*tac_u->fam_u)); - tac_u->pre_w = tac_u->siz_w; - tac_u->siz_w = nex_w; - } - - // save a head-frame and read the head from the stream - // - { - _cue_frame_t* fam_u = &(tac_u->fam_u[tac_u->fil_w++]); - fam_u->ref = u3_none; - fam_u->bit_d = bit_d; - } - continue; - } - - case ur_jam_back: { - return _cs_cue_sill_back(red_u, dic_u, out); - } - - case ur_jam_atom: { - return _cs_cue_sill_atom(red_u, dic_u, bit_d, out); - } - } - } -} - -/* u3s_cue_xeno_unsafe(): cue onto the loom, all bookkeeping off-loom. -** -** NB: unsafe wrt to [dic_u], which must be empty. -*/ -c3_o -u3s_cue_xeno_unsafe(ur_dict32_t* dic_u, - c3_d len_d, - const c3_y* byt_y, - u3_noun* out) -{ - ur_bsr_t red_u = {0}; - _cue_stack_t tac_u = {0}; - ur_cue_res_e res_e; - u3_noun ref; - - // init bitstream-reader - // - if ( ur_cue_good != (res_e = ur_bsr_init(&red_u, len_d, byt_y)) ) { - return c3n; - } - // bit-cursor (and backreferences) must fit in 62-bit direct atoms - // - else if ( 0x7ffffffffffffffULL < len_d ) { - return c3n; - } - - // setup stack - // - tac_u.pre_w = ur_fib10; - tac_u.siz_w = ur_fib11; - tac_u.fam_u = c3_malloc(tac_u.siz_w * sizeof(*tac_u.fam_u)); - - // advance into stream - // - res_e = _cs_cue_xeno_next(&tac_u, &red_u, dic_u, &ref); - - // process result - // - while ( tac_u.fil_w && (ur_cue_good == res_e) ) { - // peek at the top of the stack - // - _cue_frame_t* fam_u = &(tac_u.fam_u[tac_u.fil_w - 1]); - - // f is a head-frame; stash result and read the tail from the stream - // - if ( u3_none == fam_u->ref ) { - fam_u->ref = ref; - res_e = _cs_cue_xeno_next(&tac_u, &red_u, dic_u, &ref); - } - // f is a tail-frame; pop the stack and continue - // - else { - ur_root_t* rot_u = 0; - - ref = u3nc(fam_u->ref, ref); - ur_dict32_put(rot_u, dic_u, fam_u->bit_d, ref); - tac_u.fil_w--; - } - } - - if ( ur_cue_good == res_e ) { - *out = ref; - c3_free(tac_u.fam_u); - return c3y; - } - else { - // unwind the stack, disposing intermediate nouns - // - while ( tac_u.fil_w ) { - _cue_frame_t* fam_u = &(tac_u.fam_u[--tac_u.fil_w]); - - if ( u3_none != fam_u->ref ) { - u3z(fam_u->ref); - } - } - - c3_free(tac_u.fam_u); - return c3n; - } -} - -/* u3s_cue_xeno(): cue onto the loom, bookkeeping off the loom. -*/ -c3_o -u3s_cue_xeno(c3_d len_d, const c3_y* byt_y, u3_noun* out) -{ - ur_dict32_t dic_u = {0}; - c3_o ret_o; - - c3_assert( &(u3H->rod_u) == u3R ); - - // XX tune the initial dictionary size for less reallocation - // - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); - - ret_o = u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, out); - - ur_dict_free((ur_dict_t*)&dic_u); - - return ret_o; -} - /* _cs_cue_need(): bail on ur_cue_* read failures. */ static inline void diff --git a/pkg/urbit/tests/jam_tests.c b/pkg/urbit/tests/jam_tests.c index 842c0d893..8c03df337 100644 --- a/pkg/urbit/tests/jam_tests.c +++ b/pkg/urbit/tests/jam_tests.c @@ -366,27 +366,6 @@ _test_cue_spec(const c3_c* cap_c, { c3_i ret_i = 1; - { - ur_dict32_t dic_u = {0}; - u3_noun out; - - ur_dict32_grow((ur_root_t*)0, &dic_u, ur_fib10, ur_fib11); - - if ( c3n == u3s_cue_xeno_unsafe(&dic_u, len_w, byt_y, &out) ) { - fprintf(stderr, "\033[31mcue %s fail 1\033[0m\r\n", cap_c); - ret_i = 0; - } - else if ( c3n == u3r_sing(ref, out) ) { - fprintf(stderr, "\033[31mcue %s fail 2\033[0m\r\n", cap_c); - u3m_p("ref", ref); - u3m_p("out", out); - ret_i = 0; - } - - u3z(out); - ur_dict_free((ur_dict_t*)&dic_u); - } - { u3_noun pro = u3m_soft(0, u3s_cue_atom, u3i_bytes(len_w, byt_y)); u3_noun tag, out; @@ -394,11 +373,11 @@ _test_cue_spec(const c3_c* cap_c, u3x_cell(pro, &tag, &out); if ( u3_blip != tag ) { - fprintf(stderr, "\033[31mcue %s fail 3\033[0m\r\n", cap_c); + fprintf(stderr, "\033[31mcue %s fail 1\033[0m\r\n", cap_c); ret_i = 0; } else if ( c3n == u3r_sing(ref, out) ) { - fprintf(stderr, "\033[31mcue %s fail 4\033[0m\r\n", cap_c); + fprintf(stderr, "\033[31mcue %s fail 2\033[0m\r\n", cap_c); u3m_p("ref", ref); u3m_p("out", out); ret_i = 0; @@ -411,11 +390,11 @@ _test_cue_spec(const c3_c* cap_c, u3_noun out; if ( u3_none == (out = u3s_cue_sill(len_w, byt_y)) ) { - fprintf(stderr, "\033[31mcue %s fail 5\033[0m\r\n", cap_c); + fprintf(stderr, "\033[31mcue %s fail 3\033[0m\r\n", cap_c); ret_i = 0; } else if ( c3n == u3r_sing(ref, out) ) { - fprintf(stderr, "\033[31mcue %s fail 6\033[0m\r\n", cap_c); + fprintf(stderr, "\033[31mcue %s fail 4\033[0m\r\n", cap_c); u3m_p("ref", ref); u3m_p("out", out); ret_i = 0; From c3a854363e497d4a77dbf78c64f0c4d2da7811ce Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 12:04:04 -0700 Subject: [PATCH 18/23] u3: renames u3s_cue_sill* to u3s_cue_xeno* --- pkg/urbit/bench/ur_bench.c | 12 +++--- pkg/urbit/include/noun/serial.h | 34 +++++++---------- pkg/urbit/include/vere/vere.h | 2 +- pkg/urbit/noun/serial.c | 65 ++++++++++++++++----------------- pkg/urbit/noun/urth.c | 6 +-- pkg/urbit/tests/jam_tests.c | 2 +- pkg/urbit/vere/king.c | 6 +-- pkg/urbit/vere/lord.c | 6 +-- pkg/urbit/worker/main.c | 8 ++-- 9 files changed, 67 insertions(+), 74 deletions(-) diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index 1d82affa3..706d3ec9a 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -189,21 +189,21 @@ _cue_bench(void) : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; for ( i_w = 0; i_w < max_w; i_w++ ) { - u3z(u3s_cue_sill(len_w, byt_y)); + u3z(u3s_cue_xeno(len_w, byt_y)); } } gettimeofday(&f2, 0); timersub(&f2, &b4, &d0); mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " cue sill: %u ms\r\n", mil_w); + fprintf(stderr, " cue xeno: %u ms\r\n", mil_w); } { gettimeofday(&b4, 0); { - u3_cue_sill* sil_u = u3s_cue_sill_init(); + u3_cue_xeno* sil_u = u3s_cue_xeno_init(); c3_w len_w = u3r_met(3, vat); // XX assumes little-endian @@ -213,16 +213,16 @@ _cue_bench(void) : (c3_y*)((u3a_atom*)u3a_to_ptr(vat))->buf_w; for ( i_w = 0; i_w < max_w; i_w++ ) { - u3z(u3s_cue_sill_with(sil_u, len_w, byt_y)); + u3z(u3s_cue_xeno_with(sil_u, len_w, byt_y)); } - u3s_cue_sill_done(sil_u); + u3s_cue_xeno_done(sil_u); } gettimeofday(&f2, 0); timersub(&f2, &b4, &d0); mil_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000); - fprintf(stderr, " cue sill with: %u ms\r\n", mil_w); + fprintf(stderr, " cue xeno with: %u ms\r\n", mil_w); } { diff --git a/pkg/urbit/include/noun/serial.h b/pkg/urbit/include/noun/serial.h index bededd9e2..a2af308c0 100644 --- a/pkg/urbit/include/noun/serial.h +++ b/pkg/urbit/include/noun/serial.h @@ -3,15 +3,9 @@ */ /* opaque handles */ - /* u3_cue_sill: handle for cue-ing with an off-loom dictionary. + /* u3_cue_xeno: handle for cue-ing with an off-loom dictionary. */ - typedef struct _u3_cue_sill u3_cue_sill; - - /* forward declarations - */ - /* ur_dict32_s: off-loom 32-bit dictionary. - */ - struct ur_dict32_s; + typedef struct _u3_cue_xeno u3_cue_xeno; /* Noun serialization. All noun arguments RETAINED. */ @@ -34,32 +28,32 @@ u3_noun u3s_cue(u3_atom a); - /* u3s_cue_sill_init_with(): initialize a cue_sill handle as specified. + /* u3s_cue_xeno_init_with(): initialize a cue_xeno handle as specified. */ - u3_cue_sill* - u3s_cue_sill_init_with(c3_d pre_d, c3_d siz_d); + u3_cue_xeno* + u3s_cue_xeno_init_with(c3_d pre_d, c3_d siz_d); - /* u3s_cue_sill_init(): initialize a cue_sill handle. + /* u3s_cue_xeno_init(): initialize a cue_xeno handle. */ - u3_cue_sill* - u3s_cue_sill_init(void); + u3_cue_xeno* + u3s_cue_xeno_init(void); - /* u3s_cue_sill_init(): cue on-loom, with off-loom dictionary in handle. + /* u3s_cue_xeno_init(): cue on-loom, with off-loom dictionary in handle. */ u3_weak - u3s_cue_sill_with(u3_cue_sill* sil_u, + u3s_cue_xeno_with(u3_cue_xeno* sil_u, c3_d len_d, const c3_y* byt_y); - /* u3s_cue_sill_init(): dispose cue_sill handle. + /* u3s_cue_xeno_init(): dispose cue_xeno handle. */ void - u3s_cue_sill_done(u3_cue_sill* sil_u); + u3s_cue_xeno_done(u3_cue_xeno* sil_u); - /* u3s_cue_sill(): cue on-loom, with off-loom dictionary. + /* u3s_cue_xeno(): cue on-loom, with off-loom dictionary. */ u3_weak - u3s_cue_sill(c3_d len_d, + u3s_cue_xeno(c3_d len_d, const c3_y* byt_y); /* u3s_cue_bytes(): cue bytes onto the loom. diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index e92a74044..e3e3e5d7a 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -470,7 +470,7 @@ uv_process_t cub_u; // process handle uv_process_options_t ops_u; // process configuration uv_stdio_container_t cod_u[3]; // process options - u3_cue_sill* sil_u; // cue handle + u3_cue_xeno* sil_u; // cue handle time_t wen_t; // process creation time u3_mojo inn_u; // client's stdin u3_moat out_u; // client's stdout diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index 601488493..a3f6576a9 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -532,10 +532,10 @@ u3s_cue(u3_atom a) return pro; } -/* _cs_cue_sill_back(): cue a backref, off-loom dictionary. +/* _cs_cue_xeno_back(): cue a backref, off-loom dictionary. */ static inline ur_cue_res_e -_cs_cue_sill_back(ur_bsr_t* red_u, +_cs_cue_xeno_back(ur_bsr_t* red_u, ur_dict32_t* dic_u, u3_noun* out) { @@ -562,10 +562,10 @@ _cs_cue_sill_back(ur_bsr_t* red_u, } } -/* _cs_cue_sill_atom(): cue an atom, off-loom dictionary. +/* _cs_cue_xeno_atom(): cue an atom, off-loom dictionary. */ static inline ur_cue_res_e -_cs_cue_sill_atom(ur_bsr_t* red_u, +_cs_cue_xeno_atom(ur_bsr_t* red_u, ur_dict32_t* dic_u, c3_d bit_d, u3_noun* out) @@ -619,11 +619,10 @@ typedef struct _cue_frame_s { c3_d bit_d; } _cue_frame_t; -/* _cs_cue_sill_next(): read next value from bitstream, dictionary off-loom. -** NB: this is _cs_cue_xeno_next, using the road stack. +/* _cs_cue_xeno_next(): read next value from bitstream, dictionary off-loom. */ static inline ur_cue_res_e -_cs_cue_sill_next(u3a_pile* pil_u, +_cs_cue_xeno_next(u3a_pile* pil_u, ur_bsr_t* red_u, ur_dict32_t* dic_u, u3_noun* out) @@ -650,24 +649,24 @@ _cs_cue_sill_next(u3a_pile* pil_u, } case ur_jam_back: { - return _cs_cue_sill_back(red_u, dic_u, out); + return _cs_cue_xeno_back(red_u, dic_u, out); } case ur_jam_atom: { - return _cs_cue_sill_atom(red_u, dic_u, bit_d, out); + return _cs_cue_xeno_atom(red_u, dic_u, bit_d, out); } } } } -struct _u3_cue_sill { +struct _u3_cue_xeno { ur_dict32_t dic_u; }; -/* _cs_cue_sill(): cue on-loom, with off-loom dictionary in handle. +/* _cs_cue_xeno(): cue on-loom, with off-loom dictionary in handle. */ static u3_weak -_cs_cue_sill(u3_cue_sill* sil_u, +_cs_cue_xeno(u3_cue_xeno* sil_u, c3_d len_d, const c3_y* byt_y) { @@ -695,7 +694,7 @@ _cs_cue_sill(u3_cue_sill* sil_u, // advance into stream // - res_e = _cs_cue_sill_next(&pil_u, &red_u, dic_u, &ref); + res_e = _cs_cue_xeno_next(&pil_u, &red_u, dic_u, &ref); // process cell results // @@ -709,7 +708,7 @@ _cs_cue_sill(u3_cue_sill* sil_u, // if ( u3_none == fam_u->ref ) { fam_u->ref = ref; - res_e = _cs_cue_sill_next(&pil_u, &red_u, dic_u, &ref); + res_e = _cs_cue_xeno_next(&pil_u, &red_u, dic_u, &ref); fam_u = u3a_peek(&pil_u); } // f is a tail-frame; pop the stack and continue @@ -744,12 +743,12 @@ _cs_cue_sill(u3_cue_sill* sil_u, return u3_none; } -/* u3s_cue_sill_init_with(): initialize a cue_sill handle as specified. +/* u3s_cue_xeno_init_with(): initialize a cue_xeno handle as specified. */ -u3_cue_sill* -u3s_cue_sill_init_with(c3_d pre_d, c3_d siz_d) +u3_cue_xeno* +u3s_cue_xeno_init_with(c3_d pre_d, c3_d siz_d) { - u3_cue_sill* sil_u; + u3_cue_xeno* sil_u; c3_assert( &(u3H->rod_u) == u3R ); @@ -759,18 +758,18 @@ u3s_cue_sill_init_with(c3_d pre_d, c3_d siz_d) return sil_u; } -/* u3s_cue_sill_init(): initialize a cue_sill handle. +/* u3s_cue_xeno_init(): initialize a cue_xeno handle. */ -u3_cue_sill* -u3s_cue_sill_init(void) +u3_cue_xeno* +u3s_cue_xeno_init(void) { - return u3s_cue_sill_init_with(ur_fib10, ur_fib11); + return u3s_cue_xeno_init_with(ur_fib10, ur_fib11); } -/* u3s_cue_sill_init(): cue on-loom, with off-loom dictionary in handle. +/* u3s_cue_xeno_init(): cue on-loom, with off-loom dictionary in handle. */ u3_weak -u3s_cue_sill_with(u3_cue_sill* sil_u, +u3s_cue_xeno_with(u3_cue_xeno* sil_u, c3_d len_d, const c3_y* byt_y) { @@ -778,34 +777,34 @@ u3s_cue_sill_with(u3_cue_sill* sil_u, c3_assert( &(u3H->rod_u) == u3R ); - som = _cs_cue_sill(sil_u, len_d, byt_y); + som = _cs_cue_xeno(sil_u, len_d, byt_y); ur_dict32_wipe(&sil_u->dic_u); return som; } -/* u3s_cue_sill_init(): dispose cue_sill handle. +/* u3s_cue_xeno_init(): dispose cue_xeno handle. */ void -u3s_cue_sill_done(u3_cue_sill* sil_u) +u3s_cue_xeno_done(u3_cue_xeno* sil_u) { ur_dict_free((ur_dict_t*)&sil_u->dic_u); c3_free(sil_u); } -/* u3s_cue_sill(): cue on-loom, with off-loom dictionary. +/* u3s_cue_xeno(): cue on-loom, with off-loom dictionary. */ u3_weak -u3s_cue_sill(c3_d len_d, +u3s_cue_xeno(c3_d len_d, const c3_y* byt_y) { - u3_cue_sill* sil_u; + u3_cue_xeno* sil_u; u3_weak som; c3_assert( &(u3H->rod_u) == u3R ); - sil_u = u3s_cue_sill_init(); - som = _cs_cue_sill(sil_u, len_d, byt_y); - u3s_cue_sill_done(sil_u); + sil_u = u3s_cue_xeno_init(); + som = _cs_cue_xeno(sil_u, len_d, byt_y); + u3s_cue_xeno_done(sil_u); return som; } diff --git a/pkg/urbit/noun/urth.c b/pkg/urbit/noun/urth.c index 2124f20df..89b9185ec 100644 --- a/pkg/urbit/noun/urth.c +++ b/pkg/urbit/noun/urth.c @@ -842,11 +842,11 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d) { // XX tune the initial dictionary size for less reallocation // - u3_cue_sill* sil_u = u3s_cue_sill_init_with(ur_fib33, ur_fib34); - u3_weak ref = u3s_cue_sill_with(sil_u, len_d, byt_y); + u3_cue_xeno* sil_u = u3s_cue_xeno_init_with(ur_fib33, ur_fib34); + u3_weak ref = u3s_cue_xeno_with(sil_u, len_d, byt_y); u3_noun roc, cod; - u3s_cue_sill_done(sil_u); + u3s_cue_xeno_done(sil_u); if ( u3_none == ref ) { fprintf(stderr, "uncram: failed to cue rock\r\n"); diff --git a/pkg/urbit/tests/jam_tests.c b/pkg/urbit/tests/jam_tests.c index 8c03df337..aac870ec3 100644 --- a/pkg/urbit/tests/jam_tests.c +++ b/pkg/urbit/tests/jam_tests.c @@ -389,7 +389,7 @@ _test_cue_spec(const c3_c* cap_c, { u3_noun out; - if ( u3_none == (out = u3s_cue_sill(len_w, byt_y)) ) { + if ( u3_none == (out = u3s_cue_xeno(len_w, byt_y)) ) { fprintf(stderr, "\033[31mcue %s fail 3\033[0m\r\n", cap_c); ret_i = 0; } diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index dfa24e174..40f58f910 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -713,15 +713,15 @@ _king_boot_ivory(void) } { - u3_cue_sill* sil_u = u3s_cue_sill_init_with(ur_fib27, ur_fib28); + u3_cue_xeno* sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28); u3_weak pil; - if ( u3_none == (pil = u3s_cue_sill_with(sil_u, len_d, byt_y)) ) { + if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { u3l_log("lite: unable to cue ivory pill\r\n"); exit(1); } - u3s_cue_sill_done(sil_u); + u3s_cue_xeno_done(sil_u); if ( c3n == u3v_boot_lite(pil)) { u3l_log("lite: boot failed\r\n"); diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index dd7b3224e..f148f1c69 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -74,7 +74,7 @@ _lord_stop_cb(void* ptr_v, void (*exit_f)(void*) = god_u->cb_u.exit_f; void* exit_v = god_u->cb_u.ptr_v; - u3s_cue_sill_done(god_u->sil_u); + u3s_cue_xeno_done(god_u->sil_u); c3_free(god_u); if ( exit_f ) { @@ -682,7 +682,7 @@ _lord_on_plea(void* ptr_v, c3_d len_d, c3_y* byt_y) u3t_event_trace("king ipc cue", 'B'); #endif - jar = u3s_cue_sill_with(god_u->sil_u, len_d, byt_y); + jar = u3s_cue_xeno_with(god_u->sil_u, len_d, byt_y); #ifdef LORD_TRACE_CUE u3t_event_trace("king ipc cue", 'E'); @@ -1169,7 +1169,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) #endif { - god_u->sil_u = u3s_cue_sill_init(); + god_u->sil_u = u3s_cue_xeno_init(); } // start reading from proc diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index fe8bdaf4c..8fe291522 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -27,7 +27,7 @@ static u3_serf u3V; // one serf per process static u3_moat inn_u; // input stream static u3_mojo out_u; // output stream -static u3_cue_sill* sil_u; // cue handle +static u3_cue_xeno* sil_u; // cue handle #undef SERF_TRACE_JAM #undef SERF_TRACE_CUE @@ -116,7 +116,7 @@ _cw_serf_writ(void* vod_p, c3_d len_d, c3_y* byt_y) u3t_event_trace("serf ipc cue", 'B'); #endif - jar = u3s_cue_sill_with(sil_u, len_d, byt_y); + jar = u3s_cue_xeno_with(sil_u, len_d, byt_y); #ifdef SERF_TRACE_CUE u3t_event_trace("serf ipc cue", 'E'); @@ -162,7 +162,7 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i) static void _cw_serf_exit(void) { - u3s_cue_sill_done(sil_u); + u3s_cue_xeno_done(sil_u); u3t_trace_close(); } @@ -236,7 +236,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) uv_stream_set_blocking((uv_stream_t*)&out_u.pyp_u, 1); } - sil_u = u3s_cue_sill_init(); + sil_u = u3s_cue_xeno_init(); // set up writing // From 00df76c2145b04aa5e657a5505aac06a019f5f7d Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 12:24:34 -0700 Subject: [PATCH 19/23] u3: factors atoms/backrefs back into u3s_cue_xeno() --- pkg/urbit/noun/serial.c | 131 ++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 79 deletions(-) diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index a3f6576a9..cff41ab78 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -532,82 +532,6 @@ u3s_cue(u3_atom a) return pro; } -/* _cs_cue_xeno_back(): cue a backref, off-loom dictionary. -*/ -static inline ur_cue_res_e -_cs_cue_xeno_back(ur_bsr_t* red_u, - ur_dict32_t* dic_u, - u3_noun* out) -{ - ur_root_t* rot_u = 0; - ur_cue_res_e res_e; - c3_d len_d; - - if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { - return res_e; - } - else if ( 62 < len_d ) { - return ur_cue_meme; - } - else { - c3_d bak_d = ur_bsr64_any(red_u, len_d); - c3_w bak_w; - - if ( !ur_dict32_get(rot_u, dic_u, bak_d, &bak_w) ) { - return ur_cue_back; - } - - *out = u3k((u3_noun)bak_w); - return ur_cue_good; - } -} - -/* _cs_cue_xeno_atom(): cue an atom, off-loom dictionary. -*/ -static inline ur_cue_res_e -_cs_cue_xeno_atom(ur_bsr_t* red_u, - ur_dict32_t* dic_u, - c3_d bit_d, - u3_noun* out) -{ - ur_root_t* rot_u = 0; - ur_cue_res_e res_e; - c3_d len_d; - - if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { - return res_e; - } - - if ( 31 >= len_d ) { - *out = (u3_noun)ur_bsr32_any(red_u, len_d); - } - // XX need a ur_bsr_words_any() - // - else { - c3_w* wor_w; - c3_y* byt_y; - - { - c3_d byt_d = (len_d >> 3) + !!ur_mask_3(len_d); - - if ( 0xffffffffULL < byt_d) { - return u3m_bail(c3__meme); - } - - // XX assumes little-endian - // - wor_w = u3a_slaq(3, byt_d); - byt_y = (c3_y*)wor_w; - } - - ur_bsr_bytes_any(red_u, len_d, byt_y); - *out = u3a_malt(wor_w); - } - - ur_dict32_put(rot_u, dic_u, bit_d, *out); - return ur_cue_good; -} - /* ** stack frame for recording head vs tail iteration ** @@ -627,8 +551,10 @@ _cs_cue_xeno_next(u3a_pile* pil_u, ur_dict32_t* dic_u, u3_noun* out) { + ur_root_t* rot_u = 0; + while ( 1 ) { - c3_d bit_d = red_u->bits; + c3_d len_d, bit_d = red_u->bits; ur_cue_tag_e tag_e; ur_cue_res_e res_e; @@ -649,11 +575,58 @@ _cs_cue_xeno_next(u3a_pile* pil_u, } case ur_jam_back: { - return _cs_cue_xeno_back(red_u, dic_u, out); + if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { + return res_e; + } + else if ( 62 < len_d ) { + return ur_cue_meme; + } + else { + c3_d bak_d = ur_bsr64_any(red_u, len_d); + c3_w bak_w; + + if ( !ur_dict32_get(rot_u, dic_u, bak_d, &bak_w) ) { + return ur_cue_back; + } + + *out = u3k((u3_noun)bak_w); + return ur_cue_good; + } } case ur_jam_atom: { - return _cs_cue_xeno_atom(red_u, dic_u, bit_d, out); + if ( ur_cue_good != (res_e = ur_bsr_rub_len(red_u, &len_d)) ) { + return res_e; + } + + if ( 31 >= len_d ) { + *out = (u3_noun)ur_bsr32_any(red_u, len_d); + } + // XX need a ur_bsr_words_any() + // + else { + c3_w* wor_w; + c3_y* byt_y; + + { + c3_d byt_d = (len_d >> 3) + !!ur_mask_3(len_d); + + if ( 0xffffffffULL < byt_d) { + return u3m_bail(c3__meme); + } + + // XX assumes little-endian + // + wor_w = u3a_slaq(3, byt_d); + byt_y = (c3_y*)wor_w; + } + + ur_bsr_bytes_any(red_u, len_d, byt_y); + *out = u3a_malt(wor_w); + } + + ur_dict32_put(rot_u, dic_u, bit_d, *out); + return ur_cue_good; } } } From d2047862d82f255d9acb9ede924437cd40e544a6 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 18 Sep 2020 12:25:47 -0700 Subject: [PATCH 20/23] u3: updates u3s_cue_xeno() to return error, not bail on oversized atoms --- pkg/urbit/noun/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/urbit/noun/serial.c b/pkg/urbit/noun/serial.c index cff41ab78..7cffa8210 100644 --- a/pkg/urbit/noun/serial.c +++ b/pkg/urbit/noun/serial.c @@ -612,7 +612,7 @@ _cs_cue_xeno_next(u3a_pile* pil_u, c3_d byt_d = (len_d >> 3) + !!ur_mask_3(len_d); if ( 0xffffffffULL < byt_d) { - return u3m_bail(c3__meme); + return ur_cue_meme; } // XX assumes little-endian From 7493f98480d21b3107e66d7caae6f6af7b2fb506 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 22 Sep 2020 11:42:28 -0700 Subject: [PATCH 21/23] ur: adds missing serial.h include --- pkg/urbit/include/ur/serial.h | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/urbit/include/ur/serial.h b/pkg/urbit/include/ur/serial.h index 61e91daf9..e1cf9e39f 100644 --- a/pkg/urbit/include/ur/serial.h +++ b/pkg/urbit/include/ur/serial.h @@ -4,6 +4,7 @@ #include #include #include +#include /* ** bit-wise serialization of a noun into a byte-buffer. From 592b61fa86a899ce0d582bf6fe906a9a48e1eacf Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Tue, 22 Sep 2020 11:55:57 -0700 Subject: [PATCH 22/23] vere: use cue/test handles for repeated packet parsing --- pkg/urbit/vere/io/ames.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/urbit/vere/io/ames.c b/pkg/urbit/vere/io/ames.c index 796c08813..64771cfbb 100644 --- a/pkg/urbit/vere/io/ames.c +++ b/pkg/urbit/vere/io/ames.c @@ -12,6 +12,7 @@ #include "all.h" #include "vere/vere.h" +#include "ur/serial.h" /* u3_pact: ames packet, coming or going. */ @@ -35,6 +36,8 @@ uv_udp_t wax_u; // uv_handle_t had_u; // }; // + ur_cue_test_t* tes_u; // cue-test handle + u3_cue_xeno* sil_u; // cue handle c3_c* dns_c; // domain XX multiple/fallback c3_d dop_d; // drop count c3_d fal_d; // crash count @@ -365,8 +368,11 @@ _ames_serialize_packet(u3_panc* pac_u, c3_o dop_o) u3_noun lon, bod; { //NOTE we checked for cue safety in _ames_recv_cb - u3_noun old = u3ke_cue(u3i_bytes(pac_u->bod_u.con_w, pac_u->bod_u.con_y)); - u3x_cell(old, &lon, &bod); + // + u3_weak old = u3s_cue_xeno_with(pac_u->sam_u->sil_u, + pac_u->bod_u.con_w, + pac_u->bod_u.con_y); + u3x_cell(u3x_good(old), &lon, &bod); u3k(lon); u3k(bod); u3z(old); } @@ -798,6 +804,7 @@ _ames_recv_cb(uv_udp_t* wax_u, c3_d rec_d[2]; c3_w con_w = nrd_i - 4 - sen_y - rec_y; c3_y* con_y = NULL; + if ( c3y == pas_o ) { u3_noun sen = u3i_bytes(sen_y, bod_y); u3_noun rec = u3i_bytes(rec_y, bod_y + sen_y); @@ -810,9 +817,7 @@ _ames_recv_cb(uv_udp_t* wax_u, // ensure the content is cue-able // - u3_noun pro = u3m_soft(0, u3ke_cue, u3i_bytes(con_w, con_y)); - pas_o = (u3_blip == u3h(pro)) ? c3y : c3n; - u3z(pro); + pas_o = ur_cue_test_with(sam_u->tes_u, con_w, con_y) ? c3y : c3n; } // if we can scry, @@ -1165,6 +1170,9 @@ _ames_exit_cb(uv_handle_t* had_u) u3h_free(sam_u->lax_p); + u3s_cue_xeno_done(sam_u->sil_u); + ur_cue_test_done(sam_u->tes_u); + c3_free(sam_u); } @@ -1225,6 +1233,9 @@ u3_ames_io_init(u3_pier* pir_u) c3_assert( !uv_udp_init(u3L, &sam_u->wax_u) ); sam_u->wax_u.data = sam_u; + sam_u->sil_u = u3s_cue_xeno_init(); + sam_u->tes_u = ur_cue_test_init(); + // Disable networking for fake ships // if ( c3y == sam_u->pir_u->fak_o ) { From 6659c859f1c938c10a4a452718d3b7b81454e0bf Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 25 Sep 2020 01:43:03 +0200 Subject: [PATCH 23/23] kh: abolish unicode syntax in favor of ascii --- pkg/hs/proto/lib/Untyped/Parser.hs | 128 ++++++++--------- .../lib/Urbit/EventLog/LMDB.hs | 4 +- pkg/hs/urbit-king/lib/Urbit/King/Main.hs | 2 +- pkg/hs/urbit-king/lib/Urbit/Vere/LMDB.hs | 4 +- pkg/hs/urbit-king/lib/Urbit/Vere/NounServ.hs | 6 +- pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs | 8 +- .../urbit-king/lib/Urbit/Vere/Term/Render.hs | 10 +- pkg/hs/urbit-king/test/HoonMapSetTests.hs | 2 +- pkg/hs/urbit-noun-core/lib/Urbit/Noun/Jam.hs | 2 +- pkg/hs/urbit-noun/lib/Urbit/Noun.hs | 2 +- pkg/hs/urbit-noun/lib/Urbit/Noun/Tree.hs | 134 +++++++++--------- 11 files changed, 151 insertions(+), 151 deletions(-) diff --git a/pkg/hs/proto/lib/Untyped/Parser.hs b/pkg/hs/proto/lib/Untyped/Parser.hs index 14eb4db6b..be32011cd 100644 --- a/pkg/hs/proto/lib/Untyped/Parser.hs +++ b/pkg/hs/proto/lib/Untyped/Parser.hs @@ -79,61 +79,61 @@ data Mode = Wide | Tall type Parser = StateT Mode (Parsec Void Text) -withLocalState ∷ Monad m => s → StateT s m a → StateT s m a +withLocalState :: Monad m => s -> StateT s m a -> StateT s m a withLocalState val x = do { old <- get; put val; x <* put old } -inWideMode ∷ Parser a → Parser a +inWideMode :: Parser a -> Parser a inWideMode = withLocalState Wide -ace, pal, par ∷ Parser () +ace, pal, par :: Parser () ace = void (char ' ') pal = void (char '(') par = void (char ')') -- Simple Lexers --------------------------------------------------------------- -gap ∷ Parser () +gap :: Parser () gap = choice [ char ' ' >> void (some spaceChar) , newline >> void (many spaceChar) ] -whitespace ∷ Parser () +whitespace :: Parser () whitespace = ace <|> void gap -- Literals -------------------------------------------------------------------- -alpha ∷ Parser Char +alpha :: Parser Char alpha = oneOf (['a'..'z'] ++ ['A'..'Z']) -sym ∷ Parser Sym +sym :: Parser Sym sym = bucSym <|> pack <$> some alpha where bucSym = char '$' *> pure "" -atom ∷ Parser Nat +atom :: Parser Nat atom = do - init ← some digitChar - rest ← many (char '.' *> some digitChar) + init <- some digitChar + rest <- many (char '.' *> some digitChar) guard True -- TODO Validate '.'s pure (Prelude.read $ concat $ init:rest) -nat ∷ Parser Nat +nat :: Parser Nat nat = Prelude.read <$> some digitChar -tape ∷ Parser Text +tape :: Parser Text tape = do between (char '"') (char '"') $ pack <$> many (label "tape char" (anySingleBut '"')) -cord ∷ Parser Text +cord :: Parser Text cord = do between (char '\'') (char '\'') $ pack <$> many (label "cord char" (anySingleBut '\'')) -tag ∷ Parser Text +tag :: Parser Text tag = try (char '%' >> sym) -literal ∷ Parser CST +literal :: Parser CST literal = choice [ Yes <$ string "%.y" , No <$ string "%.n" @@ -156,48 +156,48 @@ literal = choice - accept the `tall` form or: - swich to `Wide` mode and then accept the wide form. -} -parseRune ∷ Parser a → Parser a → Parser a +parseRune :: Parser a -> Parser a -> Parser a parseRune tall wide = get >>= \case - Wide → wide - Tall → tall <|> inWideMode wide + Wide -> wide + Tall -> tall <|> inWideMode wide -rune0 ∷ a → Parser a +rune0 :: a -> Parser a rune0 = pure -rune1 ∷ (a→b) → Parser a → Parser b +rune1 :: (a->b) -> Parser a -> Parser b rune1 node x = parseRune tall wide - where tall = do gap; p←x; pure (node p) - wide = do pal; p←x; par; pure (node p) + where tall = do gap; p<-x; pure (node p) + wide = do pal; p<-x; par; pure (node p) -rune2 ∷ (a→b→c) → Parser a → Parser b → Parser c +rune2 :: (a->b->c) -> Parser a -> Parser b -> Parser c rune2 node x y = parseRune tall wide - where tall = do gap; p←x; gap; q←y; pure (node p q) - wide = do pal; p←x; ace; q←y; par; pure (node p q) + where tall = do gap; p<-x; gap; q<-y; pure (node p q) + wide = do pal; p<-x; ace; q<-y; par; pure (node p q) -rune3 ∷ (a→b→c→d) → Parser a → Parser b → Parser c → Parser d +rune3 :: (a->b->c->d) -> Parser a -> Parser b -> Parser c -> Parser d rune3 node x y z = parseRune tall wide - where tall = do gap; p←x; gap; q←y; gap; r←z; pure (node p q r) - wide = do pal; p←x; ace; q←y; ace; r←z; par; pure (node p q r) + where tall = do gap; p<-x; gap; q<-y; gap; r<-z; pure (node p q r) + wide = do pal; p<-x; ace; q<-y; ace; r<-z; par; pure (node p q r) -rune4 ∷ (a→b→c→d→e) → Parser a → Parser b → Parser c → Parser d → Parser e +rune4 :: (a->b->c->d->e) -> Parser a -> Parser b -> Parser c -> Parser d -> Parser e rune4 node x y z g = parseRune tall wide - where tall = do gap; p←x; gap; q←y; gap; r←z; gap; s←g; pure (node p q r s) - wide = do pal; p←x; ace; q←y; ace; r←z; ace; s←g; pure (node p q r s) + where tall = do gap; p<-x; gap; q<-y; gap; r<-z; gap; s<-g; pure (node p q r s) + wide = do pal; p<-x; ace; q<-y; ace; r<-z; ace; s<-g; pure (node p q r s) -runeN ∷ ([a]→b) → Parser a → Parser b +runeN :: ([a]->b) -> Parser a -> Parser b runeN node elem = node <$> parseRune tall wide where tall = gap >> elems where elems = term <|> elemAnd - elemAnd = do x ← elem; gap; xs ← elems; pure (x:xs) + elemAnd = do x <- elem; gap; xs <- elems; pure (x:xs) term = string "==" *> pure [] wide = pal *> option [] elems <* par where elems = (:) <$> elem <*> many (ace >> elem) -runeNE ∷ (NonEmpty a → b) → Parser a → Parser b +runeNE :: (NonEmpty a -> b) -> Parser a -> Parser b runeNE node elem = node <$> parseRune tall wide where tall = do let elems = term <|> elemAnd - elemAnd = do x ← elem; gap; xs ← elems; pure (x:xs) + elemAnd = do x <- elem; gap; xs <- elems; pure (x:xs) term = string "==" *> pure [] fst <- gap *> elem rst <- gap *> elems @@ -206,36 +206,36 @@ runeNE node elem = node <$> parseRune tall wide -- Irregular Syntax ------------------------------------------------------------ -inc ∷ Parser CST -- +(3) +inc :: Parser CST -- +(3) inc = do string "+(" - h ← cst + h <- cst char ')' pure h -equals ∷ Parser (CST, CST) -- =(3 4) +equals :: Parser (CST, CST) -- =(3 4) equals = do string "=(" - x ← cst + x <- cst ace - y ← cst + y <- cst char ')' pure (x, y) -tuple ∷ ∀a. Parser a → Parser [a] +tuple :: forall a. Parser a -> Parser [a] tuple p = char '[' >> elems where - xs ∷ Parser [a] - xs = do { x ← p; (x:) <$> tail } + xs :: Parser [a] + xs = do { x <- p; (x:) <$> tail } - tail ∷ Parser [a] + tail :: Parser [a] tail = (pure [] <* char ']') <|> (ace >> elems) - elems ∷ Parser [a] + elems :: Parser [a] elems = (pure [] <* char ']') <|> xs -appIrr ∷ Parser CST +appIrr :: Parser CST appIrr = do char '(' x <- cst @@ -244,7 +244,7 @@ appIrr = do char ')' pure (AppIrr x y) -irregular ∷ Parser CST +irregular :: Parser CST irregular = inWideMode $ choice [ Tupl <$> tuple cst @@ -255,14 +255,14 @@ irregular = -- Runes ----------------------------------------------------------------------- -pat ∷ Parser Pat +pat :: Parser Pat pat = choice [ PatTag <$> tag , char '*' $> PatTar ] -cases ∷ Parser [(Pat, CST)] +cases :: Parser [(Pat, CST)] cases = do - mode ← get + mode <- get guard (mode == Tall) end <|> lop where @@ -270,9 +270,9 @@ cases = do end = string "==" $> [] lop = do { p <- pat; gap; b <- cst; gap; ((p,b):) <$> goo } -wutHep ∷ Parser CST +wutHep :: Parser CST wutHep = do - mode ← get + mode <- get guard (mode == Tall) gap ex <- cst @@ -280,15 +280,15 @@ wutHep = do cs <- cases pure (WutHep ex cs) -barCen ∷ Parser CST +barCen :: Parser CST barCen = do - mode ← get + mode <- get guard (mode == Tall) gap cs <- cases pure (BarCen cs) -rune ∷ Parser CST +rune :: Parser CST rune = runeSwitch [ ("|=", rune2 BarTis sym cst) , ("|-", rune4 BarHep sym sym cst cst) , (":-", rune2 ColHep cst cst) @@ -313,13 +313,13 @@ rune = runeSwitch [ ("|=", rune2 BarTis sym cst) , ("~/", rune2 SigFas cst cst) ] -runeSwitch ∷ [(Text, Parser a)] → Parser a -runeSwitch = choice . fmap (\(s, p) → string s *> p) +runeSwitch :: [(Text, Parser a)] -> Parser a +runeSwitch = choice . fmap (\(s, p) -> string s *> p) -- CST Parser ------------------------------------------------------------------ -cst ∷ Parser CST +cst :: Parser CST cst = irregular <|> rune <|> literal @@ -327,19 +327,19 @@ cst = irregular <|> rune <|> literal hoonFile = do option () whitespace - h ← cst + h <- cst option () whitespace eof pure h -parse ∷ Text → Either Text CST +parse :: Text -> Either Text CST parse txt = runParser (evalStateT hoonFile Tall) "stdin" txt & \case - Left e → Left (pack $ errorBundlePretty e) - Right x → pure x + Left e -> Left (pack $ errorBundlePretty e) + Right x -> pure x -parseHoonTest ∷ Text → IO () +parseHoonTest :: Text -> IO () parseHoonTest = parseTest (evalStateT hoonFile Tall) -main ∷ IO () +main :: IO () main = (head <$> getArgs) >>= parseHoonTest diff --git a/pkg/hs/urbit-eventlog-lmdb/lib/Urbit/EventLog/LMDB.hs b/pkg/hs/urbit-eventlog-lmdb/lib/Urbit/EventLog/LMDB.hs index ed53db19c..0cb44beaa 100644 --- a/pkg/hs/urbit-eventlog-lmdb/lib/Urbit/EventLog/LMDB.hs +++ b/pkg/hs/urbit-eventlog-lmdb/lib/Urbit/EventLog/LMDB.hs @@ -300,7 +300,7 @@ streamEvents log first = do for_ batch yield streamEvents log (first + word (length batch)) -streamEffectsRows :: ∀e. HasLogFunc e +streamEffectsRows :: forall e. HasLogFunc e => EventLog -> Word64 -> ConduitT () (Word64, ByteString) (RIO e) () streamEffectsRows log = go @@ -352,7 +352,7 @@ readBatch log first = start {-| Read 1000 rows from the database, starting from key `first`. -} -readRowsBatch :: ∀e. HasLogFunc e +readRowsBatch :: forall e. HasLogFunc e => Env -> Dbi -> Word64 -> RIO e (V.Vector (Word64, ByteString)) readRowsBatch env dbi first = readRows where diff --git a/pkg/hs/urbit-king/lib/Urbit/King/Main.hs b/pkg/hs/urbit-king/lib/Urbit/King/Main.hs index 66092ffb6..c8b653cc9 100644 --- a/pkg/hs/urbit-king/lib/Urbit/King/Main.hs +++ b/pkg/hs/urbit-king/lib/Urbit/King/Main.hs @@ -835,7 +835,7 @@ runMultipleShips ships = do -------------------------------------------------------------------------------- -connTerm :: ∀e. HasLogFunc e => FilePath -> RIO e () +connTerm :: forall e. HasLogFunc e => FilePath -> RIO e () connTerm = Term.runTerminalClient diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/LMDB.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/LMDB.hs index 691e25e5c..8e32246df 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/LMDB.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/LMDB.hs @@ -169,7 +169,7 @@ streamEvents log first = do for_ batch yield streamEvents log (first + word (length batch)) -streamEffectsRows :: ∀e. HasLogFunc e +streamEffectsRows :: forall e. HasLogFunc e => EventLog -> EventId -> ConduitT () (Word64, ByteString) (RIO e) () streamEffectsRows log = go @@ -221,7 +221,7 @@ readBatch log first = start {- Read 1000 rows from the database, starting from key `first`. -} -readRowsBatch :: ∀e. HasLogFunc e +readRowsBatch :: forall e. HasLogFunc e => Env -> Dbi -> Word64 -> RIO e (V.Vector (Word64, ByteString)) readRowsBatch env dbi first = readRows where diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/NounServ.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/NounServ.hs index bc31c32e9..4f60929ac 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/NounServ.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/NounServ.hs @@ -44,7 +44,7 @@ data Server i o a = Server -------------------------------------------------------------------------------- -withRIOThread ∷ RIO e a → RIO e (Async a) +withRIOThread :: RIO e a -> RIO e (Async a) withRIOThread act = do env <- ask io $ async $ runRIO env $ act @@ -87,7 +87,7 @@ wsConn pre inp out wsc = do -------------------------------------------------------------------------------- -wsClient :: ∀i o e. (ToNoun o, FromNoun i, Show o, Show i, HasLogFunc e) +wsClient :: forall i o e. (ToNoun o, FromNoun i, Show o, Show i, HasLogFunc e) => Text -> W.Port -> RIO e (Client i o) wsClient pax por = do env <- ask @@ -118,7 +118,7 @@ wsServApp cb pen = do atomically $ cb (mkConn inp out) wsConn "NOUNSERV (wsServ) " inp out wsc -wsServer :: ∀i o e. (ToNoun o, FromNoun i, Show i, Show o, HasLogFunc e) +wsServer :: forall i o e. (ToNoun o, FromNoun i, Show i, Show o, HasLogFunc e) => RIO e (Server i o W.Port) wsServer = do con <- io $ newTBMChanIO 5 diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs index e4b5bf0cd..be919c721 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term.hs @@ -104,7 +104,7 @@ connClient c = Client , take = Serv.cRecv c } -connectToRemote :: ∀e. HasLogFunc e +connectToRemote :: forall e. HasLogFunc e => Port -> Client -> RAcquire e (Async (), Async ()) @@ -130,7 +130,7 @@ data HackConfigDir = HCD { _hcdPax :: FilePath } makeLenses ''HackConfigDir instance HasPierPath HackConfigDir where pierPathL = hcdPax -runTerminalClient :: ∀e. HasLogFunc e => FilePath -> RIO e () +runTerminalClient :: forall e. HasLogFunc e => FilePath -> RIO e () runTerminalClient pier = runRAcquire $ do mPort <- runRIO (HCD pier) readPortsFile port <- maybe (error "Can't connect") pure mPort @@ -173,7 +173,7 @@ _spin_idle_us = 500000 {-| Initializes the generalized input/output parts of the terminal. -} -localClient :: ∀e. HasLogFunc e +localClient :: forall e. HasLogFunc e => STM () -> RAcquire e (TermSize, Client) localClient doneSignal = fst <$> mkRAcquire start stop @@ -415,7 +415,7 @@ localClient doneSignal = fst <$> mkRAcquire start stop -- Moves the cursor left without any mutation of the LineState. Used only -- in cursor spinning. - _termSpinnerMoveLeft :: Int → RIO e () + _termSpinnerMoveLeft :: Int -> RIO e () _termSpinnerMoveLeft = T.cursorLeft -- Displays and sets the current line diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs index a7751a005..3765f9cb2 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Term/Render.hs @@ -16,17 +16,17 @@ import qualified System.Console.ANSI as ANSI -- Types ----------------------------------------------------------------------- -clearScreen ∷ MonadIO m ⇒ m () +clearScreen :: MonadIO m => m () clearScreen = liftIO $ ANSI.clearScreen -clearLine ∷ MonadIO m ⇒ m () +clearLine :: MonadIO m => m () clearLine = liftIO $ ANSI.clearLine -soundBell ∷ MonadIO m ⇒ m () +soundBell :: MonadIO m => m () soundBell = liftIO $ putStr "\a" -cursorLeft ∷ MonadIO m ⇒ Int → m () +cursorLeft :: MonadIO m => Int -> m () cursorLeft = liftIO . ANSI.cursorBackward -cursorRight ∷ MonadIO m ⇒ Int → m () +cursorRight :: MonadIO m => Int -> m () cursorRight = liftIO . ANSI.cursorForward diff --git a/pkg/hs/urbit-king/test/HoonMapSetTests.hs b/pkg/hs/urbit-king/test/HoonMapSetTests.hs index f5b797a9a..9cb8deaf9 100644 --- a/pkg/hs/urbit-king/test/HoonMapSetTests.hs +++ b/pkg/hs/urbit-king/test/HoonMapSetTests.hs @@ -38,7 +38,7 @@ type TreeTests = [TreeTest] -- Utils ----------------------------------------------------------------------- -roundTrip :: ∀a. Eq a => (a -> a) -> a -> Bool +roundTrip :: forall a. Eq a => (a -> a) -> a -> Bool roundTrip f x = f x == x diff --git a/pkg/hs/urbit-noun-core/lib/Urbit/Noun/Jam.hs b/pkg/hs/urbit-noun-core/lib/Urbit/Noun/Jam.hs index 3b5d02f44..e9f2a64c2 100644 --- a/pkg/hs/urbit-noun-core/lib/Urbit/Noun/Jam.hs +++ b/pkg/hs/urbit-noun-core/lib/Urbit/Noun/Jam.hs @@ -1,7 +1,7 @@ {-# OPTIONS_GHC -O2 #-} {-| - Fast implementation of Jam (Noun → Atom). + Fast implementation of Jam (Noun -> Atom). This is based on the implementation of `flat`. -} diff --git a/pkg/hs/urbit-noun/lib/Urbit/Noun.hs b/pkg/hs/urbit-noun/lib/Urbit/Noun.hs index 7e443992a..ac62f5c3f 100644 --- a/pkg/hs/urbit-noun/lib/Urbit/Noun.hs +++ b/pkg/hs/urbit-noun/lib/Urbit/Noun.hs @@ -49,7 +49,7 @@ data LoadErr instance Exception LoadErr -loadFile :: ∀a. FromNoun a => FilePath -> IO (Either LoadErr a) +loadFile :: forall a. FromNoun a => FilePath -> IO (Either LoadErr a) loadFile pax = try $ do byt <- try (readFile pax) >>= either (throwIO . FileErr) pure non <- cueBS byt & either (throwIO . CueErr) pure diff --git a/pkg/hs/urbit-noun/lib/Urbit/Noun/Tree.hs b/pkg/hs/urbit-noun/lib/Urbit/Noun/Tree.hs index 61751cca5..876148e3d 100644 --- a/pkg/hs/urbit-noun/lib/Urbit/Noun/Tree.hs +++ b/pkg/hs/urbit-noun/lib/Urbit/Noun/Tree.hs @@ -27,14 +27,14 @@ import GHC.Natural (Natural) -- Types ----------------------------------------------------------------------- data NounVal a = NounVal - { non ∷ Noun - , val ∷ !a + { non :: Noun + , val :: !a } data HoonTreeNode a = NTN - { n ∷ NounVal a - , l ∷ HoonTree a - , r ∷ HoonTree a + { n :: NounVal a + , l :: HoonTree a + , r :: HoonTree a } deriving (Eq, Ord, Show) @@ -43,10 +43,10 @@ data HoonTree a = E | Node (HoonTreeNode a) pattern N n l r = Node (NTN n l r) -newtype HoonSet a = HoonSet { unHoonSet ∷ HoonTree a } +newtype HoonSet a = HoonSet { unHoonSet :: HoonTree a } deriving newtype (Eq, Ord, Show, FromNoun, ToNoun) -newtype HoonMap k v = HoonMap { unHoonMap ∷ HoonTree (k, v) } +newtype HoonMap k v = HoonMap { unHoonMap :: HoonTree (k, v) } deriving newtype (Eq, Ord, Show, FromNoun, ToNoun) @@ -61,17 +61,17 @@ instance Ord (NounVal a) where instance ToNoun (NounVal a) where toNoun = non -instance Show a ⇒ Show (NounVal a) where +instance Show a => Show (NounVal a) where show = show . val -instance FromNoun a ⇒ FromNoun (NounVal a) where +instance FromNoun a => FromNoun (NounVal a) where parseNoun x = NounVal x <$> parseNoun x -instance ToNoun a ⇒ ToNoun (HoonTree a) where +instance ToNoun a => ToNoun (HoonTree a) where toNoun E = A 0 toNoun (Node n) = toNoun n -instance FromNoun a ⇒ FromNoun (HoonTree a) where +instance FromNoun a => FromNoun (HoonTree a) where parseNoun (A 0) = pure E parseNoun n = Node <$> parseNoun n @@ -82,60 +82,60 @@ deriveNoun ''HoonTreeNode type Nat = Natural -slowMug ∷ Noun → Nat +slowMug :: Noun -> Nat slowMug = trim 0xcafe_babe . \case - A a → a - C h t → mix (slowMug h) $ mix 0x7fff_ffff (slowMug t) + A a -> a + C h t -> mix (slowMug h) $ mix 0x7fff_ffff (slowMug t) where - trim ∷ Nat → Nat → Nat + trim :: Nat -> Nat -> Nat trim syd key = if 0/=ham then ham else trim (succ syd) key where haz = muk syd (met 3 key) key ham = mix (rsh 0 31 haz) (end 0 31 haz) -mix ∷ Nat → Nat → Nat +mix :: Nat -> Nat -> Nat mix = xor -- Murmur3 -muk ∷ Nat → Nat → Nat → Nat +muk :: Nat -> Nat -> Nat -> Nat muk seed len = fromIntegral . murmur3 (word32 seed) . resize . atomBytes where - resize ∷ ByteString → ByteString + resize :: ByteString -> ByteString resize buf = case compare (length buf) (int len) of - EQ → buf - LT → error "bad-muk" - GT → error "bad-muk" --- LT → buf <> replicate (len - length buf) 0 --- GT → take len buf + EQ -> buf + LT -> error "bad-muk" + GT -> error "bad-muk" +-- LT -> buf <> replicate (len - length buf) 0 +-- GT -> take len buf -int ∷ Integral i ⇒ i → Int +int :: Integral i => i -> Int int = fromIntegral -word32 ∷ Integral i ⇒ i → Word32 +word32 :: Integral i => i -> Word32 word32 = fromIntegral -bex ∷ Nat → Nat +bex :: Nat -> Nat bex = (2^) -end ∷ Nat → Nat → Nat → Nat +end :: Nat -> Nat -> Nat -> Nat end blockSize blocks n = n `mod` (bex (bex blockSize * blocks)) -rsh ∷ Nat → Nat → Nat → Nat +rsh :: Nat -> Nat -> Nat -> Nat rsh blockSize blocks n = shiftR n $ fromIntegral $ (bex blockSize * blocks) -met ∷ Nat → Nat → Nat +met :: Nat -> Nat -> Nat met bloq = go 0 where go c 0 = c go c n = go (succ c) (rsh bloq 1 n) -- XX TODO -mug ∷ Noun → Nat +mug :: Noun -> Nat mug = slowMug @@ -144,7 +144,7 @@ mug = slowMug {- Orders in ascending double mug hash order, collisions fall back to dor. -} -mor ∷ Noun → Noun → Bool +mor :: Noun -> Noun -> Bool mor a b = if c == d then dor a b else c < d where c = mug $ A $ mug a @@ -153,7 +153,7 @@ mor a b = if c == d then dor a b else c < d {- Orders in ascending tree depth. -} -dor ∷ Noun → Noun → Bool +dor :: Noun -> Noun -> Bool dor a b | a == b = True dor (A a) (C _ _) = True dor (C x y) (A b) = False @@ -166,80 +166,80 @@ dor (C x y) (C p q) = dor x p Collisions fall back to dor. -} -gor ∷ Noun → Noun → Bool +gor :: Noun -> Noun -> Bool gor a b = if c==d then dor a b else c NounVal a -> Bool morVal = on mor non gorVal = on gor non -------------------------------------------------------------------------------- -nounVal ∷ ToNoun a ⇒ Iso' a (NounVal a) +nounVal :: ToNoun a => Iso' a (NounVal a) nounVal = iso to val where to x = NounVal (toNoun x) x -treeToList ∷ ∀a. HoonTree a → [a] +treeToList :: forall a. HoonTree a -> [a] treeToList = go [] where - go ∷ [a] → HoonTree a → [a] + go :: [a] -> HoonTree a -> [a] go acc = \case - E → acc - Node (NTN v l r) → go (go (val v : acc) l) r + E -> acc + Node (NTN v l r) -> go (go (val v : acc) l) r -setFromHoonSet ∷ Ord a ⇒ HoonSet a → Set a +setFromHoonSet :: Ord a => HoonSet a -> Set a setFromHoonSet = setFromList . treeToList . unHoonSet -mapFromHoonMap ∷ Ord k ⇒ HoonMap k v → Map k v +mapFromHoonMap :: Ord k => HoonMap k v -> Map k v mapFromHoonMap = mapFromList . treeToList . unHoonMap -setToHoonSet ∷ ∀a. (Ord a, ToNoun a) ⇒ Set a → HoonSet a +setToHoonSet :: forall a. (Ord a, ToNoun a) => Set a -> HoonSet a setToHoonSet = HoonSet . foldr put E . fmap (view nounVal) . setToList where put x = \case - E → N x E E - Node a | x == n a → Node a - Node a | gorVal x (n a) → lef x a - Node a → rit x a + E -> N x E E + Node a | x == n a -> Node a + Node a | gorVal x (n a) -> lef x a + Node a -> rit x a rit x a = put x (r a) & \case - E → error "bad-put-set" - Node c | morVal (n a) (n c) → N (n a) (l a) (Node c) - Node c → N (n c) (N (n a) (l a) (l c)) (r c) + E -> error "bad-put-set" + Node c | morVal (n a) (n c) -> N (n a) (l a) (Node c) + Node c -> N (n c) (N (n a) (l a) (l c)) (r c) lef x a = put x (l a) & \case - E → error "bad-put-set" - Node c | morVal (n a) (n c) → N (n a) (Node c) (r a) - Node c → N (n c) (l c) (N (n a) (r c) (r a)) + E -> error "bad-put-set" + Node c | morVal (n a) (n c) -> N (n a) (Node c) (r a) + Node c -> N (n c) (l c) (N (n a) (r c) (r a)) -p ∷ (ToNoun a, ToNoun b) ⇒ NounVal (a,b) → NounVal a +p :: (ToNoun a, ToNoun b) => NounVal (a,b) -> NounVal a p = view (from nounVal . to fst . nounVal) -pq ∷ (ToNoun a, ToNoun b) ⇒ NounVal (a,b) → (NounVal a, NounVal b) +pq :: (ToNoun a, ToNoun b) => NounVal (a,b) -> (NounVal a, NounVal b) pq = boof . view (from nounVal) where boof (x, y) = (x ^. nounVal, y ^. nounVal) -mapToHoonMap ∷ ∀k v. (ToNoun k, ToNoun v, Ord k, Ord v) ⇒ Map k v → HoonMap k v +mapToHoonMap :: forall k v. (ToNoun k, ToNoun v, Ord k, Ord v) => Map k v -> HoonMap k v mapToHoonMap = HoonMap . foldr put E . fmap (view nounVal) . mapToList where - put ∷ NounVal (k, v) → HoonTree (k, v) → HoonTree (k, v) + put :: NounVal (k, v) -> HoonTree (k, v) -> HoonTree (k, v) put kv@(pq -> (b, c)) = \case - E → N kv E E - Node a | kv == n a → Node a - Node a | b == p (n a) → N kv (l a) (r a) - Node a | gorVal b (p $ n a) → lef kv a - Node a → rit kv a + E -> N kv E E + Node a | kv == n a -> Node a + Node a | b == p (n a) -> N kv (l a) (r a) + Node a | gorVal b (p $ n a) -> lef kv a + Node a -> rit kv a lef kv@(pq -> (b, c)) a = put kv (l a) & \case - E → error "bad-put-map" - Node d | morVal (p $ n a) (p $ n d) → N (n a) (Node d) (r a) - Node d → N (n d) (l d) (N (n a) (r d) (r a)) + E -> error "bad-put-map" + Node d | morVal (p $ n a) (p $ n d) -> N (n a) (Node d) (r a) + Node d -> N (n d) (l d) (N (n a) (r d) (r a)) rit kv@(pq -> (b, c)) a = put kv (r a) & \case - E → error "bad-put-map" - Node d | morVal (p $ n a) (p $ n d) → N (n a) (l a) (Node d) - Node d → N (n d) (N (n a) (l a) (l d)) (r d) + E -> error "bad-put-map" + Node d | morVal (p $ n a) (p $ n d) -> N (n a) (l a) (Node d) + Node d -> N (n d) (N (n a) (l a) (l d)) (r d)