From ba4c46d6faef5d2735e9e66408c2a5099a11f8d6 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Thu, 13 Jun 2024 15:40:52 -0400 Subject: [PATCH 1/9] 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 2/9] 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 3/9] 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 4/9] 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 5/9] 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 6/9] 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 7/9] 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 8/9] 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 9/9] 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); + } } }