From d9631f83e8c1c0d2c51e1deff912f06693173c4b Mon Sep 17 00:00:00 2001 From: barter-simsum Date: Fri, 12 Apr 2024 18:17:09 -0400 Subject: [PATCH 01/16] pma: fix memory corruption restoration bug Previously, we failed to record node partitions in the flist on restore. No we do so --- rust/ares_pma/c-src/btest.c | 2 +- rust/ares_pma/c-src/btree.c | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/rust/ares_pma/c-src/btest.c b/rust/ares_pma/c-src/btest.c index 1d13040d..d6496fcb 100644 --- a/rust/ares_pma/c-src/btest.c +++ b/rust/ares_pma/c-src/btest.c @@ -318,7 +318,7 @@ int main(int argc, char *argv[]) assert(SUCC(bt_state_open(state4, "./pmatest4", 0, 0644))); assert(state4->file_size_p == PMA_INITIAL_SIZE_p + PMA_GROW_SIZE_p * 2); - assert(state4->flist->next->hi == state4->file_size_p); + /* assert(state4->flist->next->hi == state4->file_size_p); */ for (size_t i = 0; i < PMA_GROW_SIZE_b * 2; i++) assert(t4a_copy[i] == t4a[i]); diff --git a/rust/ares_pma/c-src/btree.c b/rust/ares_pma/c-src/btree.c index 73588667..2af6d2ab 100644 --- a/rust/ares_pma/c-src/btree.c +++ b/rust/ares_pma/c-src/btree.c @@ -1689,7 +1689,6 @@ _flist_grow(BT_state *state, size_t pages) static int _flist_new(BT_state *state, size_t size_p) #define FLIST_PG_START (BT_META_SECTION_WIDTH / BT_PAGESIZE) -/* #define FLIST_PG_START ((BT_META_SECTION_WIDTH + BLK_BASE_LEN0_b) / BT_PAGESIZE) */ { BT_flistnode *head = calloc(1, sizeof *head); head->next = 0; @@ -2407,6 +2406,22 @@ _freelist_restore2(BT_state *state, BT_page *node, } } +static void +_flist_restore_partitions(BT_state *state) +{ + BT_meta *meta = state->meta_pages[state->which]; + assert(meta->blk_base[0] == BT_NUMMETAS); + + for (size_t i = 0 + ; i < BT_NUMPARTS && meta->blk_base[i] != 0 + ; i++) { + pgno_t partoff_p = meta->blk_base[i]; + size_t partlen_p = BLK_BASE_LENS_b[i] / BT_PAGESIZE; + + _flist_record_alloc(state, partoff_p, partoff_p + partlen_p); + } +} + static void _freelist_restore(BT_state *state) /* restores the mlist, nlist, and mlist */ @@ -2416,9 +2431,13 @@ _freelist_restore(BT_state *state) assert(SUCC(_flist_new(state, state->file_size_p))); assert(SUCC(_nlist_load(state))); assert(SUCC(_mlist_new(state))); - /* first record root's allocation */ + + /* record node partitions in flist */ + _flist_restore_partitions(state); + + /* record root's allocation and then handle subtree */ _nlist_record_alloc(state, root); - _freelist_restore2(state, root, 1, meta->depth); + _freelist_restore2(state, root, 1, meta->depth); /* ;;: flist restoration is fucked */ } static void @@ -2515,7 +2534,6 @@ _bt_state_load(BT_state *state) /* map the node segment */ _bt_state_map_node_segment(state); - /* new db, so populate metadata */ if (new) { assert(SUCC(_flist_new(state, PMA_GROW_SIZE_p))); assert(SUCC(_nlist_new(state))); From 4cf532cbff9cee6504b947ab1027873bf289d1e5 Mon Sep 17 00:00:00 2001 From: barter-simsum Date: Fri, 12 Apr 2024 18:28:32 -0400 Subject: [PATCH 02/16] pma: minor fixup --- rust/ares_pma/c-src/btest.c | 2 +- rust/ares_pma/c-src/btree.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ares_pma/c-src/btest.c b/rust/ares_pma/c-src/btest.c index d6496fcb..eed097f3 100644 --- a/rust/ares_pma/c-src/btest.c +++ b/rust/ares_pma/c-src/btest.c @@ -318,7 +318,7 @@ int main(int argc, char *argv[]) assert(SUCC(bt_state_open(state4, "./pmatest4", 0, 0644))); assert(state4->file_size_p == PMA_INITIAL_SIZE_p + PMA_GROW_SIZE_p * 2); - /* assert(state4->flist->next->hi == state4->file_size_p); */ + assert(state4->flist->hi == state4->file_size_p); for (size_t i = 0; i < PMA_GROW_SIZE_b * 2; i++) assert(t4a_copy[i] == t4a[i]); diff --git a/rust/ares_pma/c-src/btree.c b/rust/ares_pma/c-src/btree.c index 2af6d2ab..a314e288 100644 --- a/rust/ares_pma/c-src/btree.c +++ b/rust/ares_pma/c-src/btree.c @@ -2437,7 +2437,7 @@ _freelist_restore(BT_state *state) /* record root's allocation and then handle subtree */ _nlist_record_alloc(state, root); - _freelist_restore2(state, root, 1, meta->depth); /* ;;: flist restoration is fucked */ + _freelist_restore2(state, root, 1, meta->depth); } static void From 30fe59fed649f0e831cbea7ddfba57b9cf03d7d8 Mon Sep 17 00:00:00 2001 From: Sigilante <57601680+sigilante@users.noreply.github.com> Date: Mon, 20 May 2024 14:27:55 -0500 Subject: [PATCH 03/16] Update DEVELOPERS.md --- DEVELOPERS.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/DEVELOPERS.md b/DEVELOPERS.md index 2fa954af..844a97de 100644 --- a/DEVELOPERS.md +++ b/DEVELOPERS.md @@ -10,6 +10,18 @@ nix develop in `rust/` or any subdirectory, and you will be dropped into a BASH shell with the build environment set up. This will provide proper versions of non-rust dependencies, as well as the rust environment. +If you receive the error + +``` +error: experimental Nix feature 'nix-command' is disabled; use '--extra-experimental-features nix-command' to override +``` + +edit your `$HOME/.config/nix/nix.conf` to include the line + +``` +extra-experimental-features = nix-command +``` + ## Rust ### Build @@ -33,7 +45,7 @@ To run the Vere king with Ares as serf, it's necessary to modify the Vere king t arg_c[0] = "/path/to/ares/repo/rust/ares/target/debug/ares"; ``` -Then, it is necessary to follow the [Vere build instrcutions](https://github.com/urbit/vere/blob/develop/INSTALL.md). Afterwards, it's possible to launch Vere with Ares as the serf using the usual commands: +Then, it is necessary to follow the [Vere build instrcutions](https://github.com/urbit/vere/blob/develop/INSTALL.md). (You should exit the `nix develop` shell first for such a build.) Afterwards, it's possible to launch Vere with Ares as the serf using the usual commands: ```bash bazel-bin/pkg/vere/urbit -F zod From 1899056b00b22c0f17668ff1d27d0bb42c6da5bb Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Wed, 29 May 2024 13:00:29 -0400 Subject: [PATCH 04/16] Link to `DEVELOPERS.md` for alpha release --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index d0cc2d65..724d670f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,4 @@ Read the [proposal](docs/proposal/proposal-nock-performance.md) and [hypotheses] ## Installation -Dependencies: -* [`libaes_siv`](https://github.com/dfoxfranke/libaes_siv) -* [`openssl`](https://github.com/openssl/openssl) -* [`libsecp256k1`](https://github.com/bitcoin-core/secp256k1) +See the "Run" section of [DEVELOPERS.md](DEVELOPERS.md#run). From a52036343261d6402d5a05441d4d9200c4ed9119 Mon Sep 17 00:00:00 2001 From: Philip Quirk Date: Thu, 30 May 2024 16:52:45 -0500 Subject: [PATCH 05/16] fix two weird bugs --- rust/ares/src/hamt.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/rust/ares/src/hamt.rs b/rust/ares/src/hamt.rs index d7f08a32..5843f322 100644 --- a/rust/ares/src/hamt.rs +++ b/rust/ares/src/hamt.rs @@ -345,18 +345,22 @@ impl Hamt { *new_leaf_buffer = (*n, t); let split = stem.hypothetical_index(chunk); let new_buffer = stack.struct_alloc(stem.size() + 1); - copy_nonoverlapping(stem.buffer, new_buffer, split); + if split > 0 { + copy_nonoverlapping(stem.buffer, new_buffer, split); + } *new_buffer.add(split) = Entry { leaf: Leaf { len: 1, buffer: new_leaf_buffer, }, }; - copy_nonoverlapping( - stem.buffer.add(split), - new_buffer.add(split + 1), - stem.size() - split, - ); + if stem.size() - split > 0 { + copy_nonoverlapping( + stem.buffer.add(split), + new_buffer.add(split + 1), + stem.size() - split, + ); + } *dest = Stem { bitmap: stem.bitmap | chunk_to_bit(chunk), typemap: stem.typemap & !chunk_to_bit(chunk), @@ -628,8 +632,10 @@ impl Persist for Hamt { let next_chunk = traversal[depth].bitmap.trailing_zeros(); let next_type = traversal[depth].typemap & (1 << next_chunk) != 0; let next_entry = *traversal[depth].buffer; - traversal[depth].bitmap >>= next_chunk + 1; - traversal[depth].typemap >>= next_chunk + 1; + traversal[depth].bitmap >>= next_chunk; + traversal[depth].bitmap >>= 1; + traversal[depth].typemap >>= next_chunk; + traversal[depth].typemap >>= 1; traversal[depth].buffer = traversal[depth].buffer.add(1); if next_type { @@ -707,8 +713,10 @@ impl Persist for Hamt { let next_type = traversal[depth].typemap & (1 << next_chunk) != 0; let next_entry_ptr = traversal[depth].buffer; - traversal[depth].bitmap >>= next_chunk + 1; - traversal[depth].typemap >>= next_chunk + 1; + traversal[depth].bitmap >>= next_chunk; + traversal[depth].bitmap >>= 1; + traversal[depth].typemap >>= next_chunk; + traversal[depth].typemap >>= 1; traversal[depth].buffer = traversal[depth].buffer.add(1); if next_type { From 6278242bf1fdd1bdac05eeb630f9a7c9c18fbe57 Mon Sep 17 00:00:00 2001 From: Philip Quirk Date: Fri, 31 May 2024 12:31:05 -0500 Subject: [PATCH 06/16] clean up --- rust/ares/src/hamt.rs | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/rust/ares/src/hamt.rs b/rust/ares/src/hamt.rs index 5843f322..0b95d690 100644 --- a/rust/ares/src/hamt.rs +++ b/rust/ares/src/hamt.rs @@ -632,10 +632,17 @@ impl Persist for Hamt { let next_chunk = traversal[depth].bitmap.trailing_zeros(); let next_type = traversal[depth].typemap & (1 << next_chunk) != 0; let next_entry = *traversal[depth].buffer; - traversal[depth].bitmap >>= next_chunk; - traversal[depth].bitmap >>= 1; - traversal[depth].typemap >>= next_chunk; - traversal[depth].typemap >>= 1; + if next_chunk >= 31 { + // if next_chunk == 31, then we will try to shift the bitmap by next_chunk+1 = 32 bits. + // The datatype is a u32, so this is equivalent to setting it to 0. If we do try + // to shift a u32 by 32 bits, then rust's overflow checking will catch it + // and crash the process. + traversal[depth].bitmap = 0; + traversal[depth].typemap = 0; + } else { + traversal[depth].bitmap >>= next_chunk + 1; + traversal[depth].typemap >>= next_chunk + 1; + } traversal[depth].buffer = traversal[depth].buffer.add(1); if next_type { @@ -713,10 +720,17 @@ impl Persist for Hamt { let next_type = traversal[depth].typemap & (1 << next_chunk) != 0; let next_entry_ptr = traversal[depth].buffer; - traversal[depth].bitmap >>= next_chunk; - traversal[depth].bitmap >>= 1; - traversal[depth].typemap >>= next_chunk; - traversal[depth].typemap >>= 1; + if next_chunk >= 31 { + // if next_chunk == 31, then we will try to shift the bitmap by next_chunk+1 = 32 bits. + // The datatype is a u32, so this is equivalent to setting it to 0. If we do try + // to shift a u32 by 32 bits, then rust's overflow checking will catch it + // and crash the process. + traversal[depth].bitmap = 0; + traversal[depth].typemap = 0; + } else { + traversal[depth].bitmap >>= next_chunk + 1; + traversal[depth].typemap >>= next_chunk + 1; + } traversal[depth].buffer = traversal[depth].buffer.add(1); if next_type { From ba4c46d6faef5d2735e9e66408c2a5099a11f8d6 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Thu, 13 Jun 2024 15:40:52 -0400 Subject: [PATCH 07/16] site: callsite caching init --- rust/ares/src/jets/list.rs | 39 ++++--------------------- rust/ares/src/lib.rs | 1 + rust/ares/src/site.rs | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 rust/ares/src/site.rs diff --git a/rust/ares/src/jets/list.rs b/rust/ares/src/jets/list.rs index 3a2d318f..fb3e36ff 100644 --- a/rust/ares/src/jets/list.rs +++ b/rust/ares/src/jets/list.rs @@ -4,8 +4,7 @@ use crate::interpreter::{interpret, Context}; use crate::jets::util::{slot, BAIL_FAIL}; use crate::jets::Result; use crate::noun::{Cell, Noun, D, T}; -use bitvec::order::Lsb0; -use bitvec::slice::BitSlice; +use crate::site::Site; crate::gdb!(); @@ -30,43 +29,15 @@ pub fn jet_turn(context: &mut Context, subject: Noun) -> Result { let sample = slot(subject, 6)?; let mut list = slot(sample, 2)?; let mut gate = slot(sample, 3)?; - let mut gate_battery = slot(gate, 2)?; + let gate_battery = slot(gate, 2)?; let gate_context = slot(gate, 7)?; let mut res = D(0); let mut dest: *mut Noun = &mut res; // Mutable pointer because we cannot guarantee initialized - // Since the gate doesn't change, we can do a single jet check and use that through the whole - // loop - if let Some((jet, _path)) = context - .warm - .find_jet(&mut context.stack, &mut gate, &mut gate_battery) - .filter(|(_jet, mut path)| { - // check that 7 is a prefix of the parent battery axis, - // to ensure that the sample (axis 6) is not part of the jet match. - // - // XX TODO this check is pessimized since there could be multiple ways to match the - // jet and we only actually match one of them, but we check all of them and run - // unjetted if any have an axis outside 7. - let axis_7_bits: &BitSlice = BitSlice::from_element(&7u64); - let batteries_list = context.cold.find(&mut context.stack, &mut path); - let mut ret = true; - for mut batteries in batteries_list { - if let Some((_battery, parent_axis)) = batteries.next() { - let parent_axis_prefix_bits = &parent_axis.as_bitslice()[0..3]; - if parent_axis_prefix_bits == axis_7_bits { - continue; - } else { - ret = false; - break; - } - } else { - ret = false; - break; - } - } - ret - }) + if let Some(site) = Site::new(context, &mut gate) { + let jet = site.jet; + let _path = site.path; loop { if let Ok(list_cell) = list.as_cell() { list = list_cell.tail(); diff --git a/rust/ares/src/lib.rs b/rust/ares/src/lib.rs index e7c37ec9..07563d78 100644 --- a/rust/ares/src/lib.rs +++ b/rust/ares/src/lib.rs @@ -13,6 +13,7 @@ pub mod mug; pub mod newt; pub mod noun; pub mod serf; +pub mod site; //pub mod bytecode; pub mod persist; pub mod serialization; diff --git a/rust/ares/src/site.rs b/rust/ares/src/site.rs new file mode 100644 index 00000000..5edca750 --- /dev/null +++ b/rust/ares/src/site.rs @@ -0,0 +1,58 @@ +/** Call site of a kick (Nock 9), used to cache call targets. */ +use bitvec::order::Lsb0; +use bitvec::slice::BitSlice; + +use crate::interpreter::Context; +use crate::jets::util::slot; +use crate::jets::{Jet, Result}; +use crate::noun::{D, Noun}; + +pub struct Site { + pub jet: Jet, + pub path: Noun, +} + +impl Site { + /// Prepare a locally cached gate to call repeatedly. + pub fn new(ctx: &mut Context, gate: &mut Noun) -> Option { + let mut gate_battery = slot(*gate, 2).unwrap(); + if let Some((jet, path)) = ctx + .warm + .find_jet(&mut ctx.stack, gate, &mut gate_battery) + .filter(|(_jet, mut path)| { + // check that 7 is a prefix of the parent battery axis, + // to ensure that the sample (axis 6) is not part of the jet match. + // + // XX TODO this check is pessimized since there could be multiple ways to match the + // jet and we only actually match one of them, but we check all of them and run + // unjetted if any have an axis outside 7. + let axis_7_bits: &BitSlice = BitSlice::from_element(&7u64); + let batteries_list = ctx.cold.find(&mut ctx.stack, &mut path); + let mut ret = true; + for mut batteries in batteries_list { + if let Some((_battery, parent_axis)) = batteries.next() { + let parent_axis_prefix_bits = &parent_axis.as_bitslice()[0..3]; + if parent_axis_prefix_bits == axis_7_bits { + continue; + } else { + ret = false; + break; + } + } else { + ret = false; + break; + } + } + ret + }) + { + return Some(Site { jet, path } ); + } + None + } + + /// Kick a core with a cached `Site`. + pub fn kick() -> Result { + Ok(D(0)) + } +} From 445bfd7a28a7163151ac080d0c3436d85dbc6b42 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 14:15:42 -0400 Subject: [PATCH 08/16] site: `site_slam` and use it for `+turn` --- rust/ares/src/jets/list.rs | 74 +++++++++++--------------------------- rust/ares/src/site.rs | 39 +++++++++++++------- 2 files changed, 46 insertions(+), 67 deletions(-) diff --git a/rust/ares/src/jets/list.rs b/rust/ares/src/jets/list.rs index fb3e36ff..7359be18 100644 --- a/rust/ares/src/jets/list.rs +++ b/rust/ares/src/jets/list.rs @@ -1,10 +1,10 @@ /** Text processing jets */ -use crate::interpreter::{interpret, Context}; +use crate::interpreter::Context; use crate::jets::util::{slot, BAIL_FAIL}; use crate::jets::Result; -use crate::noun::{Cell, Noun, D, T}; -use crate::site::Site; +use crate::noun::{Cell, Noun, D}; +use crate::site::{site_slam, Site}; crate::gdb!(); @@ -29,61 +29,27 @@ pub fn jet_turn(context: &mut Context, subject: Noun) -> Result { let sample = slot(subject, 6)?; let mut list = slot(sample, 2)?; let mut gate = slot(sample, 3)?; - let gate_battery = slot(gate, 2)?; - let gate_context = slot(gate, 7)?; let mut res = D(0); let mut dest: *mut Noun = &mut res; // Mutable pointer because we cannot guarantee initialized - - if let Some(site) = Site::new(context, &mut gate) - { - let jet = site.jet; - let _path = site.path; - loop { - if let Ok(list_cell) = list.as_cell() { - list = list_cell.tail(); - let element_subject = T( - &mut context.stack, - &[gate_battery, list_cell.head(), gate_context], - ); - unsafe { - let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack); - (*new_mem).head = jet(context, element_subject)?; - *dest = new_cell.as_noun(); - dest = &mut (*new_mem).tail; - } - } else { - if unsafe { !list.raw_equals(D(0)) } { - return Err(BAIL_FAIL); - } - unsafe { - *dest = D(0); - }; - return Ok(res); + + let site = Site::new(context, &mut gate); + loop { + if let Ok(list_cell) = list.as_cell() { + list = list_cell.tail(); + unsafe { + let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack); + (*new_mem).head = site_slam(context, &site, list_cell.head()); + *dest = new_cell.as_noun(); + dest = &mut (*new_mem).tail; } - } - } else { - loop { - if let Ok(list_cell) = list.as_cell() { - list = list_cell.tail(); - let element_subject = T( - &mut context.stack, - &[gate_battery, list_cell.head(), gate_context], - ); - unsafe { - let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack); - (*new_mem).head = interpret(context, element_subject, gate_battery)?; - *dest = new_cell.as_noun(); - dest = &mut (*new_mem).tail; - } - } else { - if unsafe { !list.raw_equals(D(0)) } { - return Err(BAIL_FAIL); - } - unsafe { - *dest = D(0); - }; - return Ok(res); + } else { + if unsafe { !list.raw_equals(D(0)) } { + return Err(BAIL_FAIL); } + unsafe { + *dest = D(0); + }; + return Ok(res); } } } diff --git a/rust/ares/src/site.rs b/rust/ares/src/site.rs index 5edca750..afb89fd6 100644 --- a/rust/ares/src/site.rs +++ b/rust/ares/src/site.rs @@ -2,23 +2,26 @@ use bitvec::order::Lsb0; use bitvec::slice::BitSlice; -use crate::interpreter::Context; +use crate::interpreter::{interpret, Context}; use crate::jets::util::slot; -use crate::jets::{Jet, Result}; -use crate::noun::{D, Noun}; +use crate::jets::Jet; +use crate::noun::{Noun, D, T}; pub struct Site { - pub jet: Jet, - pub path: Noun, + pub battery: Noun, // battery + pub context: Noun, // context + pub jet: Option, // jet driver + pub path: Noun, // label } impl Site { /// Prepare a locally cached gate to call repeatedly. - pub fn new(ctx: &mut Context, gate: &mut Noun) -> Option { - let mut gate_battery = slot(*gate, 2).unwrap(); + pub fn new(ctx: &mut Context, core: &mut Noun) -> Site { + let mut battery = slot(*core, 2).unwrap(); + let context = slot(*core, 7).unwrap(); if let Some((jet, path)) = ctx .warm - .find_jet(&mut ctx.stack, gate, &mut gate_battery) + .find_jet(&mut ctx.stack, core, &mut battery) .filter(|(_jet, mut path)| { // check that 7 is a prefix of the parent battery axis, // to ensure that the sample (axis 6) is not part of the jet match. @@ -46,13 +49,23 @@ impl Site { ret }) { - return Some(Site { jet, path } ); + return Site { battery: battery, context: context, jet: Some(jet), path: path }; } - None + return Site { battery: battery, context: context, jet: None, path: D(0) }; } +} - /// Kick a core with a cached `Site`. - pub fn kick() -> Result { - Ok(D(0)) +/// Slam a cached call site. +pub fn site_slam( + ctx: &mut Context, + site: &Site, + sample: Noun, +) -> Noun { + let subject = T(&mut ctx.stack, &[site.battery, sample, site.context]); + if site.jet.is_some() { + let jet = site.jet.unwrap(); + return jet(ctx, subject).unwrap(); + } else { + return interpret(ctx, subject, site.battery).unwrap(); } } From c80474d0cf0c070c677a5412ecc9a6af06122920 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 14:24:59 -0400 Subject: [PATCH 09/16] cargo: fmt --- rust/ares/src/jets/list.rs | 2 +- rust/ares/src/site.rs | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/rust/ares/src/jets/list.rs b/rust/ares/src/jets/list.rs index 7359be18..33aa5fd3 100644 --- a/rust/ares/src/jets/list.rs +++ b/rust/ares/src/jets/list.rs @@ -31,7 +31,7 @@ pub fn jet_turn(context: &mut Context, subject: Noun) -> Result { let mut gate = slot(sample, 3)?; let mut res = D(0); let mut dest: *mut Noun = &mut res; // Mutable pointer because we cannot guarantee initialized - + let site = Site::new(context, &mut gate); loop { if let Ok(list_cell) = list.as_cell() { diff --git a/rust/ares/src/site.rs b/rust/ares/src/site.rs index afb89fd6..332fff42 100644 --- a/rust/ares/src/site.rs +++ b/rust/ares/src/site.rs @@ -8,10 +8,10 @@ use crate::jets::Jet; use crate::noun::{Noun, D, T}; pub struct Site { - pub battery: Noun, // battery - pub context: Noun, // context - pub jet: Option, // jet driver - pub path: Noun, // label + pub battery: Noun, // battery + pub context: Noun, // context + pub jet: Option, // jet driver + pub path: Noun, // label } impl Site { @@ -49,18 +49,24 @@ impl Site { ret }) { - return Site { battery: battery, context: context, jet: Some(jet), path: path }; + return Site { + battery: battery, + context: context, + jet: Some(jet), + path: path, + }; } - return Site { battery: battery, context: context, jet: None, path: D(0) }; + return Site { + battery: battery, + context: context, + jet: None, + path: D(0), + }; } } /// Slam a cached call site. -pub fn site_slam( - ctx: &mut Context, - site: &Site, - sample: Noun, -) -> Noun { +pub fn site_slam(ctx: &mut Context, site: &Site, sample: Noun) -> Noun { let subject = T(&mut ctx.stack, &[site.battery, sample, site.context]); if site.jet.is_some() { let jet = site.jet.unwrap(); From a7dca29031eacfa62de967d0c96edc7a2696fe8f Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 14:32:33 -0400 Subject: [PATCH 10/16] site: simplify, clippy --- rust/ares/src/site.rs | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/rust/ares/src/site.rs b/rust/ares/src/site.rs index 332fff42..c13ac7f8 100644 --- a/rust/ares/src/site.rs +++ b/rust/ares/src/site.rs @@ -19,7 +19,8 @@ impl Site { pub fn new(ctx: &mut Context, core: &mut Noun) -> Site { let mut battery = slot(*core, 2).unwrap(); let context = slot(*core, 7).unwrap(); - if let Some((jet, path)) = ctx + + let warm_result = ctx .warm .find_jet(&mut ctx.stack, core, &mut battery) .filter(|(_jet, mut path)| { @@ -47,21 +48,13 @@ impl Site { } } ret - }) - { - return Site { - battery: battery, - context: context, - jet: Some(jet), - path: path, - }; + }); + Site { + battery, + context, + jet: warm_result.map(|(jet, _)| jet), + path: warm_result.map(|(_, path)| path).unwrap_or(D(0)) } - return Site { - battery: battery, - context: context, - jet: None, - path: D(0), - }; } } @@ -70,8 +63,8 @@ pub fn site_slam(ctx: &mut Context, site: &Site, sample: Noun) -> Noun { let subject = T(&mut ctx.stack, &[site.battery, sample, site.context]); if site.jet.is_some() { let jet = site.jet.unwrap(); - return jet(ctx, subject).unwrap(); + jet(ctx, subject).unwrap() } else { - return interpret(ctx, subject, site.battery).unwrap(); + interpret(ctx, subject, site.battery).unwrap() } } From 63ccdf0832ac7d76c61d5f724ad8d0149aa3ca4e Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 14:34:03 -0400 Subject: [PATCH 11/16] cargo: fmt --- rust/ares/src/site.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ares/src/site.rs b/rust/ares/src/site.rs index c13ac7f8..3daa9a43 100644 --- a/rust/ares/src/site.rs +++ b/rust/ares/src/site.rs @@ -53,7 +53,7 @@ impl Site { battery, context, jet: warm_result.map(|(jet, _)| jet), - path: warm_result.map(|(_, path)| path).unwrap_or(D(0)) + path: warm_result.map(|(_, path)| path).unwrap_or(D(0)), } } } From 8f43be08018d1c96e5a3f6decf9c92796770c755 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 16:11:34 -0400 Subject: [PATCH 12/16] jets: roll --- rust/ares/src/jets/hot.rs | 5 +++++ rust/ares/src/jets/list.rs | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/rust/ares/src/jets/hot.rs b/rust/ares/src/jets/hot.rs index 97bf5c76..54c511b9 100644 --- a/rust/ares/src/jets/hot.rs +++ b/rust/ares/src/jets/hot.rs @@ -99,6 +99,11 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[ 1, jet_turn, ), + ( + &[K_139, Left(b"one"), Left(b"two"), Left(b"roll")], + 1, + jet_roll, + ), ( &[K_139, Left(b"one"), Left(b"two"), Left(b"zing")], 1, diff --git a/rust/ares/src/jets/list.rs b/rust/ares/src/jets/list.rs index 33aa5fd3..942483a6 100644 --- a/rust/ares/src/jets/list.rs +++ b/rust/ares/src/jets/list.rs @@ -3,7 +3,7 @@ use crate::interpreter::Context; use crate::jets::util::{slot, BAIL_FAIL}; use crate::jets::Result; -use crate::noun::{Cell, Noun, D}; +use crate::noun::{Cell, Noun, D, T}; use crate::site::{site_slam, Site}; crate::gdb!(); @@ -54,6 +54,27 @@ pub fn jet_turn(context: &mut Context, subject: Noun) -> Result { } } +pub fn jet_roll(context: &mut Context, subject: Noun) -> Result { + let sample = slot(subject, 6)?; + let mut list = slot(sample, 2)?; + let mut gate = slot(sample, 3)?; + let mut pro = slot(gate, 13)?; + + let site = Site::new(context, &mut gate); + loop { + if let Ok(list_cell) = list.as_cell() { + list = list_cell.tail(); + let sam = T(&mut context.stack, &[list_cell.head(), pro]); + pro = site_slam(context, &site, sam); + } else { + if unsafe { !list.raw_equals(D(0)) } { + return Err(BAIL_FAIL); + } + return Ok(pro); + } + } +} + pub mod util { use crate::jets::util::BAIL_EXIT; use crate::jets::{JetErr, Result}; From 68d6e5bd09de7726ce39d19f0f162a23ef6fee12 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 16:54:24 -0400 Subject: [PATCH 13/16] jets: `+rep:by` --- rust/ares/src/jets.rs | 2 ++ rust/ares/src/jets/hot.rs | 5 +++++ rust/ares/src/jets/maps.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 rust/ares/src/jets/maps.rs diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index f9ebe3cd..273f1d0f 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -8,6 +8,7 @@ pub mod hash; pub mod list; pub mod lock; pub mod lute; +pub mod maps; pub mod math; pub mod nock; pub mod parse; @@ -27,6 +28,7 @@ use crate::jets::lock::aes::*; use crate::jets::lock::ed::*; use crate::jets::lock::sha::*; use crate::jets::lute::*; +use crate::jets::maps::*; use crate::jets::math::*; use crate::jets::nock::*; use crate::jets::parse::*; diff --git a/rust/ares/src/jets/hot.rs b/rust/ares/src/jets/hot.rs index 54c511b9..5614579e 100644 --- a/rust/ares/src/jets/hot.rs +++ b/rust/ares/src/jets/hot.rs @@ -224,6 +224,11 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[ 1, jet_jam, ), + ( + &[K_139, Left(b"one"), Left(b"two"), Left(b"by"), Left(b"rep")], + 1, + jet_by_rep, + ), // ( &[ diff --git a/rust/ares/src/jets/maps.rs b/rust/ares/src/jets/maps.rs new file mode 100644 index 00000000..b0fbc303 --- /dev/null +++ b/rust/ares/src/jets/maps.rs @@ -0,0 +1,34 @@ +/** Map jets. */ +use crate::interpreter::Context; +use crate::jets::util::slot; +use crate::jets::Result; +use crate::noun::{Noun, D, T}; +use crate::site::{site_slam, Site}; + +crate::gdb!(); + +fn by_rep(context: &mut Context, tree: Noun, site: &Site, out: &mut Noun) { + if unsafe { tree.raw_equals(D(0)) } { + return; + } else { + let node = slot(tree, 2).unwrap(); + let left = slot(node, 6).unwrap(); + let rite = slot(node, 7).unwrap(); + + let acc = T(&mut context.stack, &[node, *out]); + *out = site_slam(context, site, acc); + + by_rep(context, left, site, out); + by_rep(context, rite, site, out); + } +} + +pub fn jet_by_rep(context: &mut Context, subject: Noun) -> Result { + let tree = slot(subject, 30)?; + let mut gate = slot(subject, 6)?; + let mut pro = slot(gate, 13)?; + + let site = Site::new(context, &mut gate); + by_rep(context, tree, &site, &mut pro); + Ok(pro) +} \ No newline at end of file From a18f94a8d33c45114240af6b3af58f8dcba608f4 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 16:55:49 -0400 Subject: [PATCH 14/16] cargo: clippy --- rust/ares/src/jets/maps.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/ares/src/jets/maps.rs b/rust/ares/src/jets/maps.rs index b0fbc303..e36fea46 100644 --- a/rust/ares/src/jets/maps.rs +++ b/rust/ares/src/jets/maps.rs @@ -9,7 +9,6 @@ crate::gdb!(); fn by_rep(context: &mut Context, tree: Noun, site: &Site, out: &mut Noun) { if unsafe { tree.raw_equals(D(0)) } { - return; } else { let node = slot(tree, 2).unwrap(); let left = slot(node, 6).unwrap(); @@ -31,4 +30,4 @@ pub fn jet_by_rep(context: &mut Context, subject: Noun) -> Result { let site = Site::new(context, &mut gate); by_rep(context, tree, &site, &mut pro); Ok(pro) -} \ No newline at end of file +} From 1734fb1c0dae97567c080f2639bb247946cf9426 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 14 Jun 2024 22:07:15 -0400 Subject: [PATCH 15/16] jets: `+rep:by` fix, and link to `+rep:in` too --- rust/ares/src/jets/hot.rs | 5 +++++ rust/ares/src/jets/maps.rs | 15 ++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rust/ares/src/jets/hot.rs b/rust/ares/src/jets/hot.rs index 5614579e..a5e97972 100644 --- a/rust/ares/src/jets/hot.rs +++ b/rust/ares/src/jets/hot.rs @@ -229,6 +229,11 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[ 1, jet_by_rep, ), + ( + &[K_139, Left(b"one"), Left(b"two"), Left(b"in"), Left(b"rep")], + 1, + jet_by_rep, // +rep:in has the same signature as +rep:by + ), // ( &[ diff --git a/rust/ares/src/jets/maps.rs b/rust/ares/src/jets/maps.rs index e36fea46..4c888888 100644 --- a/rust/ares/src/jets/maps.rs +++ b/rust/ares/src/jets/maps.rs @@ -9,16 +9,17 @@ crate::gdb!(); fn by_rep(context: &mut Context, tree: Noun, site: &Site, out: &mut Noun) { if unsafe { tree.raw_equals(D(0)) } { - } else { - let node = slot(tree, 2).unwrap(); - let left = slot(node, 6).unwrap(); - let rite = slot(node, 7).unwrap(); - + } else if let Ok(node) = slot(tree, 2) { let acc = T(&mut context.stack, &[node, *out]); *out = site_slam(context, site, acc); - by_rep(context, left, site, out); - by_rep(context, rite, site, out); + if let Ok(left) = slot(tree, 6) { + by_rep(context, left, site, out); + } + + if let Ok(rite) = slot(tree, 7) { + by_rep(context, rite, site, out); + } } } From 1d5ad623ca8590bb8bc9f5e8502b6d81cac60be4 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Thu, 1 Aug 2024 20:26:46 -0400 Subject: [PATCH 16/16] jets: rename `maps` to `seam` --- rust/ares/src/jets.rs | 4 ++-- rust/ares/src/jets/{maps.rs => seam.rs} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename rust/ares/src/jets/{maps.rs => seam.rs} (100%) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 273f1d0f..b91ee310 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -8,10 +8,10 @@ pub mod hash; pub mod list; pub mod lock; pub mod lute; -pub mod maps; pub mod math; pub mod nock; pub mod parse; +pub mod seam; pub mod serial; pub mod sort; pub mod tree; @@ -28,10 +28,10 @@ use crate::jets::lock::aes::*; use crate::jets::lock::ed::*; use crate::jets::lock::sha::*; use crate::jets::lute::*; -use crate::jets::maps::*; use crate::jets::math::*; use crate::jets::nock::*; use crate::jets::parse::*; +use crate::jets::seam::*; use crate::jets::serial::*; use crate::jets::sort::*; diff --git a/rust/ares/src/jets/maps.rs b/rust/ares/src/jets/seam.rs similarity index 100% rename from rust/ares/src/jets/maps.rs rename to rust/ares/src/jets/seam.rs