copy attributed variable attribute lists specially via copy_attr_var_list
This commit is contained in:
@@ -28,7 +28,10 @@ pub(crate) fn copy_term<T: CopierTarget>(
|
|||||||
attr_var_policy: AttrVarPolicy,
|
attr_var_policy: AttrVarPolicy,
|
||||||
) {
|
) {
|
||||||
let mut copy_term_state = CopyTermState::new(target, attr_var_policy);
|
let mut copy_term_state = CopyTermState::new(target, attr_var_policy);
|
||||||
|
|
||||||
copy_term_state.copy_term_impl(addr);
|
copy_term_state.copy_term_impl(addr);
|
||||||
|
copy_term_state.copy_attr_var_lists();
|
||||||
|
copy_term_state.unwind_trail();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -38,6 +41,7 @@ struct CopyTermState<T: CopierTarget> {
|
|||||||
old_h: usize,
|
old_h: usize,
|
||||||
target: T,
|
target: T,
|
||||||
attr_var_policy: AttrVarPolicy,
|
attr_var_policy: AttrVarPolicy,
|
||||||
|
attr_var_list_locs: Vec<(usize, HeapCellValue)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CopierTarget> CopyTermState<T> {
|
impl<T: CopierTarget> CopyTermState<T> {
|
||||||
@@ -48,6 +52,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
old_h: target.threshold(),
|
old_h: target.threshold(),
|
||||||
target,
|
target,
|
||||||
attr_var_policy,
|
attr_var_policy,
|
||||||
|
attr_var_list_locs: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,16 +91,12 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.target.push(hcv);
|
self.target.push(hcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cdr = self
|
let cdr = self.target.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
|
||||||
.target
|
|
||||||
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
|
|
||||||
|
|
||||||
if !cdr.is_var() {
|
if !cdr.is_var() {
|
||||||
self.trail_list_cell(addr + 1, threshold);
|
self.trail_list_cell(addr + 1, threshold);
|
||||||
} else {
|
} else {
|
||||||
let car = self
|
let car = self.target.store(self.target.deref(heap_loc_as_cell!(addr)));
|
||||||
.target
|
|
||||||
.store(self.target.deref(heap_loc_as_cell!(addr)));
|
|
||||||
|
|
||||||
if !car.is_var() {
|
if !car.is_var() {
|
||||||
self.trail_list_cell(addr, threshold);
|
self.trail_list_cell(addr, threshold);
|
||||||
@@ -167,6 +168,51 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.trail.push((Ref::heap_cell(pstr_loc), trail_item));
|
self.trail.push((Ref::heap_cell(pstr_loc), trail_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copy_attr_var_lists(&mut self) {
|
||||||
|
while !self.attr_var_list_locs.is_empty() {
|
||||||
|
let iter = mem::replace(&mut self.attr_var_list_locs, vec![]);
|
||||||
|
|
||||||
|
for (threshold, list_loc) in iter {
|
||||||
|
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
|
||||||
|
self.copy_attr_var_list(list_loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attributed variable attribute lists adhere to a particular
|
||||||
|
* structure which is ensured by this function and not at all by
|
||||||
|
* the vanilla copier.
|
||||||
|
*/
|
||||||
|
fn copy_attr_var_list(&mut self, mut list_addr: HeapCellValue) {
|
||||||
|
while let HeapCellValueTag::Lis = list_addr.get_tag() {
|
||||||
|
let threshold = self.target.threshold();
|
||||||
|
let heap_loc = list_addr.get_value();
|
||||||
|
let str_loc = self.target[heap_loc].get_value();
|
||||||
|
|
||||||
|
self.target.push(heap_loc_as_cell!(threshold+2));
|
||||||
|
self.target.push(heap_loc_as_cell!(threshold+1));
|
||||||
|
|
||||||
|
read_heap_cell!(self.target[str_loc],
|
||||||
|
(HeapCellValueTag::Atom) => {
|
||||||
|
self.target.push(self.target[str_loc]);
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Str) => {
|
||||||
|
self.copy_term_impl(self.target[str_loc]);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
list_addr = self.target[heap_loc + 1];
|
||||||
|
|
||||||
|
if HeapCellValueTag::Lis == list_addr.get_tag() {
|
||||||
|
self.target[threshold + 1] = list_loc_as_cell!(self.target.threshold());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn reinstantiate_var(&mut self, addr: HeapCellValue, frontier: usize) {
|
fn reinstantiate_var(&mut self, addr: HeapCellValue, frontier: usize) {
|
||||||
read_heap_cell!(addr,
|
read_heap_cell!(addr,
|
||||||
(HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::Var, h) => {
|
||||||
@@ -195,9 +241,15 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
|
|
||||||
if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
||||||
self.target.push(attr_var_as_cell!(threshold));
|
self.target.push(attr_var_as_cell!(threshold));
|
||||||
|
self.target.push(heap_loc_as_cell!(threshold + 1));
|
||||||
|
|
||||||
let list_val = self.target[h + 1];
|
let old_list_link = self.target[h + 1];
|
||||||
self.target.push(list_val);
|
self.trail.push((Ref::heap_cell(h + 1), old_list_link));
|
||||||
|
self.target[h + 1] = heap_loc_as_cell!(threshold + 1);
|
||||||
|
|
||||||
|
if old_list_link.get_tag() == HeapCellValueTag::Lis {
|
||||||
|
self.attr_var_list_locs.push((threshold + 1, old_list_link));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -298,8 +350,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.unwind_trail();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwind_trail(&mut self) {
|
fn unwind_trail(&mut self) {
|
||||||
|
|||||||
Reference in New Issue
Block a user