]> Repositorios git - scryer-prolog.git/commitdiff
unsafe stack transition
authorMark Thom <[email protected]>
Fri, 29 Nov 2019 01:22:03 +0000 (21:22 -0400)
committerMark Thom <[email protected]>
Fri, 29 Nov 2019 01:22:03 +0000 (21:22 -0400)
src/prolog/lib/clpb.pl
src/prolog/lib/non_iso.pl
src/prolog/machine/code_repo.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/system_calls.rs

index 5aa9561a9f4b7bf570ae5f2477688189234aacf1..3eba9a73e5e5b02d9e5e57a2c90771e26d526509 100644 (file)
@@ -1186,7 +1186,7 @@ indomain(1).
 % Examples:
 %
 % ==
-% ?- sat(A =< B), Vs = [A,B], sat_count(+[1|Vs], Count).
+% ?- 
 % Vs = [A, B],
 % Count = 3,
 % sat(A=:=A*B).
@@ -1197,7 +1197,7 @@ indomain(1).
 % Vs = [...],
 % CountOr = 1329227995784915872903807060280344575,
 % CountAnd = 1.
-% ==
+% ==sat(A =< B), Vs = [A,B], sat_count(+[1|Vs], Count).
 
 sat_count(Sat0, N) :-
         catch((parse_sat(Sat0, Sat),
index 84595e83591fcd3e42df14b0fe793a883624dde4..b4f9394d68e3fdeac162f13faa2b84a94aa532ad 100644 (file)
@@ -48,8 +48,29 @@ call_cleanup(G, C) :- setup_call_cleanup(true, G, C).
 
 setup_call_cleanup(S, G, C) :- '$get_b_value'(B),
     S, '$set_cp_by_default'(B), '$get_current_block'(Bb),
-    ( '$call_with_default_policy'(var(C)) -> throw(error(instantiation_error, setup_call_cleanup/3))
-    ; '$call_with_default_policy'(scc_helper(C, G, Bb)) ).
+    (  '$call_with_default_policy'(var(C)) ->
+       throw(error(instantiation_error, setup_call_cleanup/3))
+    ;  '$call_with_default_policy'(scc_helper(C, G, Bb))
+    ).
+
+:- non_counted_backtracking scc_helper/3.
+scc_helper(C, G, Bb) :-
+    '$get_cp'(Cp), '$install_scc_cleaner'(C, NBb), call(G),
+    ( '$check_cp'(Cp) ->
+      '$reset_block'(Bb),
+      '$call_with_default_policy'(run_cleaners_without_handling(Cp))
+    ; '$call_with_default_policy'(true)
+    ; '$reset_block'(NBb),
+      '$fail').
+scc_helper(_, _, Bb) :-
+    '$reset_block'(Bb), '$get_ball'(Ball),
+    '$call_with_default_policy'(run_cleaners_with_handling),
+    '$erase_ball',
+    '$call_with_default_policy'(throw(Ball)).
+scc_helper(_, _, _) :-
+    '$get_cp'(Cp),
+    '$call_with_default_policy'(run_cleaners_without_handling(Cp)),
+    '$fail'.
 
 :- non_counted_backtracking run_cleaners_with_handling/0.
 run_cleaners_with_handling :-
@@ -67,23 +88,6 @@ run_cleaners_without_handling(Cp) :-
 run_cleaners_without_handling(Cp) :-
     '$set_cp_by_default'(Cp), '$restore_cut_policy'.
 
-:- non_counted_backtracking scc_helper/3.
-scc_helper(C, G, Bb) :-
-    '$get_cp'(Cp), '$install_scc_cleaner'(C, NBb), call(G),
-    ( '$check_cp'(Cp) -> '$reset_block'(Bb),
-                        '$call_with_default_policy'(run_cleaners_without_handling(Cp))
-    ; '$call_with_default_policy'(true)
-    ; '$reset_block'(NBb), '$fail').
-scc_helper(_, _, Bb) :-
-    '$reset_block'(Bb), '$get_ball'(Ball),
-    '$call_with_default_policy'(run_cleaners_with_handling),
-    '$erase_ball',
-    '$call_with_default_policy'(throw(Ball)).
-scc_helper(_, _, _) :-
-    '$get_cp'(Cp),
-    '$call_with_default_policy'(run_cleaners_without_handling(Cp)),
-    '$fail'.
-
 % call_with_inference_limit
 
 :- non_counted_backtracking end_block/4.
@@ -119,8 +123,8 @@ call_with_inference_limit(G, L, R, Bb, B) :-
 call_with_inference_limit(_, _, R, Bb, B) :-
     '$reset_block'(Bb),
     '$remove_inference_counter'(B, _),
-    ( '$get_ball'(Ball), '$get_level'(Cp), '$set_cp_by_default'(Cp)
-    ; '$remove_call_policy_check'(B), '$fail' ),
+    (  '$get_ball'(Ball), '$get_level'(Cp), '$set_cp_by_default'(Cp)
+    ;  '$remove_call_policy_check'(B), '$fail' ),
     '$erase_ball',
     '$call_with_default_policy'(handle_ile(B, Ball, R)).
 
index df80644f67ef0a2a39a9bdebd5be1b6446268c74..fee126e9f3c66cb0a8422755dcb749a658b64fe9 100644 (file)
@@ -134,7 +134,7 @@ impl CodeRepo {
                 );
                 Some(RefOrOwned::Owned(call_clause))
             }
-            &CodePtr::CallN(arity, _) => {
+            &CodePtr::CallN(arity, _, last_call) => {
                 let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call);
                 Some(RefOrOwned::Owned(call_clause))
             }
index a6c3259798a7c0d4aa35a170aff138e6a03b6b87..10afcbe4b5111b83c5590d499b0336fd2e7e33fb 100644 (file)
@@ -309,7 +309,7 @@ pub enum REPLCodePtr {
 #[derive(Clone, PartialEq)]
 pub enum CodePtr {
     BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
-    CallN(usize, LocalCodePtr),                     // arity, local.
+    CallN(usize, LocalCodePtr, bool),               // arity, local, last call.
     Local(LocalCodePtr),
     DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
     REPL(REPLCodePtr, LocalCodePtr),                          // the REPL code, the return pointer.
@@ -320,7 +320,7 @@ impl CodePtr {
     pub fn local(&self) -> LocalCodePtr {
         match self {
             &CodePtr::BuiltInClause(_, ref local)
-          | &CodePtr::CallN(_, ref local)
+          | &CodePtr::CallN(_, ref local, _)
           | &CodePtr::Local(ref local) => local.clone(),
             &CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
             &CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p,
@@ -418,7 +418,7 @@ impl Add<usize> for CodePtr {
           | p @ CodePtr::VerifyAttrInterrupt(_)
           | p @ CodePtr::DynamicTransaction(..) => p,
             CodePtr::Local(local) => CodePtr::Local(local + rhs),
-            CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => {
+            CodePtr::CallN(_, local, _) | CodePtr::BuiltInClause(_, local) => {
                 CodePtr::Local(local + rhs)
             }
         }
index 434476667d013f8a70127e5871eba565dadf2484..63612858a1eb69efddaef6f81bd1ed1c166cb7cd 100644 (file)
@@ -844,7 +844,7 @@ pub(crate) trait CallPolicy: Any {
                         return Ok(());
                     }
 
-                    machine_st.p = CodePtr::CallN(arity, machine_st.p.local());
+                    machine_st.p = CodePtr::CallN(arity, machine_st.p.local(), machine_st.last_call);
                 }
                 ClauseType::BuiltIn(built_in) => {
                     machine_st.setup_built_in_call(built_in.clone());
index 90ddcb5452d48bdb2885e657b7c1ad21b29c821a..3f6df8b4e4f75e374a54bec1b7e2142878b5e65f 100644 (file)
@@ -608,7 +608,7 @@ impl MachineState {
                 }
             }
             TrailRef::Ref(Ref::StackCell(b, sc)) => {
-                if b <= self.b {
+                if b < self.b {
                     self.trail.push(TrailRef::Ref(Ref::StackCell(b, sc)));
                     self.tr += 1;
                 }
@@ -693,7 +693,7 @@ impl MachineState {
                     }
                 }
                 TrailRef::Ref(Ref::StackCell(b, _)) => {
-                    if b <= self.b {
+                    if b < self.b {
                         self.trail[i - offset] = self.trail[i];
                     } else {
                         offset += 1;
index e71bd826f16c750d956b13a2b5e46be227bc561b..005bf01c82a88c4927054b4e2bfbc1655ef74493 100644 (file)
@@ -559,12 +559,6 @@ impl Machine {
         snapshot.s = self.machine_st.s;
         snapshot.tr = self.machine_st.tr;
         snapshot.pstr_tr = self.machine_st.pstr_tr;
-        snapshot.p = self.machine_st.p.clone();
-        snapshot.cp = self.machine_st.cp;
-        snapshot.attr_var_init = mem::replace(
-            &mut self.machine_st.attr_var_init,
-            AttrVarInitializer::new(0, 0)
-        );
         snapshot.num_of_args = self.machine_st.num_of_args;
 
         snapshot.fail = self.machine_st.fail;
@@ -577,7 +571,6 @@ impl Machine {
         snapshot.block = self.machine_st.block;
 
         snapshot.ball = self.machine_st.ball.take();
-        snapshot.heap_locs = mem::replace(&mut self.machine_st.heap_locs, IndexMap::new());
         snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]);
 
         snapshot
@@ -591,9 +584,6 @@ impl Machine {
         self.machine_st.s = snapshot.s;
         self.machine_st.tr = snapshot.tr;
         self.machine_st.pstr_tr = snapshot.pstr_tr;
-        self.machine_st.p = snapshot.p;
-        self.machine_st.cp = snapshot.cp;
-        self.machine_st.attr_var_init = snapshot.attr_var_init;
         self.machine_st.num_of_args = snapshot.num_of_args;
 
         self.machine_st.fail = snapshot.fail;
@@ -610,7 +600,6 @@ impl Machine {
         self.machine_st.block = snapshot.block;
 
         self.machine_st.ball = snapshot.ball.take();
-        self.machine_st.heap_locs = mem::replace(&mut snapshot.heap_locs, IndexMap::new());
         self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
     }
 
index c8b841c3dc736833132cd2c02e3e755f87252f49..3f66dde76a1782dfc8965c3f88201f4baedf05a1 100644 (file)
@@ -863,7 +863,14 @@ impl MachineState {
                 let addr = self.store(self.deref(self[temp_v!(1)].clone()));
 
                 match addr {
-                    Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {}
+                    Addr::Con(Constant::Usize(old_b)) => {
+                        let prev_b = self.stack.index_or_frame(self.b).prelude.b;
+                        let prev_b = self.stack.index_or_frame(prev_b).prelude.b;
+
+                        if prev_b > old_b {
+                            self.fail = true;
+                        }
+                    }
                     _ => self.fail = true,
                 };
             }
@@ -1421,7 +1428,7 @@ impl MachineState {
 
                             let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
                             let list_addr = self[temp_v!(2)].clone();
-                            
+
                             self.unify(var_list_addr, list_addr);
                         } else {
                             self.fail = true;
@@ -1511,7 +1518,9 @@ impl MachineState {
                 match cut_policy.downcast_mut::<SCCCutPolicy>().ok() {
                     Some(sgc_policy) => {
                         if let Some((addr, b_cutoff, prev_b)) = sgc_policy.pop_cont_pt() {
-                            if self.b <= b_cutoff + 1 {
+                            let b = self.stack.index_or_frame(self.b).prelude.b;
+
+                            if b <= b_cutoff {
                                 self.block = prev_b;
 
                                 if let Some(r) = dest.as_var() {
@@ -1799,7 +1808,9 @@ impl MachineState {
 
                 match a2 {
                     Addr::Con(Constant::Usize(bp)) => {
-                        if self.b <= bp + 1 {
+                        let prev_b = self.stack.index_or_frame(self.b).prelude.b;
+
+                        if prev_b <= bp {
                             let a2 = Addr::Con(atom!("!"));
                             self.unify(a1, a2);
                         } else {