From: Mark Thom Date: Tue, 16 Mar 2021 08:30:09 +0000 (-0600) Subject: clear user-level definitions when reloading a file (#455) X-Git-Tag: v0.9.0~127 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=51424aed32e960511154379a8ca0975867278a04;p=scryer-prolog.git clear user-level definitions when reloading a file (#455) --- diff --git a/src/clause_types.rs b/src/clause_types.rs index 4d7e35d6..657945d6 100644 --- a/src/clause_types.rs +++ b/src/clause_types.rs @@ -372,6 +372,9 @@ impl SystemClauseType { &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => { clause_name!("$push_load_state_payload") } + &SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule) => { + clause_name!("$add_in_situ_filename_module") + } &SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"), &SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"), &SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"), @@ -765,6 +768,9 @@ impl SystemClauseType { ("$push_load_state_payload", 1) => { Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)) } + ("$add_in_situ_filename_module", 1) => { + Some(SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule)) + } ("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)), ("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)), ("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)), diff --git a/src/loader.pl b/src/loader.pl index 91b1ec83..a748f981 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -105,6 +105,10 @@ file_load(_, _). file_load(Stream, Path, Evacuable) :- create_file_load_context(Stream, Path, Evacuable), + % '$add_in_situ_filename_module' removes user level predicates, + % local predicate clauses, etc. from a previous load of the file + % at Path. + '$add_in_situ_filename_module'(Evacuable), catch((loader:load_loop(Stream, Evacuable), loader:run_initialization_goals), E, diff --git a/src/machine/compile.rs b/src/machine/compile.rs index b45b58e2..3e96672e 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -9,7 +9,7 @@ use crate::machine::preprocessor::*; use crate::machine::term_stream::*; use crate::machine::*; -use slice_deque::sdeq; +use slice_deque::{sdeq, SliceDeque}; use std::cell::Cell; use std::collections::VecDeque; @@ -867,7 +867,7 @@ fn prepend_compiled_clause( let target_arg_num = skeleton.clauses[0].opt_arg_index_key.arg_num(); let head_arg_num = skeleton.clauses[1].opt_arg_index_key.arg_num(); - + let settings = CodeGenSettings { global_clock_tick: if skeleton.is_dynamic { Some(global_clock_tick) @@ -1316,6 +1316,18 @@ fn print_overwrite_warning( } impl<'a> LoadState<'a> { + pub(super) fn listing_src_file_name(&self) -> Option { + if let Some(load_context) = self.wam.load_contexts.last() { + if let Some(path_str) = load_context.path.to_str() { + if !path_str.is_empty() { + return Some(clause_name!(path_str.to_string(), self.wam.machine_st.atom_tbl)); + } + } + } + + None + } + fn compile_standalone_clause( &mut self, term: Term, @@ -1349,7 +1361,7 @@ impl<'a> LoadState<'a> { key: PredicateKey, predicates: &mut PredicateQueue, settings: CodeGenSettings, - ) -> Result<(), SessionError> { + ) -> Result { let code_index = self.get_or_insert_code_index( key.clone(), predicates.compilation_target.clone(), @@ -1427,39 +1439,28 @@ impl<'a> LoadState<'a> { } }; - match self - .wam - .indices - .get_local_predicate_skeleton_mut( - &self.compilation_target, - predicates.compilation_target.clone(), - key.clone(), - ) - { - Some(skeleton) => { - self.retraction_info - .push_record(RetractionRecord::SkeletonLocalClauseTruncateBack( - self.compilation_target.clone(), - predicates.compilation_target.clone(), - key.clone(), - skeleton.clause_clause_locs.len(), - )); - - skeleton.clause_clause_locs.extend_from_slice( - &clause_clause_locs[0 ..] + if let Some(filename) = self.listing_src_file_name() { + if let CompilationTarget::User = &predicates.compilation_target { + let compilation_target = mem::replace( + &mut self.compilation_target, + CompilationTarget::Module(filename), ); - } - None => { - let mut skeleton = PredicateSkeleton::new(); - skeleton.clause_clause_locs = clause_clause_locs; - self.add_local_extensible_predicate( - predicates.compilation_target.clone(), - key.clone(), - skeleton, + self.extend_local_predicate_skeleton( + &CompilationTarget::User, + &key, + clause_clause_locs.clone(), ); + + self.compilation_target = compilation_target; } } + + self.extend_local_predicate_skeleton( + &predicates.compilation_target, + &key, + clause_clause_locs, + ); } print_overwrite_warning( @@ -1469,20 +1470,22 @@ impl<'a> LoadState<'a> { settings.is_dynamic(), ); + let index_ptr = if settings.is_dynamic() { + IndexPtr::DynamicIndex(code_ptr) + } else { + IndexPtr::Index(code_ptr) + }; + set_code_index( &mut self.retraction_info, &predicates.compilation_target, key, &code_index, - if settings.is_dynamic() { - IndexPtr::DynamicIndex(code_ptr) - } else { - IndexPtr::Index(code_ptr) - }, + index_ptr, ); self.wam.code_repo.code.extend(code.into_iter()); - Ok(()) + Ok(code_index) } fn record_incremental_compile( @@ -1516,6 +1519,125 @@ impl<'a> LoadState<'a> { }); } + fn extend_local_predicate_skeleton( + &mut self, + compilation_target: &CompilationTarget, + key: &PredicateKey, + clause_clause_locs: SliceDeque, + ) { + match self + .wam + .indices + .get_local_predicate_skeleton_mut( + &self.compilation_target, + compilation_target.clone(), + key.clone(), + ) + { + Some(skeleton) => { + self.retraction_info + .push_record(RetractionRecord::SkeletonLocalClauseTruncateBack( + self.compilation_target.clone(), + compilation_target.clone(), + key.clone(), + skeleton.clause_clause_locs.len(), + )); + + skeleton.clause_clause_locs.extend_from_slice( + &clause_clause_locs[0 ..] + ); + } + None => { + let mut skeleton = PredicateSkeleton::new(); + skeleton.clause_clause_locs = clause_clause_locs; + + self.add_local_extensible_predicate( + compilation_target.clone(), + key.clone(), + skeleton, + ); + } + } + } + + fn push_front_to_local_predicate_skeleton( + &mut self, + compilation_target: &CompilationTarget, + key: &PredicateKey, + code_len: usize, + ) { + match self + .wam + .indices + .get_local_predicate_skeleton_mut( + &self.compilation_target, + compilation_target.clone(), + key.clone(), + ) + { + Some(skeleton) => { + self.retraction_info.push_record( + RetractionRecord::SkeletonLocalClauseClausePopFront( + self.compilation_target.clone(), + compilation_target.clone(), + key.clone(), + ), + ); + + skeleton.clause_clause_locs.push_front(code_len); + } + None => { + let mut skeleton = PredicateSkeleton::new(); + skeleton.clause_clause_locs.push_front(code_len); + + self.add_local_extensible_predicate( + compilation_target.clone(), + key.clone(), + skeleton, + ); + } + } + } + + fn push_back_to_local_predicate_skeleton( + &mut self, + compilation_target: &CompilationTarget, + key: &PredicateKey, + code_len: usize, + ) { + match self + .wam + .indices + .get_local_predicate_skeleton_mut( + &self.compilation_target, + compilation_target.clone(), + key.clone(), + ) + { + Some(skeleton) => { + self.retraction_info.push_record( + RetractionRecord::SkeletonLocalClauseClausePopBack( + self.compilation_target.clone(), + compilation_target.clone(), + key.clone(), + ), + ); + + skeleton.clause_clause_locs.push_back(code_len); + } + None => { + let mut skeleton = PredicateSkeleton::new(); + skeleton.clause_clause_locs.push_back(code_len); + + self.add_local_extensible_predicate( + compilation_target.clone(), + key.clone(), + skeleton, + ); + } + } + } + pub(super) fn incremental_compile_clause( &mut self, key: PredicateKey, @@ -1523,7 +1645,7 @@ impl<'a> LoadState<'a> { compilation_target: CompilationTarget, non_counted_bt: bool, append_or_prepend: AppendOrPrepend, - ) -> Result<(), SessionError> { + ) -> Result { self.record_incremental_compile( key.clone(), compilation_target.clone(), @@ -1607,35 +1729,26 @@ impl<'a> LoadState<'a> { self.wam.machine_st.global_clock, ); - match self - .wam - .indices - .get_local_predicate_skeleton_mut( - &self.compilation_target, - compilation_target.clone(), - key.clone(), - ) - { - Some(skeleton) => { - self.retraction_info.push_record( - RetractionRecord::SkeletonLocalClauseClausePopBack( - self.compilation_target.clone(), - compilation_target.clone(), - key.clone(), - ), - ); + self.push_back_to_local_predicate_skeleton( + &compilation_target, + &key, + code_len, + ); - skeleton.clause_clause_locs.push_back(code_len); - } - None => { - let mut skeleton = PredicateSkeleton::new(); - skeleton.clause_clause_locs.push_back(code_len); + if let Some(filename) = self.listing_src_file_name() { + if let CompilationTarget::User = &compilation_target { + let compilation_target = mem::replace( + &mut self.compilation_target, + CompilationTarget::Module(filename), + ); - self.add_local_extensible_predicate( - compilation_target.clone(), - key.clone(), - skeleton, + self.push_back_to_local_predicate_skeleton( + &CompilationTarget::User, + &key, + code_len, ); + + self.compilation_target = compilation_target; } } @@ -1654,7 +1767,7 @@ impl<'a> LoadState<'a> { ); } - Ok(()) + Ok(code_index) } AppendOrPrepend::Prepend => { let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap(); @@ -1679,38 +1792,29 @@ impl<'a> LoadState<'a> { self.wam.machine_st.global_clock, ); - match self - .wam - .indices - .get_local_predicate_skeleton_mut( - &self.compilation_target, - compilation_target.clone(), - key.clone(), - ) - { - Some(skeleton) => { - self.retraction_info.push_record( - RetractionRecord::SkeletonLocalClauseClausePopFront( - self.compilation_target.clone(), - compilation_target.clone(), - key.clone(), - ), + if let Some(filename) = self.listing_src_file_name() { + if let CompilationTarget::User = &compilation_target { + let compilation_target = mem::replace( + &mut self.compilation_target, + CompilationTarget::Module(filename), ); - skeleton.clause_clause_locs.push_front(code_len); - } - None => { - let mut skeleton = PredicateSkeleton::new(); - skeleton.clause_clause_locs.push_front(code_len); - - self.add_local_extensible_predicate( - compilation_target.clone(), - key.clone(), - skeleton, + self.push_front_to_local_predicate_skeleton( + &CompilationTarget::User, + &key, + code_len, ); + + self.compilation_target = compilation_target; } } + self.push_front_to_local_predicate_skeleton( + &compilation_target, + &key, + code_len, + ); + let code_index = self.get_or_insert_code_index( key.clone(), compilation_target.clone(), @@ -1724,7 +1828,7 @@ impl<'a> LoadState<'a> { new_code_ptr, ); - Ok(()) + Ok(code_index) } } } @@ -2268,7 +2372,30 @@ impl<'a, TS: TermStream> Loader<'a, TS> { non_counted_bt, }; - self.load_state.compile(key.clone(), &mut self.predicates, settings)?; + let code_index + = self.load_state.compile(key.clone(), &mut self.predicates, settings)?; + + if let Some(filename) = self.load_state.listing_src_file_name() { + if let CompilationTarget::User = &self.predicates.compilation_target { + match self.load_state.wam.indices.modules.get_mut(&filename) { + Some(ref mut module) => { + let index_ptr = code_index.get(); + let code_index = module.code_dir.entry(key.clone()) + .or_insert(code_index); + + set_code_index( + &mut self.load_state.retraction_info, + &CompilationTarget::Module(filename), + key.clone(), + &code_index, + index_ptr, + ); + } + None => { + } + } + } + } } if predicate_info.is_dynamic { diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index 4e9d2033..c51328ff 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -903,7 +903,7 @@ impl<'a> LoadState<'a> { } } - pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) { + pub(crate) fn reset_in_situ_module(&mut self, module_decl: ModuleDecl, listing_src: &ListingSource) { let module_name = module_decl.name.clone(); self.remove_module_exports(module_name.clone()); @@ -947,6 +947,21 @@ impl<'a> LoadState<'a> { &skeleton.clause_clause_locs, ); } + + if &self.compilation_target == compilation_target { + let skeleton_opt = self.wam.indices.remove_predicate_skeleton( + compilation_target, + &key, + ); + + if let Some(skeleton) = skeleton_opt { + self.retraction_info.push_record(RetractionRecord::RemovedSkeleton( + compilation_target.clone(), + key.clone(), + skeleton, + )); + } + } } self.retraction_info.push_record(RetractionRecord::ReplacedModule( @@ -957,6 +972,11 @@ impl<'a> LoadState<'a> { } None => {} } + } + + pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) { + self.reset_in_situ_module(module_decl.clone(), &listing_src); + let module_name = module_decl.name.clone(); let mut module = match self.wam.indices.modules.remove(&module_name) { Some(mut module) => { diff --git a/src/machine/loader.rs b/src/machine/loader.rs index c5c5e2e8..7c1c76ad 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -726,7 +726,7 @@ pub(crate) struct Loader<'a, TermStream> { pub(super) load_state: LoadState<'a>, pub(super) predicates: PredicateQueue, pub(super) clause_clauses: Vec<(Term, Term)>, - term_stream: TermStream, + pub(super) term_stream: TermStream, pub(super) non_counted_bt_preds: IndexSet, } @@ -767,9 +767,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> { } let term = match term { - Term::Clause(_, name, terms, _) if name.as_str() == ":-" && terms.len() == 1 => { - return Ok(Some(setup_declaration(&self.load_state, terms)?)); - } + Term::Clause(_, name, terms, _) + if name.as_str() == ":-" && terms.len() == 1 => { + return Ok(Some(setup_declaration(&self.load_state, terms)?)); + } term => term, }; @@ -1463,6 +1464,36 @@ impl Machine { self.restore_load_state_payload(result, evacuable_h); } + pub(crate) fn add_in_situ_filename_module(&mut self) { + let (mut loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(1)); + + let add_in_situ_filename_module = || { + if let Some(filename) = loader.load_state.listing_src_file_name() { + let module_decl = ModuleDecl { + name: filename, + exports: vec![], + }; + + if !loader.load_state.wam.indices.modules.contains_key(&module_decl.name) { + let module_name = module_decl.name.clone(); + let module = Module::new(module_decl, ListingSource::DynamicallyGenerated); + + loader.load_state.wam.indices.modules.insert(module_name, module); + } else { + loader.load_state.reset_in_situ_module( + module_decl.clone(), + &ListingSource::DynamicallyGenerated, + ); + } + } + + LiveTermStream::evacuate(loader) + }; + + let result = add_in_situ_filename_module(); + self.restore_load_state_payload(result, evacuable_h); + } + pub(crate) fn loader_from_heap_evacuable( &mut self, r: RegType, diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index ab2f332d..90593d8f 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -425,6 +425,7 @@ pub(crate) enum REPLCodePtr { AddMultifilePredicate, AddGoalExpansionClause, AddTermExpansionClause, + AddInSituFilenameModule, ClauseToEvacuable, ScopedClauseToEvacuable, ConcludeLoad, diff --git a/src/machine/mod.rs b/src/machine/mod.rs index ad95a900..44a40e32 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -398,6 +398,9 @@ impl Machine { REPLCodePtr::AddTermExpansionClause => { self.add_term_expansion_clause(); } + REPLCodePtr::AddInSituFilenameModule => { + self.add_in_situ_filename_module(); + } REPLCodePtr::ClauseToEvacuable => { self.clause_to_evacuable(); } diff --git a/src/write.rs b/src/write.rs index 4aa84e99..1c1fc3dc 100644 --- a/src/write.rs +++ b/src/write.rs @@ -31,6 +31,8 @@ impl fmt::Display for REPLCodePtr { write!(f, "REPLCodePtr::AddGoalExpansionClause"), REPLCodePtr::AddTermExpansionClause => write!(f, "REPLCodePtr::AddTermExpansionClause"), + REPLCodePtr::AddInSituFilenameModule => + write!(f, "REPLCodePtr::AddInSituFilenameModule"), REPLCodePtr::AbolishClause => write!(f, "REPLCodePtr::AbolishClause"), REPLCodePtr::Assertz =>