mirror of
https://github.com/urbit/ares.git
synced 2024-11-27 05:06:32 +03:00
Merge pull request #60 from urbit/jon/stack-split-mem-rewrite
split stack
This commit is contained in:
commit
08690675f1
2
rust/ares/Cargo.lock
generated
2
rust/ares/Cargo.lock
generated
@ -363,7 +363,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "murmur3"
|
||||
version = "0.5.2"
|
||||
source = "git+https://github.com/tloncorp/murmur3?branch=eamsden/non_copying#dde46823a87f358eee5a928c27e2731f9a53d616"
|
||||
source = "git+https://github.com/tloncorp/murmur3?rev=7878a0f#7878a0fbecf465720891b625f1a1fc3e19b6a960"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
|
@ -440,21 +440,21 @@ impl<T: Copy> Default for Hamt<T> {
|
||||
|
||||
impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
if stack.in_frame(self.0.buffer) {
|
||||
if stack.is_in_frame(self.0.buffer) {
|
||||
let dest_buffer = stack.struct_alloc_in_previous_frame(self.0.size());
|
||||
copy_nonoverlapping(self.0.buffer, dest_buffer, self.0.size());
|
||||
self.0.buffer = dest_buffer;
|
||||
let traversal_stack = stack.struct_alloc::<(Stem<T>, u32)>(6);
|
||||
*(stack.push::<(Stem<T>, u32)>()) = (self.0, 0);
|
||||
let mut traversal_depth = 1;
|
||||
*traversal_stack = (self.0, 0);
|
||||
'preserve: loop {
|
||||
if traversal_depth == 0 {
|
||||
break;
|
||||
}
|
||||
let (stem, mut position) = *traversal_stack.add(traversal_depth - 1);
|
||||
let (stem, mut position) = *(stack.top::<(Stem<T>, u32)>());
|
||||
// can we loop over the size and count leading 0s remaining in the bitmap?
|
||||
'preserve_stem: loop {
|
||||
if position >= 32 {
|
||||
stack.pop::<(Stem<T>, u32)>();
|
||||
traversal_depth -= 1;
|
||||
continue 'preserve;
|
||||
}
|
||||
@ -464,7 +464,7 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
continue 'preserve_stem;
|
||||
}
|
||||
Some((Left(next_stem), idx)) => {
|
||||
if stack.in_frame(next_stem.buffer) {
|
||||
if stack.is_in_frame(next_stem.buffer) {
|
||||
let dest_buffer =
|
||||
stack.struct_alloc_in_previous_frame(next_stem.size());
|
||||
copy_nonoverlapping(
|
||||
@ -479,8 +479,8 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
};
|
||||
*(stem.buffer.add(idx) as *mut Entry<T>) = Entry { stem: new_stem };
|
||||
assert!(traversal_depth <= 5); // will increment
|
||||
(*traversal_stack.add(traversal_depth - 1)).1 = position + 1;
|
||||
*traversal_stack.add(traversal_depth) = (new_stem, 0);
|
||||
(*(stack.top::<(Stem<T>, u32)>())).1 = position + 1;
|
||||
*(stack.push::<(Stem<T>, u32)>()) = (new_stem, 0);
|
||||
traversal_depth += 1;
|
||||
continue 'preserve;
|
||||
} else {
|
||||
@ -489,7 +489,7 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
}
|
||||
}
|
||||
Some((Right(leaf), idx)) => {
|
||||
if stack.in_frame(leaf.buffer) {
|
||||
if stack.is_in_frame(leaf.buffer) {
|
||||
let dest_buffer = stack.struct_alloc_in_previous_frame(leaf.len);
|
||||
copy_nonoverlapping(leaf.buffer, dest_buffer, leaf.len);
|
||||
let new_leaf = Leaf {
|
||||
|
@ -77,7 +77,7 @@ pub fn interpret(
|
||||
formula: Noun,
|
||||
) -> Noun {
|
||||
let mut res = unsafe { DirectAtom::new_unchecked(0).as_atom().as_noun() };
|
||||
stack.push(1);
|
||||
stack.frame_push(1);
|
||||
let mut cache = Hamt::<Noun>::new();
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Done);
|
||||
@ -89,7 +89,7 @@ pub fn interpret(
|
||||
Done => {
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
break;
|
||||
}
|
||||
NockCellComputeHead => {
|
||||
@ -106,25 +106,28 @@ pub fn interpret(
|
||||
NockCellCons => {
|
||||
let head = *stack.local_noun_pointer(1);
|
||||
res = Cell::new(stack, head, res).as_noun();
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock0Axis => {
|
||||
if let Ok(atom) = (*(stack.local_noun_pointer(1))).as_atom() {
|
||||
res = slot(subject, atom.as_bitslice());
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
panic!("Axis must be atom");
|
||||
};
|
||||
}
|
||||
Nock1Constant => {
|
||||
res = *(stack.local_noun_pointer(1));
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock2ComputeSubject => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock2ComputeFormula);
|
||||
@ -145,9 +148,10 @@ pub fn interpret(
|
||||
}
|
||||
Nock2RestoreSubject => {
|
||||
subject = *(stack.local_noun_pointer(2));
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock3ComputeChild => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock3ComputeType);
|
||||
@ -160,9 +164,10 @@ pub fn interpret(
|
||||
} else {
|
||||
DirectAtom::new_unchecked(1).as_atom().as_noun()
|
||||
};
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock4ComputeChild => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock4Increment);
|
||||
@ -172,9 +177,10 @@ pub fn interpret(
|
||||
Nock4Increment => {
|
||||
if let Ok(atom) = res.as_atom() {
|
||||
res = inc(stack, atom).as_noun();
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
panic!("Cannot increment (Nock 4) a cell");
|
||||
};
|
||||
@ -197,9 +203,10 @@ pub fn interpret(
|
||||
} else {
|
||||
DirectAtom::new_unchecked(1).as_atom().as_noun()
|
||||
};
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock6ComputeTest => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock6ComputeBranch);
|
||||
@ -225,7 +232,7 @@ pub fn interpret(
|
||||
Nock6Done => {
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock7ComputeSubject => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock7ComputeResult);
|
||||
@ -241,9 +248,10 @@ pub fn interpret(
|
||||
}
|
||||
Nock7RestoreSubject => {
|
||||
subject = *(stack.local_noun_pointer(1));
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock8ComputeSubject => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock8ComputeResult);
|
||||
@ -259,9 +267,10 @@ pub fn interpret(
|
||||
}
|
||||
Nock8RestoreSubject => {
|
||||
subject = *(stack.local_noun_pointer(1));
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock9ComputeCore => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock9ComputeResult);
|
||||
@ -280,9 +289,10 @@ pub fn interpret(
|
||||
}
|
||||
Nock9RestoreSubject => {
|
||||
subject = *(stack.local_noun_pointer(2));
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
Nock10ComputeTree => {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock10ComputePatch);
|
||||
@ -299,9 +309,10 @@ pub fn interpret(
|
||||
if let Ok(edit_axis) = (*stack.local_noun_pointer(1)).as_atom() {
|
||||
let tree = *stack.local_noun_pointer(3);
|
||||
res = edit(stack, edit_axis.as_bitslice(), res, tree);
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
panic!("Axis into tree must be atom");
|
||||
}
|
||||
@ -314,9 +325,10 @@ pub fn interpret(
|
||||
match_pre_hint(stack, newt, subject, hint_cell, formula, &cache)
|
||||
{
|
||||
res = found;
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11ComputeResult);
|
||||
push_formula(stack, hint_cell.tail());
|
||||
@ -329,9 +341,10 @@ pub fn interpret(
|
||||
let hint = *stack.local_noun_pointer(1);
|
||||
if let Ok(found) = match_post_hint(stack, newt, subject, hint, res) {
|
||||
res = found;
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11Done);
|
||||
let formula = *stack.local_noun_pointer(2);
|
||||
@ -341,9 +354,10 @@ pub fn interpret(
|
||||
Nock11Done => {
|
||||
let hint = *stack.local_noun_pointer(1);
|
||||
let _ = match_post_hinted(stack, subject, hint, res, &mut cache);
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -356,7 +370,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
// Formula
|
||||
match formula_cell.head().as_either_atom_cell() {
|
||||
Right(_cell) => {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(NockCellComputeHead);
|
||||
*(stack.local_noun_pointer(1)) = formula_cell.head();
|
||||
@ -367,14 +381,14 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
if let Ok(direct) = atom.as_direct() {
|
||||
match direct.data() {
|
||||
0 => {
|
||||
stack.push(2);
|
||||
stack.frame_push(2);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock0Axis);
|
||||
*(stack.local_noun_pointer(1)) = formula_cell.tail();
|
||||
};
|
||||
}
|
||||
1 => {
|
||||
stack.push(2);
|
||||
stack.frame_push(2);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock1Constant);
|
||||
*(stack.local_noun_pointer(1)) = formula_cell.tail();
|
||||
@ -382,7 +396,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
2 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock2ComputeSubject);
|
||||
@ -394,14 +408,14 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
};
|
||||
}
|
||||
3 => {
|
||||
stack.push(2);
|
||||
stack.frame_push(2);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock3ComputeChild);
|
||||
*(stack.local_noun_pointer(1)) = formula_cell.tail();
|
||||
};
|
||||
}
|
||||
4 => {
|
||||
stack.push(2);
|
||||
stack.frame_push(2);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock4ComputeChild);
|
||||
*(stack.local_noun_pointer(1)) = formula_cell.tail();
|
||||
@ -409,7 +423,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
5 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock5ComputeLeftChild);
|
||||
@ -423,7 +437,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
6 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
if let Ok(branch_cell) = arg_cell.tail().as_cell() {
|
||||
stack.push(4);
|
||||
stack.frame_push(4);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock6ComputeTest);
|
||||
@ -440,7 +454,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
7 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock7ComputeSubject);
|
||||
@ -453,7 +467,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
8 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock8ComputeSubject);
|
||||
@ -466,7 +480,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
9 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock9ComputeCore);
|
||||
*(stack.local_noun_pointer(1)) = arg_cell.head();
|
||||
@ -479,7 +493,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
10 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
if let Ok(patch_cell) = arg_cell.head().as_cell() {
|
||||
stack.push(4);
|
||||
stack.frame_push(4);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(Nock10ComputeTree);
|
||||
@ -496,7 +510,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
|
||||
}
|
||||
11 => {
|
||||
if let Ok(arg_cell) = formula_cell.tail().as_cell() {
|
||||
stack.push(3);
|
||||
stack.frame_push(3);
|
||||
unsafe {
|
||||
*(stack.local_noun_pointer(0)) =
|
||||
work_to_noun(if arg_cell.head().is_cell() {
|
||||
|
@ -43,7 +43,7 @@ fn main() -> io::Result<()> {
|
||||
let in_map = Mmap::map(&f)?;
|
||||
let word_len = (in_len + 7) >> 3;
|
||||
let (mut atom, dest) = IndirectAtom::new_raw_mut(&mut stack, word_len as usize);
|
||||
write_bytes(dest.add(word_len as usize - 1), 0, 8);
|
||||
write_bytes(dest.add(word_len as usize - 1), 0, 1);
|
||||
copy_nonoverlapping(in_map.as_ptr(), dest as *mut u8, in_len as usize);
|
||||
mem::drop(in_map);
|
||||
atom.normalize_as_atom()
|
||||
|
1012
rust/ares/src/mem.rs
1012
rust/ares/src/mem.rs
File diff suppressed because it is too large
Load Diff
@ -120,46 +120,44 @@ pub fn mug_u32(stack: &mut NockStack, noun: Noun) -> u32 {
|
||||
return mug;
|
||||
}
|
||||
assert_acyclic!(noun);
|
||||
stack.push(1);
|
||||
unsafe {
|
||||
stack.save_prev_stack_pointer_to_local(0);
|
||||
*(stack.alloc_in_previous_frame()) = noun;
|
||||
*(stack.push()) = noun;
|
||||
}
|
||||
loop {
|
||||
if unsafe { stack.prev_stack_pointer_equals_local(0) } {
|
||||
if stack.stack_is_empty() {
|
||||
break;
|
||||
} else {
|
||||
let noun: Noun = unsafe { *(stack.top_in_previous_frame()) };
|
||||
let noun: Noun = unsafe { *(stack.top()) };
|
||||
match noun.as_either_direct_allocated() {
|
||||
Left(_direct) => {
|
||||
unsafe {
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
}
|
||||
continue;
|
||||
} // no point in calculating a direct mug here as we wont cache it
|
||||
Right(allocated) => match allocated.get_cached_mug() {
|
||||
Some(_mug) => {
|
||||
unsafe {
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
None => match allocated.as_either() {
|
||||
Left(indirect) => unsafe {
|
||||
set_mug(allocated, calc_atom_mug_u32(indirect.as_atom()));
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
continue;
|
||||
},
|
||||
Right(cell) => unsafe {
|
||||
match (get_mug(cell.head()), get_mug(cell.tail())) {
|
||||
(Some(head_mug), Some(tail_mug)) => {
|
||||
set_mug(allocated, calc_cell_mug_u32(head_mug, tail_mug));
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
continue;
|
||||
}
|
||||
_ => {
|
||||
*(stack.alloc_in_previous_frame()) = cell.tail();
|
||||
*(stack.alloc_in_previous_frame()) = cell.head();
|
||||
*(stack.push()) = cell.tail();
|
||||
*(stack.push()) = cell.head();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -169,10 +167,7 @@ pub fn mug_u32(stack: &mut NockStack, noun: Noun) -> u32 {
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
stack.pop();
|
||||
get_mug(noun).expect("Noun should have a mug once it is mugged.")
|
||||
}
|
||||
get_mug(noun).expect("Noun should have a mug once it is mugged.")
|
||||
}
|
||||
|
||||
pub fn mug(stack: &mut NockStack, noun: Noun) -> DirectAtom {
|
||||
|
@ -910,8 +910,8 @@ impl Noun {
|
||||
/** Produce the size of a noun in the current frame, in words */
|
||||
pub fn mass_frame(self, stack: &NockStack) -> usize {
|
||||
unsafe {
|
||||
let res = self.mass_wind(&|p| stack.in_frame(p));
|
||||
self.mass_unwind(&|p| stack.in_frame(p));
|
||||
let res = self.mass_wind(&|p| stack.is_in_frame(p));
|
||||
self.mass_unwind(&|p| stack.is_in_frame(p));
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -27,22 +27,21 @@ pub fn cue(stack: &mut NockStack, buffer: Atom) -> Noun {
|
||||
let buffer_bitslice = buffer.as_bitslice();
|
||||
let mut cursor: usize = 0;
|
||||
let backref_map = MutHamt::<Noun>::new(stack);
|
||||
stack.push(2);
|
||||
stack.frame_push(1);
|
||||
unsafe {
|
||||
stack.save_prev_stack_pointer_to_local(0);
|
||||
*(stack.alloc_in_previous_frame()) = stack.local_noun_pointer(1);
|
||||
*(stack.push::<*mut Noun>()) = stack.local_noun_pointer(0);
|
||||
};
|
||||
loop {
|
||||
if unsafe { stack.prev_stack_pointer_equals_local(0) } {
|
||||
let mut result = unsafe { *(stack.local_noun_pointer(1)) };
|
||||
if stack.stack_is_empty() {
|
||||
let mut result = unsafe { *stack.local_noun_pointer(0) };
|
||||
assert_acyclic!(result);
|
||||
unsafe {
|
||||
stack.preserve(&mut result);
|
||||
stack.pop();
|
||||
stack.frame_pop();
|
||||
}
|
||||
break result;
|
||||
} else {
|
||||
let dest_ptr: *mut Noun = unsafe { *(stack.top_in_previous_frame()) };
|
||||
let dest_ptr: *mut Noun = unsafe { *(stack.top()) };
|
||||
if buffer_bitslice[cursor] {
|
||||
// 1 bit
|
||||
if buffer_bitslice[cursor + 1] {
|
||||
@ -60,7 +59,7 @@ pub fn cue(stack: &mut NockStack, buffer: Atom) -> Noun {
|
||||
}
|
||||
*dest_ptr = reffed_noun;
|
||||
assert_acyclic!(reffed_noun);
|
||||
stack.reclaim_in_previous_frame::<*mut Noun>();
|
||||
stack.pop::<*mut Noun>();
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
@ -72,15 +71,13 @@ pub fn cue(stack: &mut NockStack, buffer: Atom) -> Noun {
|
||||
*dest_ptr = cell.as_noun();
|
||||
let mut backref_atom = Atom::new(stack, backref as u64).as_noun();
|
||||
backref_map.insert(stack, &mut backref_atom, *dest_ptr);
|
||||
stack.reclaim_in_previous_frame::<*mut Noun>();
|
||||
stack.pop::<*mut Noun>();
|
||||
(*cell_mem_ptr).tail =
|
||||
DirectAtom::new_unchecked(0xEDBEEF).as_atom().as_noun();
|
||||
(*cell_mem_ptr).head =
|
||||
DirectAtom::new_unchecked(0xDEBEEF).as_atom().as_noun();
|
||||
*(stack.alloc_in_previous_frame::<*mut Noun>()) =
|
||||
&mut ((*cell_mem_ptr).tail);
|
||||
*(stack.alloc_in_previous_frame::<*mut Noun>()) =
|
||||
&mut ((*cell_mem_ptr).head);
|
||||
*(stack.push()) = &mut (*cell_mem_ptr).tail;
|
||||
*(stack.push()) = &mut (*cell_mem_ptr).head;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -92,7 +89,7 @@ pub fn cue(stack: &mut NockStack, buffer: Atom) -> Noun {
|
||||
*dest_ptr = rub_atom(stack, &mut cursor, buffer_bitslice).as_noun();
|
||||
let mut backref_atom = Atom::new(stack, backref as u64).as_noun();
|
||||
backref_map.insert(stack, &mut backref_atom, *dest_ptr);
|
||||
stack.reclaim_in_previous_frame::<*mut Noun>();
|
||||
stack.pop::<*mut Noun>();
|
||||
};
|
||||
continue;
|
||||
}
|
||||
@ -172,16 +169,14 @@ pub fn jam(stack: &mut NockStack, noun: Noun) -> Atom {
|
||||
atom,
|
||||
slice,
|
||||
};
|
||||
stack.push(1);
|
||||
unsafe {
|
||||
stack.save_prev_stack_pointer_to_local(0);
|
||||
*(stack.alloc_in_previous_frame()) = noun;
|
||||
*(stack.push::<Noun>()) = noun;
|
||||
};
|
||||
'jam: loop {
|
||||
if unsafe { stack.prev_stack_pointer_equals_local(0) } {
|
||||
if stack.stack_is_empty() {
|
||||
break;
|
||||
} else {
|
||||
let mut noun = unsafe { *(stack.top_in_previous_frame::<Noun>()) };
|
||||
let mut noun = unsafe { *(stack.top::<Noun>()) };
|
||||
if let Some(backref) = backref_map.lookup(stack, &mut noun) {
|
||||
match noun.as_either_atom_cell() {
|
||||
Left(atom) => {
|
||||
@ -198,7 +193,7 @@ pub fn jam(stack: &mut NockStack, noun: Noun) -> Atom {
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
};
|
||||
continue 'jam;
|
||||
};
|
||||
@ -207,28 +202,23 @@ pub fn jam(stack: &mut NockStack, noun: Noun) -> Atom {
|
||||
Left(atom) => {
|
||||
jam_atom(stack, &mut state, atom);
|
||||
unsafe {
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
stack.pop::<Noun>();
|
||||
};
|
||||
continue;
|
||||
}
|
||||
Right(cell) => {
|
||||
jam_cell(stack, &mut state);
|
||||
unsafe {
|
||||
stack.reclaim_in_previous_frame::<Noun>();
|
||||
*(stack.alloc_in_previous_frame()) = cell.tail();
|
||||
*(stack.alloc_in_previous_frame()) = cell.head();
|
||||
stack.pop::<Noun>();
|
||||
*(stack.push::<Noun>()) = cell.tail();
|
||||
*(stack.push::<Noun>()) = cell.head();
|
||||
};
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
let mut result = state.atom.normalize_as_atom();
|
||||
stack.preserve(&mut result);
|
||||
stack.pop();
|
||||
result
|
||||
}
|
||||
unsafe { state.atom.normalize_as_atom() }
|
||||
}
|
||||
|
||||
fn jam_atom(traversal: &mut NockStack, state: &mut JamState, atom: Atom) {
|
||||
|
1
rust/ares/test_data/decrement2.jam
Normal file
1
rust/ares/test_data/decrement2.jam
Normal file
@ -0,0 +1 @@
|
||||
аиA╟ь XvА√Ьa&vЦЙ ╡D6╖и░и
|
Loading…
Reference in New Issue
Block a user