From d49917c88fa746af33d4b2aa71e0795ce5e4327b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 6 Mar 2019 09:17:24 -0700 Subject: [PATCH] give module bounds a better respect for dynamic predicates --- src/prolog/machine/compile.rs | 9 +-------- src/prolog/machine/mod.rs | 24 +++++++++++++++++++++++- src/prolog/machine/modules.rs | 9 ++++----- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 8d56c496..58eebb04 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -216,14 +216,7 @@ impl ClauseCodeGenerator { continue; } - if let Some(info) = wam.indices.dynamic_code_dir.get(&(name.clone(), arity)) { - if info.module_src != name.owning_module() { - let err_str = format!("{}/{}", name.as_str(), arity); - let err_str = clause_name!(err_str, wam.indices.atom_tbl()); - - return Err(SessionError::CannotOverwriteDynamicClause(err_str)); - } - } + wam.check_dynamic_clause_overwrite(name.clone(), arity)?; let predicate = Predicate(heads_and_tails.into_iter().map(|(head, tail)| { let clause = Term::Clause(Cell::default(), clause_name!("clause"), diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 2eacb5d7..2759d72f 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -101,8 +101,13 @@ impl SubModuleUser for IndexStore { } } - fn remove_code_index(&mut self, key: PredicateKey) { + fn remove_code_index(&mut self, key: PredicateKey) + { self.code_dir.remove(&key); + + if self.dynamic_code_dir.contains_key(&key) { + self.dynamic_code_dir.remove(&key); + } } fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) @@ -208,6 +213,21 @@ impl Machine { self.machine_st.flags } + pub fn check_dynamic_clause_overwrite(&self, name: ClauseName, arity: usize) + -> Result<(), SessionError> + { + if let Some(info) = self.indices.dynamic_code_dir.get(&(name.clone(), arity)) { + if info.module_src != name.owning_module() { + let err_str = format!("{}/{}", name.as_str(), arity); + let err_str = clause_name!(err_str, self.indices.atom_tbl()); + + return Err(SessionError::CannotOverwriteDynamicClause(err_str)); + } + } + + Ok(()) + } + pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError> { for (key, idx) in &indices.code_dir { @@ -222,6 +242,8 @@ impl Machine { } }; + self.check_dynamic_clause_overwrite(key.0.clone(), key.1)?; + if let Some(ref existing_idx) = self.indices.code_dir.get(&key) { // ensure we don't try to overwrite an existing predicate from a different module. if !existing_idx.is_undefined() && !idx.is_undefined() { diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index 668440c1..31e13cd9 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -84,7 +84,6 @@ pub trait SubModuleUser self.remove_code_index((name.clone(), arity)); - // remove or respecify ops. if arity == 2 { if let Some((_, _, mod_name)) = self.op_dir().get(&(name.clone(), Fixity::In)).cloned() @@ -115,7 +114,8 @@ pub trait SubModuleUser } // returns true on successful import. - fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool + fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) + -> bool { let name = name.defrock_brackets(); let mut found_op = false; @@ -156,7 +156,7 @@ pub trait SubModuleUser } pub fn use_qualified_module(user: &mut User, submodule: &Module, exports: &Vec) - -> Result<(), SessionError> + -> Result<(), SessionError> where User: SubModuleUser { for (name, arity) in exports.iter().cloned() { @@ -172,8 +172,7 @@ pub fn use_qualified_module(user: &mut User, submodule: &Module, exports: Ok(()) } -pub fn use_module(user: &mut User, submodule: &Module) - -> Result<(), SessionError> +pub fn use_module(user: &mut User, submodule: &Module) -> Result<(), SessionError> { for (name, arity) in submodule.module_decl.exports.iter().cloned() { if !user.import_decl(name, arity, submodule) { -- 2.54.0