fix copy_term/2 variable copying bug in lists (#923, #2127)

This commit is contained in:
Mark
2023-11-21 12:50:10 -07:00
parent a3e83d59be
commit 3841b29db8
6 changed files with 68 additions and 9 deletions

View File

@@ -18,6 +18,7 @@ pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
fn store(&self, value: HeapCellValue) -> HeapCellValue;
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
fn push(&mut self, value: HeapCellValue);
fn push_attr_var_queue(&mut self, attr_var_loc: usize);
fn stack(&mut self) -> &mut Stack;
fn threshold(&self) -> usize;
}
@@ -73,7 +74,6 @@ impl<T: CopierTarget> CopyTermState<T> {
if h >= self.old_h {
*self.value_at_scan() = list_loc_as_cell!(h);
self.scan += 1;
return;
}
}
@@ -96,14 +96,19 @@ impl<T: CopierTarget> CopyTermState<T> {
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
if !cdr.is_var() {
// mark addr + 1 as a list back edge in the cdr of the list
self.trail_list_cell(addr + 1, threshold);
self.target[addr + 1].set_mark_bit(true);
self.target[addr + 1].set_forwarding_bit(true);
} else {
let car = self
.target
.store(self.target.deref(heap_loc_as_cell!(addr)));
if !car.is_var() {
// mark addr as a list back edge in the car of the list
self.trail_list_cell(addr, threshold);
self.target[addr].set_mark_bit(true);
}
}
@@ -178,6 +183,7 @@ impl<T: CopierTarget> CopyTermState<T> {
for (threshold, list_loc) in iter {
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
self.target.push_attr_var_queue(threshold - 1);
self.copy_attr_var_list(list_loc);
}
}
@@ -263,6 +269,7 @@ impl<T: CopierTarget> CopyTermState<T> {
}
fn copy_var(&mut self, addr: HeapCellValue) {
let index = addr.get_value() as usize;
let rd = self.target.deref(addr);
let ra = self.target.store(rd);
@@ -271,7 +278,20 @@ impl<T: CopierTarget> CopyTermState<T> {
if h >= self.old_h {
*self.value_at_scan() = ra;
self.scan += 1;
return;
}
}
(HeapCellValueTag::Lis, h) => {
if h >= self.old_h && self.target[index].get_mark_bit() {
*self.value_at_scan() = heap_loc_as_cell!(
if ra.get_forwarding_bit() {
h + 1
} else {
h
}
);
self.scan += 1;
return;
}
}
@@ -356,12 +376,16 @@ impl<T: CopierTarget> CopyTermState<T> {
}
}
fn unwind_trail(&mut self) {
for (r, value) in self.trail.drain(0..) {
fn unwind_trail(mut self) {
for (r, value) in self.trail {
let index = r.get_value() as usize;
match r.get_tag() {
RefTag::AttrVar | RefTag::HeapCell => self.target[index] = value,
RefTag::AttrVar | RefTag::HeapCell => {
self.target[index] = value;
self.target[index].set_mark_bit(false);
self.target[index].set_forwarding_bit(false);
}
RefTag::StackCell => self.target.stack()[index] = value,
}
}