From 1dec482e22497aa22b21e24a75cc07a87d91d987 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 27 Nov 2019 00:52:30 -0700 Subject: [PATCH] use in situ code directory from metacall if conventional lookup fails (#238) --- src/prolog/machine/machine_state.rs | 8 +------- src/prolog/machine/mod.rs | 26 +++++++++++++------------- src/prolog/machine/term_expansion.rs | 12 ++++++------ src/prolog/machine/toplevel.rs | 23 ++++++++++------------- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index c632e059..d09b5745 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -873,13 +873,7 @@ pub(crate) trait CallPolicy: Any { if let Some(idx) = indices.get_code_index((name.clone(), arity), module) { self.context_call(machine_st, name, arity, idx, indices)?; } else { - let h = machine_st.heap.h; - let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); - let key = ExistenceError::Procedure(name, arity); - - return Err( - machine_st.error_form(MachineError::existence_error(h, key), stub) - ); + try_in_situ(machine_st, name, arity, indices, machine_st.last_call)?; } } ClauseType::Hook(_) | ClauseType::System(_) => { diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index a562858c..b1c0867c 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -107,13 +107,13 @@ impl SubModuleUser for IndexStore { &mut self.op_dir } - fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option { - match module.as_str() { + fn get_code_index(&self, key: PredicateKey, module_name: ClauseName) -> Option { + match module_name.as_str() { "user" | "builtin" => self.code_dir.get(&key).cloned(), _ => self - .modules - .get(&module) - .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)), + .modules + .get(&module_name) + .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)) } } @@ -132,7 +132,7 @@ impl SubModuleUser for IndexStore { return; } - self.code_dir.insert((name, arity), idx); + self.code_dir.insert((name.clone(), arity), idx.clone()); } fn use_qualified_module( @@ -241,7 +241,7 @@ impl Machine { pub fn run_init_code(&mut self, code: Code) -> bool { let old_machine_st = self.sink_to_snapshot(); - self.machine_st.reset(); + self.machine_st.reset(); self.code_repo.cached_query = code; self.run_query(); @@ -418,14 +418,14 @@ impl Machine { _ => unreachable!() }; - + let arity = match &self.machine_st.heap[s+2] { &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => arity.to_usize().unwrap(), _ => unreachable!() }; - + exports.push(ModuleExport::PredicateKey((name, arity))); } HeapCellValue::NamedStr(arity, ref name, _) @@ -443,7 +443,7 @@ impl Machine { _ => unreachable!() }; - + let prec = match &self.machine_st.heap[s+1] { &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => arity.to_usize().unwrap(), @@ -593,7 +593,7 @@ impl Machine { fn sink_to_snapshot(&mut self) -> MachineState { let mut snapshot = MachineState::with_capacity(0); - + snapshot.hb = self.machine_st.hb; snapshot.e = self.machine_st.e; snapshot.b = self.machine_st.b; @@ -619,7 +619,7 @@ impl Machine { snapshot } - fn absorb_snapshot(&mut self, mut snapshot: MachineState) { + fn absorb_snapshot(&mut self, mut snapshot: MachineState) { self.machine_st.hb = snapshot.hb; self.machine_st.e = snapshot.e; self.machine_st.b = snapshot.b; @@ -667,7 +667,7 @@ impl Machine { // so hold onto it locally and restore it after the compiler has finished. self.machine_st.fail = false; let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]); - + self.dynamic_transaction(trans_type, p); self.code_repo.cached_query = cached_query; diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index 1c45b49e..f8ef4ed3 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -161,7 +161,7 @@ impl<'a, R: Read> TermStream<'a, R> { pub fn col_num(&self) -> usize { self.parser.col_num() } - + #[inline] pub fn update_expansion_lens(&mut self) { let te_key = (clause_name!("term_expansion"), 2); @@ -267,7 +267,7 @@ impl<'a, R: Read> TermStream<'a, R> { let line_num = self.line_num(); let col_num = self.col_num(); - + let term = self.parser.read_term(composite_op!( self.in_module, &self.wam.indices.op_dir, @@ -308,7 +308,7 @@ impl<'a, R: Read> TermStream<'a, R> { initial_term, clause_name!(","), ))); - + Ok(Term::Clause(cell, name, terms, arity)) } _ => Ok(term), @@ -324,7 +324,7 @@ impl<'a, R: Read> TermStream<'a, R> { ) -> Result, ParserError> { let mut results = vec![]; - while let Some(term) = terms.pop_front() { + while let Some(term) = terms.pop_front() { match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) { Some(term_string) => { let term = self.parse_expansion_output(term_string.as_str(), op_dir)?; @@ -382,14 +382,14 @@ impl MachineState { ) -> Option { let term_write_result = write_term_to_heap(term, self); let h = self.heap.h; - + self[temp_v!(1)] = Addr::HeapCell(term_write_result.heap_loc); self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); self[temp_v!(2)] = Addr::HeapCell(h); let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)]; wam.code_repo.cached_query = code; - + self.query_stepper( &mut wam.indices, &mut wam.policies, diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index 823067a4..a01d3dd8 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -60,8 +60,8 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir, IndexSource::Local(ref mut indices) => &mut indices.code_dir, } - } - + } + fn static_code_dir(&self) -> Option<&CodeDir> { match self.static_code_dir { Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir), @@ -81,11 +81,11 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { }; if let Some(idx) = idx_opt { - self.local_code_dir().insert((name, arity), idx.clone()); + self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } else { - let idx = CodeIndex::default(); - self.local_code_dir().insert((name, arity), idx.clone()); + let idx = CodeIndex::default(); + self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } } @@ -594,7 +594,7 @@ impl RelationWorker { fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque) { let vars = self.compute_head(&body_term); - let clauses: Vec<_> = unfold_by_str(body_term, ";") + let results = unfold_by_str(body_term, ";") .into_iter() .map(|term| { let mut subterms = unfold_by_str(term, ","); @@ -603,13 +603,10 @@ impl RelationWorker { check_for_internal_if_then(&mut subterms); let term = subterms.pop().unwrap(); - fold_by_str(subterms.into_iter(), term, clause_name!(",")) - }) - .collect(); + let clause = fold_by_str(subterms.into_iter(), term, clause_name!(",")); - let results = clauses - .into_iter() - .map(|clause| self.fabricate_rule_body(&vars, clause)) + self.fabricate_rule_body(&vars, clause) + }) .collect(); (vars, results) @@ -984,7 +981,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> { if self.in_module { None } else { Some(IndexSource::TermStream) } ); - let queue = self.rel_worker.parse_queue(&mut indices)?; + let queue = self.rel_worker.parse_queue(&mut indices)?; let result = (append_preds(preds), queue); let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir; -- 2.54.0