From: bakaq Date: Wed, 5 Feb 2025 05:22:59 +0000 (-0300) Subject: Scan entire predicate in InstallVerifyAttr X-Git-Tag: v0.10.0~75^2 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=6d80c843e61774c821a5a605c6063795ab38ea5e;p=scryer-prolog.git Scan entire predicate in InstallVerifyAttr --- diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index a5ebe291..57d3e5ae 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -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) => {