add '$remove_module_exports' to loader.rs
This commit is contained in:
@@ -419,6 +419,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::REPL(REPLCodePtr::FlushTermQueue) => {
|
&SystemClauseType::REPL(REPLCodePtr::FlushTermQueue) => {
|
||||||
clause_name!("$flush_term_queue")
|
clause_name!("$flush_term_queue")
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::RemoveModuleExports) => {
|
||||||
|
clause_name!("$remove_module_exports")
|
||||||
|
}
|
||||||
&SystemClauseType::Close => clause_name!("$close"),
|
&SystemClauseType::Close => clause_name!("$close"),
|
||||||
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||||
@@ -772,6 +775,9 @@ impl SystemClauseType {
|
|||||||
("$flush_term_queue", 1) => {
|
("$flush_term_queue", 1) => {
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::FlushTermQueue))
|
Some(SystemClauseType::REPL(REPLCodePtr::FlushTermQueue))
|
||||||
}
|
}
|
||||||
|
("$remove_module_exports", 2) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::RemoveModuleExports))
|
||||||
|
}
|
||||||
("$variant", 2) => Some(SystemClauseType::Variant),
|
("$variant", 2) => Some(SystemClauseType::Variant),
|
||||||
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
|
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
|
||||||
("$write_term", 7) => Some(SystemClauseType::WriteTerm),
|
("$write_term", 7) => Some(SystemClauseType::WriteTerm),
|
||||||
|
|||||||
@@ -246,19 +246,30 @@ compile_dispatch((user:goal_expansion(Term, Terms) :- Body), Evacuable) :-
|
|||||||
'$add_goal_expansion_clause'(user, (goal_expansion(Term, Terms) :- Body), Evacuable).
|
'$add_goal_expansion_clause'(user, (goal_expansion(Term, Terms) :- Body), Evacuable).
|
||||||
|
|
||||||
|
|
||||||
|
remove_module(Module, Evacuable) :-
|
||||||
|
( nonvar(Module),
|
||||||
|
Module = library(ModuleName),
|
||||||
|
atom(ModuleName),
|
||||||
|
atom \== [] ->
|
||||||
|
'$remove_module_exports'(ModuleName, Evacuable)
|
||||||
|
; atom(Module),
|
||||||
|
atom \== [] ->
|
||||||
|
'$remove_module_exports'(Module, Evacuable)
|
||||||
|
; domain_error(module_specifier, Module, use_module/2)
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
compile_declaration(use_module(Module), Evacuable) :-
|
compile_declaration(use_module(Module), Evacuable) :-
|
||||||
use_module(Module, [], Evacuable).
|
use_module(Module, [], Evacuable).
|
||||||
compile_declaration(use_module(Module, Exports), Evacuable) :-
|
compile_declaration(use_module(Module, Exports), Evacuable) :-
|
||||||
( Exports == [] ->
|
( Exports == [] ->
|
||||||
'$remove_module_exports'(Module, Evacuable) % TODO: implement this.
|
remove_module(Module, Evacuable)
|
||||||
;
|
; use_module(Module, Exports, Evacuable)
|
||||||
use_module(Module, Exports, Evacuable)
|
|
||||||
).
|
).
|
||||||
compile_declaration(module(Module, Exports), Evacuable) :-
|
compile_declaration(module(Module, Exports), Evacuable) :-
|
||||||
( atom(Module) ->
|
( atom(Module) ->
|
||||||
'$declare_module'(Module, Exports, Evacuable)
|
'$declare_module'(Module, Exports, Evacuable)
|
||||||
;
|
; type_error(atom, Module, load/1)
|
||||||
type_error(atom, Module, load/1)
|
|
||||||
).
|
).
|
||||||
compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
||||||
!,
|
!,
|
||||||
@@ -375,7 +386,7 @@ use_module(Module) :-
|
|||||||
use_module(Module, Exports) :-
|
use_module(Module, Exports) :-
|
||||||
'$push_load_state_payload'(Evacuable),
|
'$push_load_state_payload'(Evacuable),
|
||||||
( Exports == [] ->
|
( Exports == [] ->
|
||||||
'$remove_module_exports'(Module, Evacuable)
|
remove_module(Module, Evacuable)
|
||||||
; use_module(Module, Exports, Evacuable)
|
; use_module(Module, Exports, Evacuable)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|||||||
@@ -459,6 +459,94 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn remove_module_exports(&mut self, module_name: ClauseName) {
|
||||||
|
let removed_module = match self.wam.indices.modules.remove(&module_name) {
|
||||||
|
Some(module) => module,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn remove_module_exports(
|
||||||
|
removed_module: &Module,
|
||||||
|
code_dir: &mut CodeDir,
|
||||||
|
op_dir: &mut OpDir,
|
||||||
|
retraction_info: &mut RetractionInfo,
|
||||||
|
predicate_retractor: impl Fn(PredicateKey, IndexPtr) -> RetractionRecord,
|
||||||
|
op_retractor: impl Fn(OpDecl, usize, Specifier) -> RetractionRecord,
|
||||||
|
) {
|
||||||
|
for export in removed_module.module_decl.exports.iter() {
|
||||||
|
match export {
|
||||||
|
ModuleExport::PredicateKey(ref key) => {
|
||||||
|
match (removed_module.code_dir.get(key), code_dir.get(key)) {
|
||||||
|
(Some(module_code_index), Some(target_code_index))
|
||||||
|
if module_code_index.get() == target_code_index.get() => {
|
||||||
|
let old_index_ptr = target_code_index.replace(IndexPtr::Undefined);
|
||||||
|
|
||||||
|
retraction_info.push_record(
|
||||||
|
predicate_retractor(key.clone(), old_index_ptr),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ModuleExport::OpDecl(op_decl) => {
|
||||||
|
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 {
|
||||||
|
let (prec, spec) = op_dir_value.shared_op_desc().get();
|
||||||
|
|
||||||
|
retraction_info.push_record(
|
||||||
|
op_retractor(op_decl.clone(), prec, spec),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &self.compilation_target {
|
||||||
|
CompilationTarget::User => {
|
||||||
|
remove_module_exports(
|
||||||
|
&removed_module,
|
||||||
|
&mut self.wam.indices.code_dir,
|
||||||
|
&mut self.wam.indices.op_dir,
|
||||||
|
&mut self.retraction_info,
|
||||||
|
RetractionRecord::ReplacedUserPredicate,
|
||||||
|
RetractionRecord::ReplacedUserOp,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
CompilationTarget::Module(ref target_module_name)
|
||||||
|
if target_module_name.as_str() != module_name.as_str() => {
|
||||||
|
let predicate_retractor = |key, index_ptr| {
|
||||||
|
RetractionRecord::ReplacedModulePredicate(
|
||||||
|
module_name.clone(), key, index_ptr,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let op_retractor = |op_decl, prec, spec| {
|
||||||
|
RetractionRecord::ReplacedModuleOp(
|
||||||
|
module_name.clone(), op_decl, prec, spec,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(module) = self.wam.indices.modules.get_mut(target_module_name) {
|
||||||
|
remove_module_exports(
|
||||||
|
&removed_module,
|
||||||
|
&mut module.code_dir,
|
||||||
|
&mut module.op_dir,
|
||||||
|
&mut self.retraction_info,
|
||||||
|
predicate_retractor,
|
||||||
|
op_retractor,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompilationTarget::Module(_) => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
self.wam.indices.modules.insert(module_name, removed_module);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_or_insert_local_code_index(
|
fn get_or_insert_local_code_index(
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
@@ -787,6 +875,7 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
pub(crate) fn add_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());
|
||||||
|
|
||||||
match self.wam.indices.modules.get_mut(&module_name) {
|
match self.wam.indices.modules.get_mut(&module_name) {
|
||||||
Some(module) => {
|
Some(module) => {
|
||||||
|
|||||||
@@ -1922,6 +1922,24 @@ impl Machine {
|
|||||||
self.restore_load_state_payload(result, evacuable_h);
|
self.restore_load_state_payload(result, evacuable_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn remove_module_exports(&mut self) {
|
||||||
|
let module_name = atom_from!(
|
||||||
|
self.machine_st,
|
||||||
|
self.machine_st
|
||||||
|
.store(self.machine_st.deref(self.machine_st[temp_v!(1)]))
|
||||||
|
);
|
||||||
|
|
||||||
|
let (mut loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(2));
|
||||||
|
|
||||||
|
let remove_module_exports = || {
|
||||||
|
loader.load_state.remove_module_exports(module_name);
|
||||||
|
LiveTermStream::evacuate(loader)
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = remove_module_exports();
|
||||||
|
self.restore_load_state_payload(result, evacuable_h);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn meta_predicate_property(&mut self) {
|
pub(crate) fn meta_predicate_property(&mut self) {
|
||||||
let module_name = atom_from!(
|
let module_name = atom_from!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
|
|||||||
@@ -448,6 +448,7 @@ pub enum REPLCodePtr {
|
|||||||
Retract,
|
Retract,
|
||||||
IsConsistentWithTermQueue,
|
IsConsistentWithTermQueue,
|
||||||
FlushTermQueue,
|
FlushTermQueue,
|
||||||
|
RemoveModuleExports,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|||||||
@@ -510,6 +510,9 @@ impl Machine {
|
|||||||
REPLCodePtr::FlushTermQueue => {
|
REPLCodePtr::FlushTermQueue => {
|
||||||
self.flush_term_queue();
|
self.flush_term_queue();
|
||||||
}
|
}
|
||||||
|
REPLCodePtr::RemoveModuleExports => {
|
||||||
|
self.remove_module_exports();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.p = CodePtr::Local(p);
|
self.machine_st.p = CodePtr::Local(p);
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
write!(f, "REPLCodePtr::IsConsistentWithTermQueue"),
|
write!(f, "REPLCodePtr::IsConsistentWithTermQueue"),
|
||||||
REPLCodePtr::FlushTermQueue =>
|
REPLCodePtr::FlushTermQueue =>
|
||||||
write!(f, "REPLCodePtr::FlushTermQueue"),
|
write!(f, "REPLCodePtr::FlushTermQueue"),
|
||||||
|
REPLCodePtr::RemoveModuleExports =>
|
||||||
|
write!(f, "REPLCodePtr::RemoveModuleExports"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user