clear user-level definitions when reloading a file (#455)

This commit is contained in:
Mark Thom
2021-03-16 02:30:09 -06:00
parent 914fb09ed0
commit 51424aed32
8 changed files with 292 additions and 98 deletions

View File

@@ -372,6 +372,9 @@ impl SystemClauseType {
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => { &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
clause_name!("$push_load_state_payload") 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::Asserta) => clause_name!("$asserta"),
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"), &SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
&SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"), &SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
@@ -765,6 +768,9 @@ impl SystemClauseType {
("$push_load_state_payload", 1) => { ("$push_load_state_payload", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)) Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
} }
("$add_in_situ_filename_module", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule))
}
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)), ("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)), ("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)), ("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),

View File

@@ -105,6 +105,10 @@ file_load(_, _).
file_load(Stream, Path, Evacuable) :- file_load(Stream, Path, Evacuable) :-
create_file_load_context(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), catch((loader:load_loop(Stream, Evacuable),
loader:run_initialization_goals), loader:run_initialization_goals),
E, E,

View File

@@ -9,7 +9,7 @@ use crate::machine::preprocessor::*;
use crate::machine::term_stream::*; use crate::machine::term_stream::*;
use crate::machine::*; use crate::machine::*;
use slice_deque::sdeq; use slice_deque::{sdeq, SliceDeque};
use std::cell::Cell; use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
@@ -1316,6 +1316,18 @@ fn print_overwrite_warning(
} }
impl<'a> LoadState<'a> { impl<'a> LoadState<'a> {
pub(super) fn listing_src_file_name(&self) -> Option<ClauseName> {
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( fn compile_standalone_clause(
&mut self, &mut self,
term: Term, term: Term,
@@ -1349,7 +1361,7 @@ impl<'a> LoadState<'a> {
key: PredicateKey, key: PredicateKey,
predicates: &mut PredicateQueue, predicates: &mut PredicateQueue,
settings: CodeGenSettings, settings: CodeGenSettings,
) -> Result<(), SessionError> { ) -> Result<CodeIndex, SessionError> {
let code_index = self.get_or_insert_code_index( let code_index = self.get_or_insert_code_index(
key.clone(), key.clone(),
predicates.compilation_target.clone(), predicates.compilation_target.clone(),
@@ -1427,39 +1439,28 @@ impl<'a> LoadState<'a> {
} }
}; };
match self if let Some(filename) = self.listing_src_file_name() {
.wam if let CompilationTarget::User = &predicates.compilation_target {
.indices let compilation_target = mem::replace(
.get_local_predicate_skeleton_mut( &mut self.compilation_target,
&self.compilation_target, CompilationTarget::Module(filename),
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 ..]
); );
}
None => {
let mut skeleton = PredicateSkeleton::new();
skeleton.clause_clause_locs = clause_clause_locs;
self.add_local_extensible_predicate( self.extend_local_predicate_skeleton(
predicates.compilation_target.clone(), &CompilationTarget::User,
key.clone(), &key,
skeleton, clause_clause_locs.clone(),
); );
self.compilation_target = compilation_target;
} }
} }
self.extend_local_predicate_skeleton(
&predicates.compilation_target,
&key,
clause_clause_locs,
);
} }
print_overwrite_warning( print_overwrite_warning(
@@ -1469,20 +1470,22 @@ impl<'a> LoadState<'a> {
settings.is_dynamic(), settings.is_dynamic(),
); );
let index_ptr = if settings.is_dynamic() {
IndexPtr::DynamicIndex(code_ptr)
} else {
IndexPtr::Index(code_ptr)
};
set_code_index( set_code_index(
&mut self.retraction_info, &mut self.retraction_info,
&predicates.compilation_target, &predicates.compilation_target,
key, key,
&code_index, &code_index,
if settings.is_dynamic() { index_ptr,
IndexPtr::DynamicIndex(code_ptr)
} else {
IndexPtr::Index(code_ptr)
},
); );
self.wam.code_repo.code.extend(code.into_iter()); self.wam.code_repo.code.extend(code.into_iter());
Ok(()) Ok(code_index)
} }
fn record_incremental_compile( 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<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::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( pub(super) fn incremental_compile_clause(
&mut self, &mut self,
key: PredicateKey, key: PredicateKey,
@@ -1523,7 +1645,7 @@ impl<'a> LoadState<'a> {
compilation_target: CompilationTarget, compilation_target: CompilationTarget,
non_counted_bt: bool, non_counted_bt: bool,
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) -> Result<(), SessionError> { ) -> Result<CodeIndex, SessionError> {
self.record_incremental_compile( self.record_incremental_compile(
key.clone(), key.clone(),
compilation_target.clone(), compilation_target.clone(),
@@ -1607,35 +1729,26 @@ impl<'a> LoadState<'a> {
self.wam.machine_st.global_clock, self.wam.machine_st.global_clock,
); );
match self self.push_back_to_local_predicate_skeleton(
.wam &compilation_target,
.indices &key,
.get_local_predicate_skeleton_mut( code_len,
&self.compilation_target, );
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(
Some(skeleton) => { &mut self.compilation_target,
self.retraction_info.push_record( CompilationTarget::Module(filename),
RetractionRecord::SkeletonLocalClauseClausePopBack(
self.compilation_target.clone(),
compilation_target.clone(),
key.clone(),
),
); );
skeleton.clause_clause_locs.push_back(code_len); self.push_back_to_local_predicate_skeleton(
} &CompilationTarget::User,
None => { &key,
let mut skeleton = PredicateSkeleton::new(); code_len,
skeleton.clause_clause_locs.push_back(code_len);
self.add_local_extensible_predicate(
compilation_target.clone(),
key.clone(),
skeleton,
); );
self.compilation_target = compilation_target;
} }
} }
@@ -1654,7 +1767,7 @@ impl<'a> LoadState<'a> {
); );
} }
Ok(()) Ok(code_index)
} }
AppendOrPrepend::Prepend => { AppendOrPrepend::Prepend => {
let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap(); let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap();
@@ -1679,38 +1792,29 @@ impl<'a> LoadState<'a> {
self.wam.machine_st.global_clock, self.wam.machine_st.global_clock,
); );
match self if let Some(filename) = self.listing_src_file_name() {
.wam if let CompilationTarget::User = &compilation_target {
.indices let compilation_target = mem::replace(
.get_local_predicate_skeleton_mut( &mut self.compilation_target,
&self.compilation_target, CompilationTarget::Module(filename),
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); self.push_front_to_local_predicate_skeleton(
} &CompilationTarget::User,
None => { &key,
let mut skeleton = PredicateSkeleton::new(); code_len,
skeleton.clause_clause_locs.push_front(code_len);
self.add_local_extensible_predicate(
compilation_target.clone(),
key.clone(),
skeleton,
); );
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( let code_index = self.get_or_insert_code_index(
key.clone(), key.clone(),
compilation_target.clone(), compilation_target.clone(),
@@ -1724,7 +1828,7 @@ impl<'a> LoadState<'a> {
new_code_ptr, new_code_ptr,
); );
Ok(()) Ok(code_index)
} }
} }
} }
@@ -2268,7 +2372,30 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
non_counted_bt, 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 { if predicate_info.is_dynamic {

View File

@@ -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(); let module_name = module_decl.name.clone();
self.remove_module_exports(module_name.clone()); self.remove_module_exports(module_name.clone());
@@ -947,6 +947,21 @@ impl<'a> LoadState<'a> {
&skeleton.clause_clause_locs, &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( self.retraction_info.push_record(RetractionRecord::ReplacedModule(
@@ -957,6 +972,11 @@ impl<'a> LoadState<'a> {
} }
None => {} 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) { let mut module = match self.wam.indices.modules.remove(&module_name) {
Some(mut module) => { Some(mut module) => {

View File

@@ -726,7 +726,7 @@ pub(crate) struct Loader<'a, TermStream> {
pub(super) load_state: LoadState<'a>, pub(super) load_state: LoadState<'a>,
pub(super) predicates: PredicateQueue, pub(super) predicates: PredicateQueue,
pub(super) clause_clauses: Vec<(Term, Term)>, pub(super) clause_clauses: Vec<(Term, Term)>,
term_stream: TermStream, pub(super) term_stream: TermStream,
pub(super) non_counted_bt_preds: IndexSet<PredicateKey>, pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
} }
@@ -767,9 +767,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
} }
let term = match term { let term = match term {
Term::Clause(_, name, terms, _) if name.as_str() == ":-" && terms.len() == 1 => { Term::Clause(_, name, terms, _)
return Ok(Some(setup_declaration(&self.load_state, terms)?)); if name.as_str() == ":-" && terms.len() == 1 => {
} return Ok(Some(setup_declaration(&self.load_state, terms)?));
}
term => term, term => term,
}; };
@@ -1463,6 +1464,36 @@ impl Machine {
self.restore_load_state_payload(result, evacuable_h); 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( pub(crate) fn loader_from_heap_evacuable(
&mut self, &mut self,
r: RegType, r: RegType,

View File

@@ -425,6 +425,7 @@ pub(crate) enum REPLCodePtr {
AddMultifilePredicate, AddMultifilePredicate,
AddGoalExpansionClause, AddGoalExpansionClause,
AddTermExpansionClause, AddTermExpansionClause,
AddInSituFilenameModule,
ClauseToEvacuable, ClauseToEvacuable,
ScopedClauseToEvacuable, ScopedClauseToEvacuable,
ConcludeLoad, ConcludeLoad,

View File

@@ -398,6 +398,9 @@ impl Machine {
REPLCodePtr::AddTermExpansionClause => { REPLCodePtr::AddTermExpansionClause => {
self.add_term_expansion_clause(); self.add_term_expansion_clause();
} }
REPLCodePtr::AddInSituFilenameModule => {
self.add_in_situ_filename_module();
}
REPLCodePtr::ClauseToEvacuable => { REPLCodePtr::ClauseToEvacuable => {
self.clause_to_evacuable(); self.clause_to_evacuable();
} }

View File

@@ -31,6 +31,8 @@ impl fmt::Display for REPLCodePtr {
write!(f, "REPLCodePtr::AddGoalExpansionClause"), write!(f, "REPLCodePtr::AddGoalExpansionClause"),
REPLCodePtr::AddTermExpansionClause => REPLCodePtr::AddTermExpansionClause =>
write!(f, "REPLCodePtr::AddTermExpansionClause"), write!(f, "REPLCodePtr::AddTermExpansionClause"),
REPLCodePtr::AddInSituFilenameModule =>
write!(f, "REPLCodePtr::AddInSituFilenameModule"),
REPLCodePtr::AbolishClause => REPLCodePtr::AbolishClause =>
write!(f, "REPLCodePtr::AbolishClause"), write!(f, "REPLCodePtr::AbolishClause"),
REPLCodePtr::Assertz => REPLCodePtr::Assertz =>