fix use of local skeletons to reload predicates (#919)

This commit is contained in:
Mark Thom
2021-04-27 02:00:54 -06:00
parent 48225c3c0a
commit 7e4cfede7d
7 changed files with 540 additions and 601 deletions

View File

@@ -696,24 +696,22 @@ impl PredicateInfo {
} }
} }
#[derive(Debug)] #[derive(Clone, Debug)]
pub(crate) struct PredicateSkeleton { pub(crate) struct LocalPredicateSkeleton {
pub(crate) is_discontiguous: bool, pub(crate) is_discontiguous: bool,
pub(crate) is_dynamic: bool, pub(crate) is_dynamic: bool,
pub(crate) is_multifile: bool, pub(crate) is_multifile: bool,
pub(crate) clauses: SliceDeque<ClauseIndexInfo>,
pub(crate) clause_clause_locs: SliceDeque<usize>, pub(crate) clause_clause_locs: SliceDeque<usize>,
pub(crate) clause_assert_margin: usize, pub(crate) clause_assert_margin: usize,
} }
impl PredicateSkeleton { impl LocalPredicateSkeleton {
#[inline] #[inline]
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
PredicateSkeleton { Self {
is_discontiguous: false, is_discontiguous: false,
is_dynamic: false, is_dynamic: false,
is_multifile: false, is_multifile: false,
clauses: sdeq![],
clause_clause_locs: sdeq![], clause_clause_locs: sdeq![],
clause_assert_margin: 0, clause_assert_margin: 0,
} }
@@ -732,23 +730,56 @@ impl PredicateSkeleton {
#[inline] #[inline]
pub(crate) fn reset(&mut self) { pub(crate) fn reset(&mut self) {
self.clauses.clear();
self.clause_clause_locs.clear(); self.clause_clause_locs.clear();
self.clause_assert_margin = 0; self.clause_assert_margin = 0;
} }
}
#[derive(Clone, Debug)]
pub(crate) struct PredicateSkeleton {
pub(crate) core: LocalPredicateSkeleton,
pub(crate) clauses: SliceDeque<ClauseIndexInfo>,
}
impl PredicateSkeleton {
#[inline]
pub(crate) fn new() -> Self {
PredicateSkeleton {
core: LocalPredicateSkeleton::new(),
clauses: sdeq![],
}
}
#[inline]
pub(crate) fn predicate_info(&self) -> PredicateInfo {
PredicateInfo {
is_extensible: true,
is_discontiguous: self.core.is_discontiguous,
is_dynamic: self.core.is_dynamic,
is_multifile: self.core.is_multifile,
has_clauses: !self.clauses.is_empty(),
}
}
#[inline]
pub(crate) fn reset(&mut self) {
self.core.clause_clause_locs.clear();
self.core.clause_assert_margin = 0;
self.clauses.clear();
}
pub(crate) fn target_pos_of_clause_clause_loc( pub(crate) fn target_pos_of_clause_clause_loc(
&self, &self,
clause_clause_loc: usize, clause_clause_loc: usize,
) -> Option<usize> { ) -> Option<usize> {
let search_result = self.clause_clause_locs[0..self.clause_assert_margin] let search_result = self.core.clause_clause_locs[0..self.core.clause_assert_margin]
.binary_search_by(|loc| clause_clause_loc.cmp(&loc)); .binary_search_by(|loc| clause_clause_loc.cmp(&loc));
match search_result { match search_result {
Ok(loc) => Some(loc), Ok(loc) => Some(loc),
Err(_) => self.clause_clause_locs[self.clause_assert_margin..] Err(_) => self.core.clause_clause_locs[self.core.clause_assert_margin..]
.binary_search_by(|loc| loc.cmp(&clause_clause_loc)) .binary_search_by(|loc| loc.cmp(&clause_clause_loc))
.map(|loc| loc + self.clause_assert_margin) .map(|loc| loc + self.core.clause_assert_margin)
.ok(), .ok(),
} }
} }

View File

@@ -847,7 +847,7 @@ asserta_clause(Head, Body) :-
asserta(Clause) :- asserta(Clause) :-
( Clause \= (_ :- _) -> ( Clause \= (_ :- _) ->
Head = Clause, Head = Clause,
Body = true, Body = user:true,
asserta_clause(Head, Body) asserta_clause(Head, Body)
; Clause = (Head :- Body) -> ; Clause = (Head :- Body) ->
asserta_clause(Head, Body) asserta_clause(Head, Body)
@@ -897,7 +897,7 @@ assertz_clause(Head, Body) :-
assertz(Clause) :- assertz(Clause) :-
( Clause \= (_ :- _) -> ( Clause \= (_ :- _) ->
Head = Clause, Head = Clause,
Body = true, Body = user:true,
assertz_clause(Head, Body) assertz_clause(Head, Body)
; Clause = (Head :- Body) -> ; Clause = (Head :- Body) ->
assertz_clause(Head, Body) assertz_clause(Head, Body)

View File

@@ -509,7 +509,8 @@ use_module(Module, Exports, Evacuable) :-
; ( path_atom(Module, ModulePath) -> ; ( path_atom(Module, ModulePath) ->
load_context_path(ModulePath, Path), load_context_path(ModulePath, Path),
open_file(Path, Stream), open_file(Path, Stream),
file_load(Stream, Path, Subevacuable), stream_property(Stream, file_name(PathFileName)),
file_load(Stream, PathFileName, Subevacuable),
'$use_module'(Evacuable, Subevacuable, Exports) '$use_module'(Evacuable, Subevacuable, Exports)
; type_error(atom, Library, load/1) ; type_error(atom, Library, load/1)
) )

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::preprocessor::*; use crate::machine::preprocessor::*;
use crate::machine::*;
use crate::machine::term_stream::*; use crate::machine::term_stream::*;
use crate::machine::*;
use prolog_parser::clause_name; use prolog_parser::clause_name;
@@ -349,15 +349,15 @@ impl<'a> LoadState<'a> {
.indices .indices
.get_predicate_skeleton(&compilation_target, &key) .get_predicate_skeleton(&compilation_target, &key)
.map(|skeleton| { .map(|skeleton| {
(clause_locs (
clause_locs
.iter() .iter()
.map(|clause_clause_loc| { .map(|clause_clause_loc| {
skeleton.target_pos_of_clause_clause_loc( skeleton.target_pos_of_clause_clause_loc(*clause_clause_loc)
*clause_clause_loc,
)
}) })
.collect(), .collect(),
skeleton.is_dynamic) skeleton.core.is_dynamic,
)
}); });
if let Some((clause_target_poses, is_dynamic)) = result_opt { if let Some((clause_target_poses, is_dynamic)) = result_opt {
@@ -377,10 +377,7 @@ impl<'a> LoadState<'a> {
mut clause_target_poses: Vec<Option<usize>>, mut clause_target_poses: Vec<Option<usize>>,
is_dynamic: bool, is_dynamic: bool,
) { ) {
let old_compilation_target = mem::replace( let old_compilation_target = mem::replace(&mut self.compilation_target, compilation_target);
&mut self.compilation_target,
compilation_target,
);
while let Some(target_pos_opt) = clause_target_poses.pop() { while let Some(target_pos_opt) = clause_target_poses.pop() {
match target_pos_opt { match target_pos_opt {
@@ -408,15 +405,12 @@ impl<'a> LoadState<'a> {
) { ) {
let key = (clause_name!("$clause"), 2); let key = (clause_name!("$clause"), 2);
match self match self.wam.indices.get_local_predicate_skeleton_mut(
.wam self.compilation_target.clone(),
.indices
.get_local_predicate_skeleton_mut(
&self.compilation_target,
clause_clause_compilation_target.clone(), clause_clause_compilation_target.clone(),
self.listing_src_file_name(),
key.clone(), key.clone(),
) ) {
{
Some(skeleton) => { Some(skeleton) => {
self.retraction_info.push_record( self.retraction_info.push_record(
RetractionRecord::RemovedLocalSkeletonClauseLocations( RetractionRecord::RemovedLocalSkeletonClauseLocations(
@@ -436,11 +430,7 @@ impl<'a> LoadState<'a> {
} }
}; };
self.retract_local_clauses( self.retract_local_clauses(clause_clause_compilation_target, key, &clause_locs);
clause_clause_compilation_target,
key,
&clause_locs,
);
} }
pub(super) fn try_term_to_tl( pub(super) fn try_term_to_tl(
@@ -448,11 +438,7 @@ impl<'a> LoadState<'a> {
term: Term, term: Term,
preprocessor: &mut Preprocessor, preprocessor: &mut Preprocessor,
) -> Result<PredicateClause, SessionError> { ) -> Result<PredicateClause, SessionError> {
let tl = preprocessor.try_term_to_tl( let tl = preprocessor.try_term_to_tl(self, term, CutContext::BlocksCuts)?;
self,
term,
CutContext::BlocksCuts,
)?;
Ok(match tl { Ok(match tl {
TopLevel::Fact(fact) => PredicateClause::Fact(fact), TopLevel::Fact(fact) => PredicateClause::Fact(fact),
@@ -485,11 +471,12 @@ impl<'a> LoadState<'a> {
if code_index.get() != IndexPtr::Undefined { if code_index.get() != IndexPtr::Undefined {
let old_index_ptr = code_index.replace(IndexPtr::Undefined); let old_index_ptr = code_index.replace(IndexPtr::Undefined);
self.retraction_info.push_record( self.retraction_info
RetractionRecord::ReplacedModulePredicate( .push_record(RetractionRecord::ReplacedModulePredicate(
module_name.clone(), key.clone(), old_index_ptr, module_name.clone(),
), key.clone(),
); old_index_ptr,
));
} }
} }
@@ -515,25 +502,24 @@ impl<'a> LoadState<'a> {
ModuleExport::PredicateKey(ref key) => { ModuleExport::PredicateKey(ref key) => {
match (removed_module.code_dir.get(key), code_dir.get(key)) { match (removed_module.code_dir.get(key), code_dir.get(key)) {
(Some(module_code_index), Some(target_code_index)) (Some(module_code_index), Some(target_code_index))
if module_code_index.get() == target_code_index.get() => { if module_code_index.get() == target_code_index.get() =>
{
let old_index_ptr = target_code_index.replace(IndexPtr::Undefined); let old_index_ptr = target_code_index.replace(IndexPtr::Undefined);
retraction_info.push_record( retraction_info
predicate_retractor(key.clone(), old_index_ptr), .push_record(predicate_retractor(key.clone(), old_index_ptr));
);
} }
_ => {} _ => {}
} }
} }
ModuleExport::OpDecl(op_decl) => { ModuleExport::OpDecl(op_decl) => {
let op_dir_value_opt = op_dir.remove(&(op_decl.name.clone(), op_decl.fixity())); let op_dir_value_opt =
op_dir.remove(&(op_decl.name.clone(), op_decl.fixity()));
if let Some(op_dir_value) = op_dir_value_opt { if let Some(op_dir_value) = op_dir_value_opt {
let (prec, spec) = op_dir_value.shared_op_desc().get(); let (prec, spec) = op_dir_value.shared_op_desc().get();
retraction_info.push_record( retraction_info.push_record(op_retractor(op_decl.clone(), prec, spec));
op_retractor(op_decl.clone(), prec, spec),
);
} }
} }
} }
@@ -552,17 +538,14 @@ impl<'a> LoadState<'a> {
); );
} }
CompilationTarget::Module(ref target_module_name) CompilationTarget::Module(ref target_module_name)
if target_module_name.as_str() != module_name.as_str() => { if target_module_name.as_str() != module_name.as_str() =>
{
let predicate_retractor = |key, index_ptr| { let predicate_retractor = |key, index_ptr| {
RetractionRecord::ReplacedModulePredicate( RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, index_ptr)
module_name.clone(), key, index_ptr,
)
}; };
let op_retractor = |op_decl, prec, spec| { let op_retractor = |op_decl, prec, spec| {
RetractionRecord::ReplacedModuleOp( RetractionRecord::ReplacedModuleOp(module_name.clone(), op_decl, prec, spec)
module_name.clone(), op_decl, prec, spec,
)
}; };
if let Some(module) = self.wam.indices.modules.get_mut(target_module_name) { if let Some(module) = self.wam.indices.modules.get_mut(target_module_name) {
@@ -578,7 +561,7 @@ impl<'a> LoadState<'a> {
unreachable!() unreachable!()
} }
} }
CompilationTarget::Module(_) => {}, CompilationTarget::Module(_) => {}
}; };
self.wam.indices.modules.insert(module_name, removed_module); self.wam.indices.modules.insert(module_name, removed_module);
@@ -599,13 +582,11 @@ impl<'a> LoadState<'a> {
self.add_dynamically_generated_module(&module_name); self.add_dynamically_generated_module(&module_name);
match self.wam.indices.modules.get_mut(&module_name) { match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => { Some(ref mut module) => module
module
.code_dir .code_dir
.entry(key) .entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone() .clone(),
}
None => { None => {
unreachable!() unreachable!()
} }
@@ -665,18 +646,14 @@ impl<'a> LoadState<'a> {
.extensible_predicates .extensible_predicates
.insert(key.clone(), skeleton); .insert(key.clone(), skeleton);
let record = RetractionRecord::AddedExtensiblePredicate( let record =
CompilationTarget::User, RetractionRecord::AddedExtensiblePredicate(CompilationTarget::User, key);
key,
);
self.retraction_info.push_record(record); self.retraction_info.push_record(record);
} }
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => {
if let Some(module) = self.wam.indices.modules.get_mut(&module_name) { if let Some(module) = self.wam.indices.modules.get_mut(&module_name) {
module module.extensible_predicates.insert(key.clone(), skeleton);
.extensible_predicates
.insert(key.clone(), skeleton);
let record = RetractionRecord::AddedExtensiblePredicate( let record = RetractionRecord::AddedExtensiblePredicate(
CompilationTarget::Module(module_name), CompilationTarget::Module(module_name),
@@ -696,9 +673,14 @@ impl<'a> LoadState<'a> {
&mut self, &mut self,
local_compilation_target: CompilationTarget, local_compilation_target: CompilationTarget,
key: PredicateKey, key: PredicateKey,
skeleton: PredicateSkeleton, skeleton: LocalPredicateSkeleton,
) { ) {
match self.compilation_target.clone() { let src_compilation_target = match self.listing_src_file_name() {
Some(filename) => CompilationTarget::Module(filename),
None => self.compilation_target.clone(),
};
match src_compilation_target {
CompilationTarget::User => { CompilationTarget::User => {
self.wam self.wam
.indices .indices
@@ -725,8 +707,7 @@ impl<'a> LoadState<'a> {
Some(ref mut module) => { Some(ref mut module) => {
op_decl.insert_into_op_dir(&mut module.op_dir); op_decl.insert_into_op_dir(&mut module.op_dir);
} }
None => { None => {}
}
} }
} }
@@ -911,11 +892,16 @@ impl<'a> LoadState<'a> {
code_dir, code_dir,
op_dir, op_dir,
meta_predicates, meta_predicates,
).unwrap(); )
.unwrap();
} }
} }
pub(crate) fn reset_in_situ_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());
@@ -940,8 +926,8 @@ impl<'a> LoadState<'a> {
let is_dynamic = self let is_dynamic = self
.wam .wam
.indices .indices
.get_predicate_skeleton(&compilation_target, &key) .get_predicate_skeleton(compilation_target, key)
.map(|skeleton| skeleton.is_dynamic) .map(|skeleton| skeleton.core.is_dynamic)
.unwrap_or(false); .unwrap_or(false);
if is_dynamic { if is_dynamic {
@@ -949,9 +935,7 @@ impl<'a> LoadState<'a> {
CompilationTarget::User => { CompilationTarget::User => {
CompilationTarget::Module(clause_name!("builtins")) CompilationTarget::Module(clause_name!("builtins"))
} }
module => { module => module.clone(),
module.clone()
}
}; };
self.retract_local_clause_clauses( self.retract_local_clause_clauses(
@@ -959,33 +943,10 @@ impl<'a> LoadState<'a> {
&skeleton.clause_clause_locs, &skeleton.clause_clause_locs,
); );
} }
if &self.compilation_target == compilation_target {
if let CompilationTarget::User = &self.compilation_target {
match (key.0.as_str(), key.1) {
("term_expansion", 2) | ("goal_expansion", 2) => {
continue;
}
_ => {}
}
} }
let skeleton_opt = self.wam.indices.remove_predicate_skeleton( self.retraction_info
compilation_target, .push_record(RetractionRecord::ReplacedModule(
&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(
old_module_decl, old_module_decl,
listing_src.clone(), listing_src.clone(),
local_extensible_predicates, local_extensible_predicates,

View File

@@ -198,14 +198,14 @@ impl<'a> Drop for LoadState<'a> {
.extensible_predicates .extensible_predicates
.get_mut(&key) .get_mut(&key)
.map(|skeleton| { .map(|skeleton| {
skeleton.is_discontiguous = false; skeleton.core.is_discontiguous = false;
}); });
} }
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => {
match self.wam.indices.modules.get_mut(&module_name) { match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => { Some(ref mut module) => {
module.extensible_predicates.get_mut(&key).map(|skeleton| { module.extensible_predicates.get_mut(&key).map(|skeleton| {
skeleton.is_discontiguous = false; skeleton.core.is_discontiguous = false;
}); });
} }
None => {} None => {}
@@ -221,14 +221,14 @@ impl<'a> Drop for LoadState<'a> {
.extensible_predicates .extensible_predicates
.get_mut(&key) .get_mut(&key)
.map(|skeleton| { .map(|skeleton| {
skeleton.is_dynamic = false; skeleton.core.is_dynamic = false;
}); });
} }
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => {
match self.wam.indices.modules.get_mut(&module_name) { match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => { Some(ref mut module) => {
module.extensible_predicates.get_mut(&key).map(|skeleton| { module.extensible_predicates.get_mut(&key).map(|skeleton| {
skeleton.is_dynamic = false; skeleton.core.is_dynamic = false;
}); });
} }
None => {} None => {}
@@ -244,14 +244,14 @@ impl<'a> Drop for LoadState<'a> {
.extensible_predicates .extensible_predicates
.get_mut(&key) .get_mut(&key)
.map(|skeleton| { .map(|skeleton| {
skeleton.is_multifile = false; skeleton.core.is_multifile = false;
}); });
} }
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => {
match self.wam.indices.modules.get_mut(&module_name) { match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => { Some(ref mut module) => {
module.extensible_predicates.get_mut(&key).map(|skeleton| { module.extensible_predicates.get_mut(&key).map(|skeleton| {
skeleton.is_multifile = false; skeleton.core.is_multifile = false;
}); });
} }
None => {} None => {}
@@ -429,7 +429,7 @@ impl<'a> Drop for LoadState<'a> {
{ {
Some(skeleton) => { Some(skeleton) => {
skeleton.clauses.pop_back(); skeleton.clauses.pop_back();
skeleton.clause_clause_locs.pop_back(); skeleton.core.clause_clause_locs.pop_back();
} }
None => {} None => {}
} }
@@ -442,8 +442,8 @@ impl<'a> Drop for LoadState<'a> {
{ {
Some(skeleton) => { Some(skeleton) => {
skeleton.clauses.pop_front(); skeleton.clauses.pop_front();
skeleton.clause_clause_locs.pop_front(); skeleton.core.clause_clause_locs.pop_front();
skeleton.clause_assert_margin -= 1; skeleton.core.clause_assert_margin -= 1;
} }
None => {} None => {}
} }
@@ -454,8 +454,9 @@ impl<'a> Drop for LoadState<'a> {
key, key,
) => { ) => {
match self.wam.indices.get_local_predicate_skeleton_mut( match self.wam.indices.get_local_predicate_skeleton_mut(
&src_compilation_target, src_compilation_target,
local_compilation_target, local_compilation_target,
self.listing_src_file_name(),
key, key,
) { ) {
Some(skeleton) => { Some(skeleton) => {
@@ -470,8 +471,9 @@ impl<'a> Drop for LoadState<'a> {
key, key,
) => { ) => {
match self.wam.indices.get_local_predicate_skeleton_mut( match self.wam.indices.get_local_predicate_skeleton_mut(
&src_compilation_target, src_compilation_target,
local_compilation_target, local_compilation_target,
self.listing_src_file_name(),
key, key,
) { ) {
Some(skeleton) => { Some(skeleton) => {
@@ -487,8 +489,9 @@ impl<'a> Drop for LoadState<'a> {
len, len,
) => { ) => {
match self.wam.indices.get_local_predicate_skeleton_mut( match self.wam.indices.get_local_predicate_skeleton_mut(
&src_compilation_target, src_compilation_target,
local_compilation_target, local_compilation_target,
self.listing_src_file_name(),
key, key,
) { ) {
Some(skeleton) => { Some(skeleton) => {
@@ -505,7 +508,7 @@ impl<'a> Drop for LoadState<'a> {
{ {
Some(skeleton) => { Some(skeleton) => {
skeleton.clauses.truncate_back(len); skeleton.clauses.truncate_back(len);
skeleton.clause_clause_locs.truncate_back(len); skeleton.core.clause_clause_locs.truncate_back(len);
} }
None => {} None => {}
} }
@@ -541,6 +544,7 @@ impl<'a> Drop for LoadState<'a> {
{ {
Some(skeleton) => { Some(skeleton) => {
skeleton skeleton
.core
.clause_clause_locs .clause_clause_locs
.insert(target_pos, clause_clause_loc); .insert(target_pos, clause_clause_loc);
skeleton.clauses.insert(target_pos, clause_index_info); skeleton.clauses.insert(target_pos, clause_index_info);
@@ -558,8 +562,9 @@ impl<'a> Drop for LoadState<'a> {
clause_locs, clause_locs,
) => { ) => {
match self.wam.indices.get_local_predicate_skeleton_mut( match self.wam.indices.get_local_predicate_skeleton_mut(
&compilation_target, compilation_target,
local_compilation_target, local_compilation_target,
self.listing_src_file_name(),
key, key,
) { ) {
Some(skeleton) => skeleton.clause_clause_locs = clause_locs, Some(skeleton) => skeleton.clause_clause_locs = clause_locs,
@@ -581,10 +586,14 @@ impl<'a> Drop for LoadState<'a> {
RetractionRecord::ReplacedDynamicElseOffset(instr_loc, next) => { RetractionRecord::ReplacedDynamicElseOffset(instr_loc, next) => {
match &mut self.wam.code_repo.code[instr_loc] { match &mut self.wam.code_repo.code[instr_loc] {
Line::Choice(ChoiceInstruction::DynamicElse( Line::Choice(ChoiceInstruction::DynamicElse(
_, _, NextOrFail::Next(ref mut o), _,
)) | _,
Line::Choice(ChoiceInstruction::DynamicInternalElse( NextOrFail::Next(ref mut o),
_, _, NextOrFail::Next(ref mut o), ))
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
_,
_,
NextOrFail::Next(ref mut o),
)) => { )) => {
*o = next; *o = next;
} }
@@ -594,10 +603,14 @@ impl<'a> Drop for LoadState<'a> {
RetractionRecord::AppendedNextOrFail(instr_loc, fail) => { RetractionRecord::AppendedNextOrFail(instr_loc, fail) => {
match &mut self.wam.code_repo.code[instr_loc] { match &mut self.wam.code_repo.code[instr_loc] {
Line::Choice(ChoiceInstruction::DynamicElse( Line::Choice(ChoiceInstruction::DynamicElse(
_, _, ref mut next_or_fail, _,
)) | _,
Line::Choice(ChoiceInstruction::DynamicInternalElse( ref mut next_or_fail,
_, _, ref mut next_or_fail, ))
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
_,
_,
ref mut next_or_fail,
)) => { )) => {
*next_or_fail = fail; *next_or_fail = fail;
} }
@@ -731,8 +744,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
} }
let term = match term { let term = match term {
Term::Clause(_, name, terms, _) Term::Clause(_, name, terms, _) if name.as_str() == ":-" && terms.len() == 1 => {
if name.as_str() == ":-" && terms.len() == 1 => {
return Ok(Some(setup_declaration(&self.load_state, terms)?)); return Ok(Some(setup_declaration(&self.load_state, terms)?));
} }
term => term, term => term,
@@ -905,7 +917,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
compilation_target: CompilationTarget, compilation_target: CompilationTarget,
name: ClauseName, name: ClauseName,
arity: usize, arity: usize,
flag_accessor: impl Fn(&mut PredicateSkeleton) -> &mut bool, flag_accessor: impl Fn(&mut LocalPredicateSkeleton) -> &mut bool,
retraction_fn: impl Fn(CompilationTarget, PredicateKey) -> RetractionRecord, retraction_fn: impl Fn(CompilationTarget, PredicateKey) -> RetractionRecord,
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
let key = (name, arity); let key = (name, arity);
@@ -920,9 +932,9 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
.extensible_predicates .extensible_predicates
.get_mut(&key) .get_mut(&key)
{ {
Some(ref mut skeleton) => { Some(skeleton) => {
if !*flag_accessor(skeleton) { if !*flag_accessor(&mut skeleton.core) {
*flag_accessor(skeleton) = true; *flag_accessor(&mut skeleton.core) = true;
self.load_state.retraction_info.push_record(retraction_fn( self.load_state.retraction_info.push_record(retraction_fn(
compilation_target.clone(), compilation_target.clone(),
@@ -933,7 +945,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
None => { None => {
if self.load_state.compilation_target == compilation_target { if self.load_state.compilation_target == compilation_target {
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton.core) = true;
self.load_state.add_extensible_predicate( self.load_state.add_extensible_predicate(
key.clone(), key.clone(),
@@ -950,8 +962,8 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
match self.load_state.wam.indices.modules.get_mut(module_name) { match self.load_state.wam.indices.modules.get_mut(module_name) {
Some(ref mut module) => match module.extensible_predicates.get_mut(&key) { Some(ref mut module) => match module.extensible_predicates.get_mut(&key) {
Some(ref mut skeleton) => { Some(ref mut skeleton) => {
if !*flag_accessor(skeleton) { if !*flag_accessor(&mut skeleton.core) {
*flag_accessor(skeleton) = true; *flag_accessor(&mut skeleton.core) = true;
self.load_state.retraction_info.push_record(retraction_fn( self.load_state.retraction_info.push_record(retraction_fn(
compilation_target.clone(), compilation_target.clone(),
@@ -962,7 +974,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
None => { None => {
if self.load_state.compilation_target == compilation_target { if self.load_state.compilation_target == compilation_target {
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton.core) = true;
self.load_state.add_extensible_predicate( self.load_state.add_extensible_predicate(
key.clone(), key.clone(),
@@ -979,7 +991,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
.add_dynamically_generated_module(module_name); .add_dynamically_generated_module(module_name);
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton.core) = true;
self.load_state.add_extensible_predicate( self.load_state.add_extensible_predicate(
key.clone(), key.clone(),
@@ -998,16 +1010,19 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
.load_state .load_state
.wam .wam
.indices .indices
.local_extensible_predicates .get_local_predicate_skeleton_mut(
.get_mut(&(compilation_target.clone(), key.clone())) self.load_state.compilation_target.clone(),
{ compilation_target.clone(),
Some(ref mut skeleton) => { self.load_state.listing_src_file_name(),
key.clone(),
) {
Some(skeleton) => {
if !*flag_accessor(skeleton) { if !*flag_accessor(skeleton) {
*flag_accessor(skeleton) = true; *flag_accessor(skeleton) = true;
} }
} }
None => { None => {
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = LocalPredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton) = true;
self.load_state.add_local_extensible_predicate( self.load_state.add_local_extensible_predicate(
@@ -1020,17 +1035,17 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
} }
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(ref module_name) => {
match self.load_state.wam.indices.modules.get_mut(module_name) { match self.load_state.wam.indices.modules.get_mut(module_name) {
Some(ref mut module) => match module Some(module) => match module
.local_extensible_predicates .local_extensible_predicates
.get_mut(&(compilation_target.clone(), key.clone())) .get_mut(&(compilation_target.clone(), key.clone()))
{ {
Some(ref mut skeleton) => { Some(skeleton) => {
if !*flag_accessor(skeleton) { if !*flag_accessor(skeleton) {
*flag_accessor(skeleton) = true; *flag_accessor(skeleton) = true;
} }
} }
None => { None => {
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = LocalPredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton) = true;
self.load_state.add_local_extensible_predicate( self.load_state.add_local_extensible_predicate(
@@ -1044,7 +1059,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
self.load_state self.load_state
.add_dynamically_generated_module(module_name); .add_dynamically_generated_module(module_name);
let mut skeleton = PredicateSkeleton::new(); let mut skeleton = LocalPredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true; *flag_accessor(&mut skeleton) = true;
self.load_state.add_local_extensible_predicate( self.load_state.add_local_extensible_predicate(
@@ -1139,7 +1154,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
&self.predicates.compilation_target, &self.predicates.compilation_target,
&(predicate_name, arity), &(predicate_name, arity),
) )
.map(|skeleton| skeleton.is_dynamic) .map(|skeleton| skeleton.core.is_dynamic)
.unwrap_or(false); .unwrap_or(false);
if is_dynamic { if is_dynamic {
@@ -1156,8 +1171,9 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
.wam .wam
.indices .indices
.get_local_predicate_skeleton_mut( .get_local_predicate_skeleton_mut(
&self.load_state.compilation_target, self.load_state.compilation_target.clone(),
self.predicates.compilation_target.clone(), self.predicates.compilation_target.clone(),
self.load_state.listing_src_file_name(),
key.clone(), key.clone(),
) { ) {
Some(skeleton) if !skeleton.clause_clause_locs.is_empty() => { Some(skeleton) if !skeleton.clause_clause_locs.is_empty() => {
@@ -1440,9 +1456,20 @@ impl Machine {
let module_name = module_decl.name.clone(); let module_name = module_decl.name.clone();
if !loader.load_state.wam.indices.modules.contains_key(&module_decl.name) { if !loader
.load_state
.wam
.indices
.modules
.contains_key(&module_decl.name)
{
let module = Module::new_in_situ(module_decl); let module = Module::new_in_situ(module_decl);
loader.load_state.wam.indices.modules.insert(module_name, module); loader
.load_state
.wam
.indices
.modules
.insert(module_name, module);
} else { } else {
loader.load_state.reset_in_situ_module( loader.load_state.reset_in_situ_module(
module_decl.clone(), module_decl.clone(),
@@ -1458,8 +1485,7 @@ impl Machine {
op_decl.remove(&mut loader.load_state.wam.indices.op_dir); op_decl.remove(&mut loader.load_state.wam.indices.op_dir);
} }
} }
None => { None => {}
}
} }
} }
} }
@@ -1638,7 +1664,8 @@ impl Machine {
.push(HeapCellValue::Atom(path_atom, None)), .push(HeapCellValue::Atom(path_atom, None)),
); );
self.machine_st.unify(path_addr, self.machine_st[temp_v!(1)]); self.machine_st
.unify(path_addr, self.machine_st[temp_v!(1)]);
} else { } else {
self.machine_st.fail = true; self.machine_st.fail = true;
} }
@@ -1658,7 +1685,8 @@ impl Machine {
.push(HeapCellValue::Atom(file_name_atom, None)), .push(HeapCellValue::Atom(file_name_atom, None)),
); );
self.machine_st.unify(file_name_addr, self.machine_st[temp_v!(1)]); self.machine_st
.unify(file_name_addr, self.machine_st[temp_v!(1)]);
return; return;
} }
_ => { _ => {
@@ -1684,7 +1712,8 @@ impl Machine {
.push(HeapCellValue::Atom(directory_atom, None)), .push(HeapCellValue::Atom(directory_atom, None)),
); );
self.machine_st.unify(directory_addr, self.machine_st[temp_v!(1)]); self.machine_st
.unify(directory_addr, self.machine_st[temp_v!(1)]);
return; return;
} }
} }
@@ -1700,7 +1729,8 @@ impl Machine {
.push(HeapCellValue::Atom(load_context.module.clone(), None)), .push(HeapCellValue::Atom(load_context.module.clone(), None)),
); );
self.machine_st.unify(module_name_addr, self.machine_st[temp_v!(1)]); self.machine_st
.unify(module_name_addr, self.machine_st[temp_v!(1)]);
} else { } else {
self.machine_st.fail = true; self.machine_st.fail = true;
} }
@@ -1714,7 +1744,8 @@ impl Machine {
.push(HeapCellValue::Stream(load_context.stream.clone())), .push(HeapCellValue::Stream(load_context.stream.clone())),
); );
self.machine_st.unify(stream_addr, self.machine_st[temp_v!(1)]); self.machine_st
.unify(stream_addr, self.machine_st[temp_v!(1)]);
} else { } else {
self.machine_st.fail = true; self.machine_st.fail = true;
} }
@@ -1752,11 +1783,7 @@ impl Machine {
); );
// if a new predicate was just created, make it dynamic. // if a new predicate was just created, make it dynamic.
loader.add_dynamic_predicate( loader.add_dynamic_predicate(compilation_target.clone(), key.0.clone(), key.1)?;
compilation_target.clone(),
key.0.clone(),
key.1,
)?;
loader.load_state.incremental_compile_clause( loader.load_state.incremental_compile_clause(
key.clone(), key.clone(),
@@ -1833,6 +1860,7 @@ impl Machine {
) )
.map(|clause_clause_skeleton| { .map(|clause_clause_skeleton| {
skeleton skeleton
.core
.clause_clause_locs .clause_clause_locs
.iter() .iter()
.map(|clause_clause_loc| { .map(|clause_clause_loc| {
@@ -2060,7 +2088,8 @@ impl Machine {
.heap .heap
.push(HeapCellValue::Addr(Addr::HeapCell(list_loc))); .push(HeapCellValue::Addr(Addr::HeapCell(list_loc)));
self.machine_st.unify(Addr::HeapCell(heap_loc), self.machine_st[temp_v!(4)]); self.machine_st
.unify(Addr::HeapCell(heap_loc), self.machine_st[temp_v!(4)]);
} }
None => { None => {
self.machine_st.fail = true; self.machine_st.fail = true;
@@ -2089,7 +2118,7 @@ impl Machine {
.get_predicate_skeleton(&compilation_target, &key) .get_predicate_skeleton(&compilation_target, &key)
{ {
Some(skeleton) => { Some(skeleton) => {
self.machine_st.fail = !skeleton.is_dynamic; self.machine_st.fail = !skeleton.core.is_dynamic;
} }
None => { None => {
self.machine_st.fail = true; self.machine_st.fail = true;
@@ -2118,7 +2147,7 @@ impl Machine {
.get_predicate_skeleton(&compilation_target, &key) .get_predicate_skeleton(&compilation_target, &key)
{ {
Some(skeleton) => { Some(skeleton) => {
self.machine_st.fail = !skeleton.is_multifile; self.machine_st.fail = !skeleton.core.is_multifile;
} }
None => { None => {
self.machine_st.fail = true; self.machine_st.fail = true;
@@ -2147,7 +2176,7 @@ impl Machine {
.get_predicate_skeleton(&compilation_target, &key) .get_predicate_skeleton(&compilation_target, &key)
{ {
Some(skeleton) => { Some(skeleton) => {
self.machine_st.fail = !skeleton.is_discontiguous; self.machine_st.fail = !skeleton.core.is_discontiguous;
} }
None => { None => {
self.machine_st.fail = true; self.machine_st.fail = true;

View File

@@ -673,7 +673,7 @@ pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>>;
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>; pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
pub(crate) type LocalExtensiblePredicates = pub(crate) type LocalExtensiblePredicates =
IndexMap<(CompilationTarget, PredicateKey), PredicateSkeleton>; IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton>;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct IndexStore { pub(crate) struct IndexStore {
@@ -716,12 +716,34 @@ impl IndexStore {
} }
} }
pub(crate) fn get_predicate_skeleton(
&self,
compilation_target: &CompilationTarget,
key: &PredicateKey,
) -> Option<&PredicateSkeleton> {
match compilation_target {
CompilationTarget::User => self.extensible_predicates.get(key),
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get(module_name) {
module.extensible_predicates.get(key)
} else {
None
}
}
}
}
pub(crate) fn get_local_predicate_skeleton_mut( pub(crate) fn get_local_predicate_skeleton_mut(
&mut self, &mut self,
src_compilation_target: &CompilationTarget, mut src_compilation_target: CompilationTarget,
local_compilation_target: CompilationTarget, local_compilation_target: CompilationTarget,
listing_src_file_name: Option<ClauseName>,
key: PredicateKey, key: PredicateKey,
) -> Option<&mut PredicateSkeleton> { ) -> Option<&mut LocalPredicateSkeleton> {
if let Some(filename) = listing_src_file_name {
src_compilation_target = CompilationTarget::Module(filename);
}
match src_compilation_target { match src_compilation_target {
CompilationTarget::User => self CompilationTarget::User => self
.local_extensible_predicates .local_extensible_predicates
@@ -740,10 +762,15 @@ impl IndexStore {
pub(crate) fn get_local_predicate_skeleton( pub(crate) fn get_local_predicate_skeleton(
&self, &self,
src_compilation_target: &CompilationTarget, mut src_compilation_target: CompilationTarget,
local_compilation_target: CompilationTarget, local_compilation_target: CompilationTarget,
listing_src_file_name: Option<ClauseName>,
key: PredicateKey, key: PredicateKey,
) -> Option<&PredicateSkeleton> { ) -> Option<&LocalPredicateSkeleton> {
if let Some(filename) = listing_src_file_name {
src_compilation_target = CompilationTarget::Module(filename);
}
match src_compilation_target { match src_compilation_target {
CompilationTarget::User => self CompilationTarget::User => self
.local_extensible_predicates .local_extensible_predicates
@@ -760,23 +787,6 @@ impl IndexStore {
} }
} }
pub(crate) fn get_predicate_skeleton(
&self,
compilation_target: &CompilationTarget,
key: &PredicateKey,
) -> Option<&PredicateSkeleton> {
match compilation_target {
CompilationTarget::User => self.extensible_predicates.get(key),
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get(module_name) {
module.extensible_predicates.get(key)
} else {
None
}
}
}
}
pub(crate) fn remove_predicate_skeleton( pub(crate) fn remove_predicate_skeleton(
&mut self, &mut self,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
@@ -845,13 +855,13 @@ impl IndexStore {
"user" => self "user" => self
.extensible_predicates .extensible_predicates
.get(&key) .get(&key)
.map(|skeleton| skeleton.is_dynamic) .map(|skeleton| skeleton.core.is_dynamic)
.unwrap_or(false), .unwrap_or(false),
_ => match self.modules.get(&module_name) { _ => match self.modules.get(&module_name) {
Some(ref module) => module Some(ref module) => module
.extensible_predicates .extensible_predicates
.get(&key) .get(&key)
.map(|skeleton| skeleton.is_dynamic) .map(|skeleton| skeleton.core.is_dynamic)
.unwrap_or(false), .unwrap_or(false),
None => false, None => false,
}, },