]> Repositorios git - scryer-prolog.git/commitdiff
pop AND frames when safe to do so, suspend resizing of AND frames until a proper...
authorMark Thom <[email protected]>
Sat, 30 Nov 2019 21:08:02 +0000 (14:08 -0700)
committerMark Thom <[email protected]>
Sat, 30 Nov 2019 21:08:02 +0000 (14:08 -0700)
src/prolog/machine/and_stack.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/toplevel.pl

index 3a16f5c0d9f9f5b06ce464b4aab2f4247396498a..002e6f68a6a3169fce8df760c377d2ff6f8defad 100644 (file)
@@ -55,6 +55,10 @@ impl AndStack {
         self.0.clear()
     }
 
+    /* 
+
+    // See MachineState::allocate for why this is commented out.
+
     pub fn resize(&mut self, fr: usize, n: usize) {
         let len = self[fr].perms.len();
 
@@ -66,7 +70,8 @@ impl AndStack {
             }
         }
     }
-
+    */
+    
     #[inline]
     pub fn truncate(&mut self, len: usize) {
         self.0.truncate(len);
index 20162ac16891d4c21f964b4706f03b182dc326bb..fd506f3ccb03c93798666654f2649ba1db9e443d 100644 (file)
@@ -423,8 +423,6 @@ pub(crate) trait CallPolicy: Any {
         machine_st.e = machine_st.or_stack[b].e;
         machine_st.cp = machine_st.or_stack[b].cp.clone();
 
-        machine_st.pop_stack_frames();
-        
         machine_st.or_stack[b].bp = machine_st.p.clone() + offset;
 
         let old_tr = machine_st.or_stack[b].tr;
@@ -471,8 +469,6 @@ pub(crate) trait CallPolicy: Any {
         machine_st.e = machine_st.or_stack[b].e;
         machine_st.cp = machine_st.or_stack[b].cp.clone();
 
-        machine_st.pop_stack_frames();
-        
         machine_st.or_stack[b].bp = machine_st.p.clone() + 1;
 
         let old_tr = machine_st.or_stack[b].tr;
@@ -515,6 +511,8 @@ pub(crate) trait CallPolicy: Any {
             machine_st.registers[i] = machine_st.or_stack[b][i].clone();
         }
 
+        machine_st.pop_stack_frames();
+
         machine_st.num_of_args = n;
         machine_st.e = machine_st.or_stack[b].e;
         machine_st.cp = machine_st.or_stack[b].cp.clone();
@@ -548,8 +546,6 @@ pub(crate) trait CallPolicy: Any {
         machine_st.b = machine_st.or_stack[b].b;
         machine_st.or_stack.truncate(machine_st.b);
 
-        machine_st.pop_stack_frames();
-
         machine_st.hb = machine_st.heap.h;
         machine_st.p += offset;
 
@@ -564,6 +560,8 @@ pub(crate) trait CallPolicy: Any {
             machine_st.registers[i] = machine_st.or_stack[b][i].clone();
         }
 
+        machine_st.pop_stack_frames();
+
         machine_st.num_of_args = n;
         machine_st.e = machine_st.or_stack[b].e;
         machine_st.cp = machine_st.or_stack[b].cp.clone();
@@ -597,8 +595,6 @@ pub(crate) trait CallPolicy: Any {
         machine_st.b = machine_st.or_stack[b].b;
         machine_st.or_stack.truncate(machine_st.b);
 
-        machine_st.pop_stack_frames();
-
         machine_st.hb = machine_st.heap.h;
         machine_st.p += 1;
 
index f28eb077f3697d4ee7a66addfa28b8d38c40cfcc..df22f68518fbae62d2c034606222a6cb5ea599d3 100644 (file)
@@ -123,7 +123,7 @@ impl MachineState {
         self.flags
     }
 
-    fn next_global_index(&self) -> usize {
+    pub(super) fn next_global_index(&self) -> usize {
         max(
             if self.and_stack.len() > 0 {
                 self.and_stack[self.e].global_index
@@ -3127,10 +3127,18 @@ impl MachineState {
 
     pub(super) fn allocate(&mut self, num_cells: usize) {
         let gi = self.next_global_index();
+//        let new_e = self.e + 1;
 
         self.p += 1;
 
-        if self.e + 1 < self.and_stack.len() {
+/*
+        /* See issue #244 for an example of a program broken (at the 
+           top level) by the inclusion of this code. A proper GC must determine if an 
+           existing AND frame is safe to resize; the check here is not 
+           enough.
+        */
+
+        if new_e < self.and_stack.len() {
             let and_gi = self.and_stack[self.e].global_index;
             let or_gi = self
                 .or_stack
@@ -3139,10 +3147,8 @@ impl MachineState {
                 .unwrap_or(0);
 
             if and_gi > or_gi {
-                let new_e = self.e + 1;
-
                 self.and_stack[new_e].e = self.e;
-                self.and_stack[new_e].cp = self.cp.clone();
+                self.and_stack[new_e].cp = self.cp;
                 self.and_stack[new_e].global_index = gi;
 
                 self.and_stack.resize(new_e, num_cells);
@@ -3151,7 +3157,7 @@ impl MachineState {
                 return;
             }
         }
-
+*/
         self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
         self.e = self.and_stack.len() - 1;
     }
@@ -3353,7 +3359,7 @@ impl MachineState {
                 self.b = self.or_stack.len();
                 let b = self.b - 1;
 
-                for i in 1..n + 1 {
+                for i in 1 .. n + 1 {
                     self.or_stack[b][i] = self.registers[i].clone();
                 }
 
index 634335544b4fbbc245deb383015e215d1250eafc..4700806a3170699fe6c39708ea1a0db3df6bf0af 100644 (file)
@@ -32,7 +32,7 @@
     ;  !,
        catch(throw(error(type_error(atom, Item), repl/0)),
             E,
-            '$print_exception_with_check'(E))       
+            '$print_exception_with_check'(E))
     ).
 '$instruction_match'(Term, VarList) :-
     '$submit_query_and_print_results'(Term, VarList),
@@ -42,7 +42,9 @@
     (  expand_goals(Term0, Term) -> true
     ;  Term = Term0
     ),
-    (  '$get_b_value'(B), call(Term), '$write_eqs_and_read_input'(B, VarList), !
+    (  '$get_b_value'(B), call(Term),
+       '$write_eqs_and_read_input'(B, VarList),
+       !
     ;  write('false.'), nl
     ).
 
@@ -79,7 +81,7 @@
        (  '$needs_bracketing'(Value, (=)) ->
          write('('),
          write_term(Value, [quoted(true), variable_names(VarList)]),
-         write(')')              
+         write(')')
        ;  write_term(Value, [quoted(true), variable_names(VarList)]),
          (  '$trailing_period_is_ambiguous'(Value) ->
             write(' ')
     '$write_eq'(G2, VarList).
 '$write_eq'(G, VarList) :-
     '$write_last_goal'(G, VarList).
-    
+
 '$graphic_token_char'(C) :-
     memberchk(C, ['#', '$', '&', '*', '+', '-', '.', ('/'), ':',
                   '<', '=', '>', '?', '@', '^', '~', ('\\')]).