From b943afb7c7a5e70038f4291e3b448f2aa01b7f2a Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 18 Dec 2023 09:52:46 -0700 Subject: [PATCH] fix '$get_clause_p' whose old implementation was broken by the introduction of lookahead indexing --- src/machine/mod.rs | 17 ++-- src/machine/system_calls.rs | 149 +++++++++++++----------------------- 2 files changed, 66 insertions(+), 100 deletions(-) diff --git a/src/machine/mod.rs b/src/machine/mod.rs index b25627db..fccf7d59 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -925,8 +925,8 @@ impl Machine { self.machine_st.hb = self.machine_st.heap.len(); - self.machine_st.oip = 0; - self.machine_st.iip = 0; + // self.machine_st.oip = 0; + // self.machine_st.iip = 0; } self.machine_st.p += offset; @@ -1010,8 +1010,8 @@ impl Machine { self.machine_st.heap.truncate(target_h); - self.machine_st.oip = 0; - self.machine_st.iip = 0; + // self.machine_st.oip = 0; + // self.machine_st.iip = 0; } else { self.trust_epilogue(offset); } @@ -1059,8 +1059,13 @@ impl Machine { self.machine_st.stack.truncate(b); self.machine_st.heap.truncate(target_h); - self.machine_st.oip = 0; - self.machine_st.iip = 0; + // these registers don't need to be reset here and MUST NOT be + // (nor in indexed_try to trust_epilogue)! oip could be reset + // without any adverse effects but iip is needed by + // get_clause_p to find the last executed clause/2 clause. + + // self.machine_st.oip = 0; + // self.machine_st.iip = 0; } #[inline(always)] diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 674a288f..675340a0 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1171,112 +1171,73 @@ impl Machine { .get_predicate_skeleton(&compilation_target, &key) .unwrap(); - if self.machine_st.b > self.machine_st.e { - let or_frame = self.machine_st.stack.index_or_frame(self.machine_st.b); - let bp = or_frame.prelude.bp; - - match &self.code[bp] { - Instruction::IndexingCode(ref indexing_code) => { - match &indexing_code[or_frame.prelude.boip as usize] { - IndexingLine::IndexedChoice(ref indexed_choice) => { - let p = or_frame.prelude.biip as usize - 1; - - match &indexed_choice[p] { - &IndexedChoiceInstruction::Try(offset) - | &IndexedChoiceInstruction::Retry(offset) - | &IndexedChoiceInstruction::DefaultRetry(offset) => { - let clause_clause_loc = skeleton.core.clause_clause_locs[p]; - (clause_clause_loc, bp + offset) - } - &IndexedChoiceInstruction::Trust(_) - | &IndexedChoiceInstruction::DefaultTrust(_) => { - unreachable!() - } - } - } - _ => { - unreachable!() - } + let module_name = match compilation_target { + CompilationTarget::User => atom!("builtins"), + CompilationTarget::Module(target) => target, + }; + + let bp = self + .indices + .get_predicate_code_index(atom!("$clause"), 2, module_name) + .and_then(|idx| idx.local()) + .unwrap(); + + let p = self.machine_st.iip as usize; + + macro_rules! extract_ptr { + ($ptr: expr) => { + match $ptr { + IndexingCodePtr::External(p) => { + return ( + skeleton.core.clause_clause_locs.back().cloned().unwrap(), + bp + p, + ) } + IndexingCodePtr::Internal(boip) => boip, + _ => unreachable!(), } - _ => unreachable!(), - } - } else { - let module_name = match compilation_target { - CompilationTarget::User => atom!("builtins"), - CompilationTarget::Module(target) => target, }; + } - let bp = self - .indices - .get_predicate_code_index(atom!("$clause"), 2, module_name) - .and_then(|idx| idx.local()) - .unwrap(); - - macro_rules! extract_ptr { - ($ptr: expr) => { - match $ptr { - IndexingCodePtr::External(p) => { - return ( - skeleton.core.clause_clause_locs.back().cloned().unwrap(), - bp + p, - ) + match &self.code[bp] { + Instruction::IndexingCode(ref indexing_code) => { + let indexing_code_ptr = match &indexing_code[0] { + &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, c, _, s)) => { + if key.1 > 0 { + s + } else { + c } - IndexingCodePtr::Internal(boip) => boip, - _ => unreachable!(), + } + _ => { + unreachable!() } }; - } - match &self.code[bp] { - Instruction::IndexingCode(ref indexing_code) => { - let indexing_code_ptr = match &indexing_code[0] { - &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm( - _, - _, - c, - _, - s, - )) => { - if key.1 > 0 { - s - } else { - c - } - } - _ => { - unreachable!() - } - }; - - let boip = extract_ptr!(indexing_code_ptr); + let boip = extract_ptr!(indexing_code_ptr); - let boip = match &indexing_code[boip] { - IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref hm)) => { - boip + extract_ptr!(hm.get(&key).cloned().unwrap()) - } - IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref hm)) => { - boip + extract_ptr!(hm.get(&Literal::Atom(key.0)).cloned().unwrap()) - } - _ => boip, - }; + let boip = match &indexing_code[boip] { + IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref hm)) => { + boip + extract_ptr!(hm.get(&key).cloned().unwrap()) + } + IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref hm)) => { + boip + extract_ptr!(hm.get(&Literal::Atom(key.0)).cloned().unwrap()) + } + _ => boip, + }; - match &indexing_code[boip] { - IndexingLine::IndexedChoice(indexed_choice) => { - return ( - skeleton.core.clause_clause_locs.back().cloned().unwrap(), - bp + indexed_choice.back().unwrap().offset(), - ); - } - _ => unreachable!(), + match &indexing_code[boip] { + IndexingLine::IndexedChoice(indexed_choice) => { + return ( + skeleton.core.clause_clause_locs[p], + bp + indexed_choice[p].offset(), + ); } + _ => unreachable!(), } - _ => { - return ( - skeleton.core.clause_clause_locs.back().cloned().unwrap(), - bp, - ); - } + } + _ => { + return (skeleton.core.clause_clause_locs[p], bp); } } } -- 2.54.0