]> Repositorios git - scryer-prolog.git/commitdiff
Scan entire predicate in InstallVerifyAttr
authorbakaq <[email protected]>
Wed, 5 Feb 2025 05:22:59 +0000 (02:22 -0300)
committerbakaq <[email protected]>
Wed, 5 Feb 2025 14:40:05 +0000 (11:40 -0300)
src/machine/dispatch.rs

index a5ebe291d74633bc20169198395f7b58829a1ee0..57d3e5ae0b9f834aa5f64530eebc8ec7b6e760c6 100644 (file)
@@ -563,9 +563,9 @@ impl Machine {
                             self.machine_st.cp = self.machine_st.attr_var_init.cp;
                         }
 
-                        let mut p = self.machine_st.p;
-                        let mut arity = 0;
+                        let p = self.machine_st.p;
 
+                        // Find the boundaries of the current predicate
                         self.indices.code_dir.sort_by(|_, a, _, b| a.cmp(b));
 
                         let predicate_idx = self
@@ -574,38 +574,41 @@ impl Machine {
                             .binary_search_by_key(&p, |_, x| x.get().p() as usize)
                             .unwrap_or_else(|x| x - 1);
 
-                        let current_pred_limit = self
+                        let current_pred_start = self
                             .indices
                             .code_dir
-                            .get_index(predicate_idx + 1)
-                            .map(|x| x.1.p() as usize);
-
-                        while self.code[p].is_head_instr() {
-                            //println!("{}: {:?}", p, &self.code[p]);
-                            //println!("{} {:?}", arity, self.code[p]);
-                            for r in self.code[p].registers() {
-                                //println!("reg {:?}", r);
-                                if let RegType::Temp(t) = r {
-                                    arity = std::cmp::max(arity, t);
-                                }
-                            }
+                            .get_index(predicate_idx)
+                            .map(|x| x.1.p() as usize)
+                            .unwrap();
 
-                            p += 1;
-                        }
+                        debug_assert!(current_pred_start <= p);
 
-                        let p_interrupt = p;
+                        let current_pred_end = self
+                            .indices
+                            .code_dir
+                            .get_index(predicate_idx + 1)
+                            .map(|x| x.1.p() as usize)
+                            .unwrap_or(self.code.len());
 
-                        while p < self.code.len()
-                            && current_pred_limit.map(|x| p < x).unwrap_or(true)
-                        {
-                            for r in self.code[p].registers() {
-                                if let RegType::Temp(t) = r {
-                                    arity = std::cmp::max(arity, t);
-                                }
-                            }
+                        debug_assert!(current_pred_end >= p);
+                        debug_assert!(current_pred_end <= self.code.len());
 
-                            p += 1;
-                        }
+                        // Find point to insert the interrupt
+                        let p_interrupt = p + self.code[p..current_pred_end]
+                            .iter()
+                            .position(|x| !x.is_head_instr())
+                            .unwrap();
+
+                        // Scan registers of all instructions to find out how many to save
+                        let arity = self.code[current_pred_start..current_pred_end]
+                            .iter()
+                            .flat_map(Instruction::registers)
+                            .flat_map(|r| match r {
+                                RegType::Temp(t) => Some(t),
+                                _ => None,
+                            })
+                            .max()
+                            .unwrap_or(0);
 
                         let instr = std::mem::replace(
                             &mut self.code[p_interrupt],
@@ -616,9 +619,6 @@ impl Machine {
                         self.machine_st.attr_var_init.cp = p_interrupt;
                     }
                     &Instruction::VerifyAttrInterrupt(arity) => {
-                        //println!("VerifyAttr arity: {arity}");
-                        // let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
-                        // let arity = std::cmp::max(arity, self.machine_st.num_of_args);
                         self.run_verify_attr_interrupt(arity);
                     }
                     &Instruction::Add(ref a1, ref a2, t) => {