From 77cf0fd87bd208a30c395ca7b468c89cd1f7f826 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 28 Apr 2020 01:40:11 -0600 Subject: [PATCH] don't append lists of attributes when binding attributed variables (#353) --- src/prolog/lib/atts.pl | 3 +- src/prolog/machine/system_calls.rs | 47 +++++++++++++----------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 1d6fddf7..7160ab24 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -56,7 +56,8 @@ '$del_attr'(Ls0, V, Attr) :- Ls0 = [Att | Ls1], nonvar(Att), - ( Att \= Attr -> '$del_attr_buried'(Ls0, Ls1, V, Attr) + ( Att \= Attr -> + '$del_attr_buried'(Ls0, Ls1, V, Attr) ; '$enqueue_attr_var'(V), '$del_attr_head'(V), '$del_attr'(Ls1, V, Attr) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 13ceb30c..632472be 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1815,6 +1815,9 @@ impl MachineState { Addr::Lis(l) => { let tail = self.store(self.deref(Addr::HeapCell(l + 1))); let tail = if tail.is_ref() { + self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)); + self.trail(TrailRef::Ref(Ref::AttrVar(h))); + Addr::HeapCell(h + 1) } else { tail @@ -1823,10 +1826,14 @@ impl MachineState { self.heap[h + 1] = HeapCellValue::Addr(tail); self.trail(TrailRef::AttrVarListLink(h + 1, l)); } - _ => unreachable!(), + _ => { + unreachable!(); + } } } - _ => unreachable!(), + _ => { + unreachable!(); + } } } &SystemClauseType::DynamicModuleResolution(narity) => { @@ -2229,16 +2236,16 @@ impl MachineState { Addr::AttrVar(h) => { h + 1 } - attr_var @ Addr::HeapCell(_) - | attr_var @ Addr::StackCell(..) => { - // create an AttrVar in the heap. - let h = self.heap.h(); + attr_var @ Addr::HeapCell(_) | + attr_var @ Addr::StackCell(..) => { + // create an AttrVar in the heap. + let h = self.heap.h(); - self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h))); - self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1))); + self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h))); + self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1))); - self.bind(Ref::AttrVar(h), attr_var); - h + 1 + self.bind(Ref::AttrVar(h), attr_var); + h + 1 } _ => { self.fail = true; @@ -2247,7 +2254,7 @@ impl MachineState { }; let list_addr = self[temp_v!(2)]; - self.unify(Addr::HeapCell(attr_var_list), list_addr); + self.bind(Ref::HeapCell(attr_var_list), list_addr); } &SystemClauseType::GetAttrVarQueueDelimiter => { let addr = self[temp_v!(1)]; @@ -2658,26 +2665,12 @@ impl MachineState { }; } &SystemClauseType::RedoAttrVarBinding => { - let var = self.store(self.deref(self[temp_v!(1)])); + let var = self.store(self.deref(self[temp_v!(1)])); let value = self.store(self.deref(self[temp_v!(2)])); match var { Addr::AttrVar(h) => { - if let Addr::AttrVar(h1) = value { - self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h1)); - - // append h's attributes list to h1's. - let mut l = h1 + 1; - - while let Addr::Lis(l1) = self.store(self.deref(self.heap[l].as_addr(l))) { - l = l1 + 1; - } - - self.heap[l] = HeapCellValue::Addr(Addr::HeapCell(h + 1)); - self.trail(TrailRef::Ref(Ref::HeapCell(l))); - } else { - self.heap[h] = HeapCellValue::Addr(value); - } + self.heap[h] = HeapCellValue::Addr(value); } _ => { unreachable!() -- 2.54.0