use in situ code directory from metacall if conventional lookup fails (#238)

This commit is contained in:
Mark Thom
2019-11-27 00:52:30 -07:00
parent 0a665b79f2
commit 1dec482e22
4 changed files with 30 additions and 39 deletions

View File

@@ -873,13 +873,7 @@ pub(crate) trait CallPolicy: Any {
if let Some(idx) = indices.get_code_index((name.clone(), arity), module) { if let Some(idx) = indices.get_code_index((name.clone(), arity), module) {
self.context_call(machine_st, name, arity, idx, indices)?; self.context_call(machine_st, name, arity, idx, indices)?;
} else { } else {
let h = machine_st.heap.h; try_in_situ(machine_st, name, arity, indices, machine_st.last_call)?;
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)
);
} }
} }
ClauseType::Hook(_) | ClauseType::System(_) => { ClauseType::Hook(_) | ClauseType::System(_) => {

View File

@@ -107,13 +107,13 @@ impl SubModuleUser for IndexStore {
&mut self.op_dir &mut self.op_dir
} }
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> { fn get_code_index(&self, key: PredicateKey, module_name: ClauseName) -> Option<CodeIndex> {
match module.as_str() { match module_name.as_str() {
"user" | "builtin" => self.code_dir.get(&key).cloned(), "user" | "builtin" => self.code_dir.get(&key).cloned(),
_ => self _ => self
.modules .modules
.get(&module) .get(&module_name)
.and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)), .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from))
} }
} }
@@ -132,7 +132,7 @@ impl SubModuleUser for IndexStore {
return; return;
} }
self.code_dir.insert((name, arity), idx); self.code_dir.insert((name.clone(), arity), idx.clone());
} }
fn use_qualified_module( fn use_qualified_module(

View File

@@ -81,11 +81,11 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
}; };
if let Some(idx) = idx_opt { 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 idx
} else { } else {
let idx = CodeIndex::default(); let idx = CodeIndex::default();
self.local_code_dir().insert((name, arity), idx.clone()); self.local_code_dir().insert((name.clone(), arity), idx.clone());
idx idx
} }
} }
@@ -594,7 +594,7 @@ impl RelationWorker {
fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) { fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) {
let vars = self.compute_head(&body_term); let vars = self.compute_head(&body_term);
let clauses: Vec<_> = unfold_by_str(body_term, ";") let results = unfold_by_str(body_term, ";")
.into_iter() .into_iter()
.map(|term| { .map(|term| {
let mut subterms = unfold_by_str(term, ","); let mut subterms = unfold_by_str(term, ",");
@@ -603,13 +603,10 @@ impl RelationWorker {
check_for_internal_if_then(&mut subterms); check_for_internal_if_then(&mut subterms);
let term = subterms.pop().unwrap(); let term = subterms.pop().unwrap();
fold_by_str(subterms.into_iter(), term, clause_name!(",")) let clause = fold_by_str(subterms.into_iter(), term, clause_name!(","));
})
.collect();
let results = clauses self.fabricate_rule_body(&vars, clause)
.into_iter() })
.map(|clause| self.fabricate_rule_body(&vars, clause))
.collect(); .collect();
(vars, results) (vars, results)