mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 17:24:52 +03:00
codegen: progress re-implementing rust interpreter
This commit is contained in:
parent
3204982f37
commit
6e40a1ebee
@ -1265,7 +1265,7 @@
|
|||||||
hill
|
hill
|
||||||
--
|
--
|
||||||
:: codegen interface
|
:: codegen interface
|
||||||
:- %1
|
=+ %1
|
||||||
|%
|
|%
|
||||||
::
|
::
|
||||||
:: core reference
|
:: core reference
|
||||||
|
@ -202,11 +202,11 @@
|
|||||||
::
|
::
|
||||||
:: long: starting label for direct calls axis 2
|
:: long: starting label for direct calls axis 2
|
||||||
:: want: input registers for direct calls axis 6
|
:: want: input registers for direct calls axis 6
|
||||||
:: walt: input starting registers LR axis 30
|
:: walt: input starting registers LR axis 14
|
||||||
:: wish: starting label for indirect calls axis 62
|
:: wish: starting label for indirect calls axis 30
|
||||||
:: sire: input register for indirect calls axis 126
|
:: sire: input register for indirect calls axis 62
|
||||||
:: will: code table for arm axis 254
|
:: will: code table for arm axis 126
|
||||||
:: sans: next SSA register axis 255
|
:: sans: next SSA register axis 127
|
||||||
+$ pile
|
+$ pile
|
||||||
$: long=bile
|
$: long=bile
|
||||||
want=need
|
want=need
|
||||||
|
423
rust/ares/src/codegen.rs
Normal file
423
rust/ares/src/codegen.rs
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
use crate::interpreter::{inc, interpret, Context, Error, Result, BAIL_EXIT};
|
||||||
|
use crate::jets::seam::util::get_by;
|
||||||
|
use crate::jets::util::slot;
|
||||||
|
use crate::mem::NockStack;
|
||||||
|
use crate::noun::{DirectAtom, Noun, D, NOUN_NONE, T};
|
||||||
|
use ares_macros::tas;
|
||||||
|
use std::mem::size_of;
|
||||||
|
use std::ptr::write_bytes;
|
||||||
|
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Frame {
|
||||||
|
/// Slow stack as a list
|
||||||
|
slow: Noun,
|
||||||
|
/// Mean stack as a list
|
||||||
|
mean: Noun,
|
||||||
|
/// Code table for current arm
|
||||||
|
pile: Noun,
|
||||||
|
/// Continuation label when returning to this frame
|
||||||
|
cont: Noun,
|
||||||
|
/// Result register when returning to this frame
|
||||||
|
salt: usize,
|
||||||
|
/// number of locals
|
||||||
|
vars: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Frame {
|
||||||
|
fn init(&mut self, vars: usize, prev: Option<&Frame>) {
|
||||||
|
*self = Frame {
|
||||||
|
slow: prev.map_or(D(0), |f| f.slow),
|
||||||
|
mean: prev.map_or(D(0), |f| f.mean),
|
||||||
|
pile: NOUN_NONE,
|
||||||
|
cont: NOUN_NONE,
|
||||||
|
salt: usize::MAX,
|
||||||
|
vars,
|
||||||
|
};
|
||||||
|
unsafe { write_bytes((self as *mut Frame).add(1) as *mut u64, 0, vars) };
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn current<'a>(stack: &NockStack) -> &'a Self {
|
||||||
|
&(*(stack.get_frame_base() as *const Frame))
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn current_mut<'a>(stack: &NockStack) -> &'a mut Self {
|
||||||
|
&mut (*(stack.get_frame_base() as *mut Frame))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vars<'a>(&self) -> &'a [Noun] {
|
||||||
|
unsafe { from_raw_parts((self as *const Frame).add(1) as *const Noun, self.vars) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vars_mut<'a>(&mut self) -> &'a mut [Noun] {
|
||||||
|
unsafe { from_raw_parts_mut((self as *mut Frame).add(1) as *mut Noun, self.vars) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mean_push(&mut self, stack: &mut NockStack, entry: Noun) {
|
||||||
|
self.mean = T(stack, &[entry, self.mean]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mean_pop(&mut self) {
|
||||||
|
self.mean = self
|
||||||
|
.mean
|
||||||
|
.as_cell()
|
||||||
|
.expect("Cannot pop empty mean stack")
|
||||||
|
.tail();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slow_push(&mut self, stack: &mut NockStack, entry: Noun) {
|
||||||
|
self.slow = T(stack, &[entry, self.slow]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slow_pop(&mut self) {
|
||||||
|
self.slow = self
|
||||||
|
.slow
|
||||||
|
.as_cell()
|
||||||
|
.expect("Cannot pop empty slow stack")
|
||||||
|
.tail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq_align!(Frame, u64, usize);
|
||||||
|
assert_eq_size!(u64, usize);
|
||||||
|
const FRAME_WORD_SIZE: usize = size_of::<Frame>() / size_of::<u64>();
|
||||||
|
|
||||||
|
fn push_interpreter_frame(stack: &mut NockStack, pile: Noun) {
|
||||||
|
let vars = pile_sans(pile);
|
||||||
|
let prev = unsafe { Frame::current(stack) };
|
||||||
|
stack.frame_push(FRAME_WORD_SIZE + vars);
|
||||||
|
let frame = unsafe { Frame::current_mut(stack) };
|
||||||
|
frame.init(vars, Some(prev));
|
||||||
|
frame.pile = pile;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_outer_frame(stack: &mut NockStack, pile: Noun) {
|
||||||
|
let vars = pile_sans(pile);
|
||||||
|
stack.frame_push(FRAME_WORD_SIZE + vars);
|
||||||
|
let frame = unsafe { Frame::current_mut(stack) };
|
||||||
|
frame.init(vars, None);
|
||||||
|
frame.pile = pile;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PEEK_AXIS: u64 = 4;
|
||||||
|
const POKE_AXIS: u64 = 46;
|
||||||
|
|
||||||
|
fn slam_line(context: &mut Context, arm_axis: u64, sample: Noun) -> Noun {
|
||||||
|
let axis_noun = DirectAtom::new_panic(arm_axis).as_noun();
|
||||||
|
let subject = T(&mut context.stack, &[sample, context.line]);
|
||||||
|
let sample_patch = T(&mut context.stack, &[D(6), D(0), D(2)]);
|
||||||
|
let arm_kick_form = T(&mut context.stack, &[D(9), axis_noun, D(0), D(3)]);
|
||||||
|
let gate_slam_form = T(
|
||||||
|
&mut context.stack,
|
||||||
|
&[D(9), D(2), D(10), sample_patch, arm_kick_form],
|
||||||
|
);
|
||||||
|
interpret(context, subject, gate_slam_form).expect("Crash in codegen")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cg_peek(context: &mut Context, subject: Noun, formula: Noun) -> Option<Noun> {
|
||||||
|
assert!(!context.line.is_none());
|
||||||
|
let sample = T(&mut context.stack, &[subject, formula]);
|
||||||
|
let peek_result = slam_line(context, PEEK_AXIS, sample);
|
||||||
|
if unsafe { peek_result.raw_equals(D(0)) } {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let unit_cell = peek_result.as_cell().expect("Peek should return unit");
|
||||||
|
Some(unit_cell.tail())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cg_poke(context: &mut Context, slow: Noun, subject: Noun, formula: Noun) {
|
||||||
|
assert!(!context.line.is_none());
|
||||||
|
let sample = T(
|
||||||
|
&mut context.stack,
|
||||||
|
&[D(tas!(b"comp")), slow, subject, formula],
|
||||||
|
);
|
||||||
|
let result = slam_line(context, POKE_AXIS, sample);
|
||||||
|
let new_line = slot(result, 7).expect("Poke should return triple");
|
||||||
|
context.line = new_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the $pile for an arm, possibly updating the line core
|
||||||
|
fn cg_indirect(
|
||||||
|
context: &mut Context,
|
||||||
|
hill: &mut Noun,
|
||||||
|
slow: Noun,
|
||||||
|
subject: Noun,
|
||||||
|
formula: Noun,
|
||||||
|
) -> Noun {
|
||||||
|
let bell_hill = if let Some(res) = cg_peek(context, subject, formula) {
|
||||||
|
res
|
||||||
|
} else {
|
||||||
|
cg_poke(context, slow, subject, formula);
|
||||||
|
cg_peek(context, subject, formula).expect("Codegen peek should return value after poke.")
|
||||||
|
};
|
||||||
|
let bell_hill_cell = bell_hill
|
||||||
|
.as_cell()
|
||||||
|
.expect("Codegen successful peek should return pair");
|
||||||
|
get_by(
|
||||||
|
&mut context.stack,
|
||||||
|
&mut bell_hill_cell.tail(),
|
||||||
|
&mut bell_hill_cell.head(),
|
||||||
|
)
|
||||||
|
.expect("Codegen bell lookup should succeed.")
|
||||||
|
.expect("Codegen peek bell should be in hill")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cg_interpret(context: &mut Context, slow: Noun, subject: Noun, formula: Noun) -> Result {
|
||||||
|
let mut hill = NOUN_NONE;
|
||||||
|
let outer_pile = cg_indirect(context, &mut hill, slow, subject, formula);
|
||||||
|
let virtual_frame = context.stack.get_frame_pointer();
|
||||||
|
push_outer_frame(&mut context.stack, outer_pile);
|
||||||
|
let mut wish = pile_wish(outer_pile);
|
||||||
|
let (mut body, mut bend) = get_blob(context, outer_pile, &mut wish);
|
||||||
|
let sire = pile_sire(outer_pile);
|
||||||
|
(unsafe { Frame::current_mut(&context.stack).vars_mut() })[sire] = subject;
|
||||||
|
let inner_res = 'interpret: loop {
|
||||||
|
let frame = unsafe { Frame::current_mut(&context.stack) };
|
||||||
|
if let Ok(body_cell) = body.as_cell() {
|
||||||
|
body = body_cell.tail();
|
||||||
|
let inst_cell = body_cell
|
||||||
|
.head()
|
||||||
|
.as_cell()
|
||||||
|
.expect("Codegen instruction should be a cell");
|
||||||
|
let inst_tag = inst_cell
|
||||||
|
.head()
|
||||||
|
.as_atom()
|
||||||
|
.expect("Codegen instruction tag should be atom")
|
||||||
|
.as_u64()
|
||||||
|
.expect("codegen instruction tag should convert to u64");
|
||||||
|
match inst_tag {
|
||||||
|
tas!(b"imm") => {
|
||||||
|
let imm_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let imm_n = imm_cell.head();
|
||||||
|
let imm_d = imm_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
frame.vars_mut()[imm_d] = imm_n;
|
||||||
|
}
|
||||||
|
tas!(b"mov") => {
|
||||||
|
let mov_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let mov_s = mov_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let mov_d = mov_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
frame.vars_mut()[mov_d] = frame.vars()[mov_s];
|
||||||
|
}
|
||||||
|
tas!(b"inc") => {
|
||||||
|
let inc_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let inc_s = inc_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let inc_d = inc_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
if let Ok(s_atom) = frame.vars()[inc_s].as_atom() {
|
||||||
|
frame.vars_mut()[inc_d] = inc(&mut context.stack, s_atom).as_noun();
|
||||||
|
} else {
|
||||||
|
break BAIL_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tas!(b"con") => {
|
||||||
|
let con_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let con_h = con_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let con_tell = con_cell.tail().as_cell().unwrap();
|
||||||
|
let con_t = con_tell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let con_d = con_tell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
frame.vars_mut()[con_d] = T(
|
||||||
|
&mut context.stack,
|
||||||
|
&[frame.vars()[con_h], frame.vars()[con_t]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tas!(b"hed") => {
|
||||||
|
let hed_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let hed_s = hed_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let hed_d = hed_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let s_noun = frame.vars()[hed_s];
|
||||||
|
if s_noun.is_none() {
|
||||||
|
frame.vars_mut()[hed_d] = NOUN_NONE;
|
||||||
|
} else if let Ok(s_cell) = frame.vars()[hed_s].as_cell() {
|
||||||
|
frame.vars_mut()[hed_d] = s_cell.head();
|
||||||
|
} else {
|
||||||
|
frame.vars_mut()[hed_d] = NOUN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tas!(b"tal") => {
|
||||||
|
let tal_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let tal_s = tal_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let tal_d = tal_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let s_noun = frame.vars()[tal_s];
|
||||||
|
if s_noun.is_none() {
|
||||||
|
frame.vars_mut()[tal_d] = NOUN_NONE;
|
||||||
|
} else if let Ok(s_cell) = frame.vars()[tal_s].as_cell() {
|
||||||
|
frame.vars_mut()[tal_d] = s_cell.tail();
|
||||||
|
} else {
|
||||||
|
frame.vars_mut()[tal_d] = NOUN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tas!(b"men") => {
|
||||||
|
let men_cell = inst_cell.tail().as_cell().unwrap();
|
||||||
|
let men_l = men_cell.head();
|
||||||
|
assert!(men_l.is_atom());
|
||||||
|
let men_s = men_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let men_entry = T(&mut context.stack, &[men_l, frame.vars()[men_s]]);
|
||||||
|
frame.mean = T(&mut context.stack, &[men_entry, frame.mean])
|
||||||
|
}
|
||||||
|
tas!(b"man") => {
|
||||||
|
frame.mean = frame.mean.as_cell().unwrap().tail();
|
||||||
|
}
|
||||||
|
tas!(b"slo") => {
|
||||||
|
let slo_s = inst_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
let slo_tag = frame.vars()[slo_s];
|
||||||
|
assert!(slo_tag.is_atom());
|
||||||
|
frame.slow = T(&mut context.stack, &[slo_tag, frame.slow]);
|
||||||
|
}
|
||||||
|
tas!(b"sld") => {
|
||||||
|
frame.slow = frame.slow.as_cell().unwrap().tail();
|
||||||
|
todo!("sld")
|
||||||
|
}
|
||||||
|
tas!(b"hit") => {
|
||||||
|
// XX TODO implement
|
||||||
|
}
|
||||||
|
tas!(b"slg") => {
|
||||||
|
let slg_s = inst_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
context
|
||||||
|
.newt
|
||||||
|
.slog(&mut context.stack, 0, frame.vars()[slg_s]);
|
||||||
|
}
|
||||||
|
tas!(b"mew") => {
|
||||||
|
// XX TODO implement
|
||||||
|
}
|
||||||
|
tas!(b"tim") => {
|
||||||
|
// XX TODO implement
|
||||||
|
}
|
||||||
|
tas!(b"tom") => {
|
||||||
|
// XX TODO implement
|
||||||
|
}
|
||||||
|
tas!(b"mem") => {
|
||||||
|
// XX TODO implement
|
||||||
|
}
|
||||||
|
tas!(b"poi") => {
|
||||||
|
let poi_p = inst_cell.tail().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
frame.vars_mut()[poi_p] = NOUN_NONE;
|
||||||
|
}
|
||||||
|
tas!(b"ipb") => {
|
||||||
|
let mut ipb_p = inst_cell.tail();
|
||||||
|
'ipb: loop {
|
||||||
|
if unsafe { ipb_p.raw_equals(D(0)) } {
|
||||||
|
break 'ipb;
|
||||||
|
} else {
|
||||||
|
let p_cell = ipb_p.as_cell().unwrap();
|
||||||
|
ipb_p = p_cell.tail();
|
||||||
|
let p_i = p_cell.head().as_atom().unwrap().as_u64().unwrap() as usize;
|
||||||
|
if frame.vars()[p_i].is_none() {
|
||||||
|
break 'interpret BAIL_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Codegen instruction unsupported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let inst_cell = bend
|
||||||
|
.as_cell()
|
||||||
|
.expect("Codegen instruction should be a cell");
|
||||||
|
let inst_tag = inst_cell
|
||||||
|
.head()
|
||||||
|
.as_atom()
|
||||||
|
.expect("Codegen instruction tag should be atom")
|
||||||
|
.as_u64()
|
||||||
|
.expect("codegen instruction tag should convert to u64");
|
||||||
|
match inst_tag {
|
||||||
|
tas!(b"clq") => {
|
||||||
|
todo!("clq")
|
||||||
|
}
|
||||||
|
tas!(b"eqq") => {
|
||||||
|
todo!("eqq")
|
||||||
|
}
|
||||||
|
tas!(b"brn") => {
|
||||||
|
todo!("brn")
|
||||||
|
}
|
||||||
|
tas!(b"hop") => {
|
||||||
|
todo!("hop")
|
||||||
|
}
|
||||||
|
tas!(b"hip") => {
|
||||||
|
todo!("hip")
|
||||||
|
}
|
||||||
|
tas!(b"lnk") => {
|
||||||
|
todo!("lnk")
|
||||||
|
}
|
||||||
|
tas!(b"cal") => {
|
||||||
|
todo!("cal")
|
||||||
|
}
|
||||||
|
tas!(b"caf") => {
|
||||||
|
todo!("caf")
|
||||||
|
}
|
||||||
|
tas!(b"lnt") => {
|
||||||
|
todo!("lnt")
|
||||||
|
}
|
||||||
|
tas!(b"jmp") => {
|
||||||
|
todo!("jmp")
|
||||||
|
}
|
||||||
|
tas!(b"jmf") => {
|
||||||
|
todo!("jmf")
|
||||||
|
}
|
||||||
|
tas!(b"spy") => {
|
||||||
|
todo!("spy")
|
||||||
|
}
|
||||||
|
tas!(b"mer") => {
|
||||||
|
todo!("mer")
|
||||||
|
}
|
||||||
|
tas!(b"don") => {
|
||||||
|
todo!("don")
|
||||||
|
}
|
||||||
|
tas!(b"bom") => {
|
||||||
|
todo!("bom")
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Codegen instruction unsupported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match inner_res {
|
||||||
|
Ok(res) => inner_res,
|
||||||
|
Err(err) => exit(context, err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Crash with an
|
||||||
|
fn exit(context: &mut Context, err: Error) -> Result {
|
||||||
|
todo!("exit")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pile_sans(pile: Noun) -> usize {
|
||||||
|
(slot(pile, 127)
|
||||||
|
.expect("Codegen pile should have sans face")
|
||||||
|
.as_atom()
|
||||||
|
.expect("Codegen sans should be atom")
|
||||||
|
.as_u64()
|
||||||
|
.expect("Codegen sans too big")) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pile_wish(pile: Noun) -> Noun {
|
||||||
|
slot(pile, 30).expect("Codegen pile should have wish face")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pile_sire(pile: Noun) -> usize {
|
||||||
|
(slot(pile, 62)
|
||||||
|
.expect("Codegen pile should have sire face")
|
||||||
|
.as_atom()
|
||||||
|
.expect("Codegen sire should be atom")
|
||||||
|
.as_u64()
|
||||||
|
.expect("Codegen sire too big")) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pile_will(pile: Noun) -> Noun {
|
||||||
|
slot(pile, 126).expect("Codegen pile should have will face")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_blob(context: &mut Context, pile: Noun, bile: &mut Noun) -> (Noun, Noun) {
|
||||||
|
let mut will = pile_will(pile);
|
||||||
|
let blob_with_biff = get_by(&mut context.stack, &mut will, bile)
|
||||||
|
.expect("Codegen bile lookup successful")
|
||||||
|
.expect("Codegen will has bile");
|
||||||
|
let blob_cell = slot(blob_with_biff, 3)
|
||||||
|
.expect("Codegen blob has tail")
|
||||||
|
.as_cell()
|
||||||
|
.expect("Codegen blob tail should be cell");
|
||||||
|
(blob_cell.head(), blob_cell.tail())
|
||||||
|
}
|
@ -268,6 +268,7 @@ pub struct Context {
|
|||||||
pub cold: Cold,
|
pub cold: Cold,
|
||||||
pub warm: Warm,
|
pub warm: Warm,
|
||||||
pub hot: Hot,
|
pub hot: Hot,
|
||||||
|
pub line: Noun,
|
||||||
pub cache: Hamt<Noun>,
|
pub cache: Hamt<Noun>,
|
||||||
pub scry_stack: Noun,
|
pub scry_stack: Noun,
|
||||||
pub trace_info: Option<TraceInfo>,
|
pub trace_info: Option<TraceInfo>,
|
||||||
@ -360,7 +361,7 @@ impl From<cold::Error> for Error {
|
|||||||
|
|
||||||
pub type Result = result::Result<Noun, Error>;
|
pub type Result = result::Result<Noun, Error>;
|
||||||
|
|
||||||
const BAIL_EXIT: Result = Err(Error::Deterministic(Mote::Exit, D(0)));
|
pub const BAIL_EXIT: Result = Err(Error::Deterministic(Mote::Exit, D(0)));
|
||||||
const BAIL_FAIL: Result = Err(Error::NonDeterministic(Mote::Fail, D(0)));
|
const BAIL_FAIL: Result = Err(Error::NonDeterministic(Mote::Fail, D(0)));
|
||||||
const BAIL_INTR: Result = Err(Error::NonDeterministic(Mote::Intr, D(0)));
|
const BAIL_INTR: Result = Err(Error::NonDeterministic(Mote::Intr, D(0)));
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ pub mod util {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::hamt::Hamt;
|
use crate::hamt::Hamt;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::noun::{Atom, Noun, D, T};
|
use crate::noun::{Atom, Noun, D, NOUN_NONE, T};
|
||||||
use crate::unifying_equality::unifying_equality;
|
use crate::unifying_equality::unifying_equality;
|
||||||
use assert_no_alloc::assert_no_alloc;
|
use assert_no_alloc::assert_no_alloc;
|
||||||
use ibig::UBig;
|
use ibig::UBig;
|
||||||
@ -322,6 +322,7 @@ pub mod util {
|
|||||||
let warm = Warm::new(&mut stack);
|
let warm = Warm::new(&mut stack);
|
||||||
let hot = Hot::init(&mut stack, URBIT_HOT_STATE);
|
let hot = Hot::init(&mut stack, URBIT_HOT_STATE);
|
||||||
let cache = Hamt::<Noun>::new(&mut stack);
|
let cache = Hamt::<Noun>::new(&mut stack);
|
||||||
|
let line = NOUN_NONE;
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
stack,
|
stack,
|
||||||
@ -330,6 +331,7 @@ pub mod util {
|
|||||||
warm,
|
warm,
|
||||||
hot,
|
hot,
|
||||||
cache,
|
cache,
|
||||||
|
line,
|
||||||
scry_stack: D(0),
|
scry_stack: D(0),
|
||||||
trace_info: None,
|
trace_info: None,
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
// use crate::jets::util::*;
|
// use crate::jets::util::*;
|
||||||
// use crate::jets::Result;
|
// use crate::jets::Result;
|
||||||
// use crate::noun::{IndirectAtom, Noun, D};
|
// use crate::noun::{IndirectAtom, Noun, D};
|
||||||
|
|
||||||
use self::util::*;
|
use self::util::*;
|
||||||
|
|
||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
@ -13,14 +12,14 @@ crate::gdb!();
|
|||||||
// XX TODO actual jets
|
// XX TODO actual jets
|
||||||
|
|
||||||
pub mod util {
|
pub mod util {
|
||||||
use crate::mug::mug_u32;
|
|
||||||
use crate::unifying_equality::unifying_equality;
|
|
||||||
use crate::mem::NockStack;
|
|
||||||
use crate::jets::math::util::lth_b;
|
use crate::jets::math::util::lth_b;
|
||||||
use crate::jets::util::slot;
|
use crate::jets::util::slot;
|
||||||
use crate::noun::{Noun, D};
|
|
||||||
use either::Either::*;
|
|
||||||
use crate::jets::JetErr;
|
use crate::jets::JetErr;
|
||||||
|
use crate::mem::NockStack;
|
||||||
|
use crate::mug::mug_u32;
|
||||||
|
use crate::noun::{Noun, D};
|
||||||
|
use crate::unifying_equality::unifying_equality;
|
||||||
|
use either::Either::*;
|
||||||
|
|
||||||
pub fn dor_b(stack: &mut NockStack, a: &mut Noun, b: &mut Noun) -> bool {
|
pub fn dor_b(stack: &mut NockStack, a: &mut Noun, b: &mut Noun) -> bool {
|
||||||
let mut ap = a as *mut Noun;
|
let mut ap = a as *mut Noun;
|
||||||
@ -38,10 +37,14 @@ pub mod util {
|
|||||||
} else {
|
} else {
|
||||||
break true;
|
break true;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Right(a_cell) => {
|
Right(a_cell) => {
|
||||||
if let Ok(b_cell) = (*bp).as_cell() {
|
if let Ok(b_cell) = (*bp).as_cell() {
|
||||||
if unifying_equality(stack, a_cell.head_as_mut(), b_cell.head_as_mut()) {
|
if unifying_equality(
|
||||||
|
stack,
|
||||||
|
a_cell.head_as_mut(),
|
||||||
|
b_cell.head_as_mut(),
|
||||||
|
) {
|
||||||
ap = a_cell.tail_as_mut();
|
ap = a_cell.tail_as_mut();
|
||||||
bp = b_cell.tail_as_mut();
|
bp = b_cell.tail_as_mut();
|
||||||
continue;
|
continue;
|
||||||
@ -70,7 +73,11 @@ pub mod util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_by(stack: &mut NockStack, a: &mut Noun, b: &mut Noun) -> Result<Option<Noun>, JetErr> {
|
pub fn get_by(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
a: &mut Noun,
|
||||||
|
b: &mut Noun,
|
||||||
|
) -> Result<Option<Noun>, JetErr> {
|
||||||
let mut ap = a as *mut Noun;
|
let mut ap = a as *mut Noun;
|
||||||
let bp = b as *mut Noun;
|
let bp = b as *mut Noun;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -3,6 +3,7 @@ extern crate num_derive;
|
|||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate static_assertions;
|
extern crate static_assertions;
|
||||||
|
pub mod codegen;
|
||||||
pub mod flog;
|
pub mod flog;
|
||||||
pub mod guard;
|
pub mod guard;
|
||||||
pub mod hamt;
|
pub mod hamt;
|
||||||
|
@ -9,7 +9,7 @@ use memmap::MmapMut;
|
|||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::copy_nonoverlapping;
|
use std::ptr::{copy, copy_nonoverlapping};
|
||||||
|
|
||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
|
|
||||||
@ -146,6 +146,45 @@ impl NockStack {
|
|||||||
self.frame_pointer
|
self.frame_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_frame_base(&self) -> *mut u64 {
|
||||||
|
if self.is_west() {
|
||||||
|
unsafe { *(self.prev_alloc_pointer_pointer()) }
|
||||||
|
} else {
|
||||||
|
unsafe { self.frame_pointer.add(RESERVED) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn resize_frame(&mut self, new_size: usize) {
|
||||||
|
// lightweight stack must be empty
|
||||||
|
assert!(self.stack_pointer == self.frame_pointer);
|
||||||
|
let raw_new_size = (new_size + RESERVED) as isize;
|
||||||
|
if self.is_west() {
|
||||||
|
let current_size = self
|
||||||
|
.frame_pointer
|
||||||
|
.offset_from(*(self.prev_alloc_pointer_pointer()));
|
||||||
|
assert!(current_size >= RESERVED as isize);
|
||||||
|
let offset = raw_new_size - current_size;
|
||||||
|
let new_frame_pointer = self.frame_pointer.offset(offset);
|
||||||
|
copy(
|
||||||
|
self.frame_pointer.sub(RESERVED),
|
||||||
|
new_frame_pointer.sub(RESERVED),
|
||||||
|
RESERVED,
|
||||||
|
);
|
||||||
|
self.frame_pointer = new_frame_pointer;
|
||||||
|
self.stack_pointer = new_frame_pointer;
|
||||||
|
} else {
|
||||||
|
let current_size =
|
||||||
|
(*(self.prev_alloc_pointer_pointer())).offset_from(self.frame_pointer);
|
||||||
|
assert!(current_size >= RESERVED as isize);
|
||||||
|
let offset = current_size - raw_new_size;
|
||||||
|
let new_frame_pointer = self.frame_pointer.offset(offset);
|
||||||
|
let copy_size = current_size.min(raw_new_size);
|
||||||
|
copy(self.frame_pointer, new_frame_pointer, RESERVED);
|
||||||
|
self.frame_pointer = new_frame_pointer;
|
||||||
|
self.stack_pointer = new_frame_pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Current stack pointer of this NockStack */
|
/** Current stack pointer of this NockStack */
|
||||||
pub fn get_stack_pointer(&self) -> *const u64 {
|
pub fn get_stack_pointer(&self) -> *const u64 {
|
||||||
self.stack_pointer
|
self.stack_pointer
|
||||||
|
@ -31,6 +31,9 @@ const CELL_TAG: u64 = u64::MAX & INDIRECT_MASK;
|
|||||||
/** Tag mask for a cell. */
|
/** Tag mask for a cell. */
|
||||||
const CELL_MASK: u64 = !(u64::MAX >> 3);
|
const CELL_MASK: u64 = !(u64::MAX >> 3);
|
||||||
|
|
||||||
|
const NONE_BITS: u64 = !(u64::MAX >> 3);
|
||||||
|
pub const NOUN_NONE: Noun = Noun { raw: NONE_BITS };
|
||||||
|
|
||||||
/* A note on forwarding pointers:
|
/* A note on forwarding pointers:
|
||||||
*
|
*
|
||||||
* Forwarding pointers are only used temporarily during copies between NockStack frames and between
|
* Forwarding pointers are only used temporarily during copies between NockStack frames and between
|
||||||
@ -155,6 +158,10 @@ fn is_cell(noun: u64) -> bool {
|
|||||||
noun & CELL_MASK == CELL_TAG
|
noun & CELL_MASK == CELL_TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_none(noun: u64) -> bool {
|
||||||
|
noun == NONE_BITS
|
||||||
|
}
|
||||||
|
|
||||||
/** A noun-related error. */
|
/** A noun-related error. */
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -1023,14 +1030,16 @@ pub union Noun {
|
|||||||
|
|
||||||
impl Noun {
|
impl Noun {
|
||||||
pub fn is_none(self) -> bool {
|
pub fn is_none(self) -> bool {
|
||||||
unsafe { self.raw == u64::MAX }
|
unsafe { is_none(self.raw) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_direct(&self) -> bool {
|
pub fn is_direct(&self) -> bool {
|
||||||
|
assert!(!self.is_none());
|
||||||
unsafe { is_direct_atom(self.raw) }
|
unsafe { is_direct_atom(self.raw) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_indirect(&self) -> bool {
|
pub fn is_indirect(&self) -> bool {
|
||||||
|
assert!(!self.is_none());
|
||||||
unsafe { is_indirect_atom(self.raw) }
|
unsafe { is_indirect_atom(self.raw) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1043,6 +1052,7 @@ impl Noun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_cell(&self) -> bool {
|
pub fn is_cell(&self) -> bool {
|
||||||
|
assert!(!self.is_none());
|
||||||
unsafe { is_cell(self.raw) }
|
unsafe { is_cell(self.raw) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use crate::jets::warm::Warm;
|
|||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::mug::*;
|
use crate::mug::*;
|
||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
use crate::noun::{Atom, Cell, DirectAtom, Noun, Slots, D, T};
|
use crate::noun::{Atom, Cell, DirectAtom, Noun, Slots, D, NOUN_NONE, T};
|
||||||
use crate::persist::pma_meta_set;
|
use crate::persist::pma_meta_set;
|
||||||
use crate::persist::{pma_meta_get, pma_open, pma_sync, Persist};
|
use crate::persist::{pma_meta_get, pma_open, pma_sync, Persist};
|
||||||
use crate::trace::*;
|
use crate::trace::*;
|
||||||
@ -172,6 +172,7 @@ impl Context {
|
|||||||
cache,
|
cache,
|
||||||
scry_stack: D(0),
|
scry_stack: D(0),
|
||||||
trace_info,
|
trace_info,
|
||||||
|
line: NOUN_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
|
Loading…
Reference in New Issue
Block a user