From d9e42bfcbae82dd77e8ca64199c43481a7550773 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 3 May 2021 16:59:12 -0600 Subject: [PATCH] fix incremental compilation and multifile bugs --- src/lib/builtins.pl | 27 +++++++++++++++++++++------ src/lib/os.pl | 2 +- src/loader.pl | 2 +- src/machine/compile.rs | 20 ++++++++++++++++++-- src/machine/load_state.rs | 12 ++++++++++-- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl index 83d248bc..bddcabf5 100644 --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@ -834,8 +834,13 @@ asserta_clause(Head, Body) :- ( Name == (:), Arity =:= 2 -> arg(1, Head, Module), - arg(2, Head, F), - module_asserta_clause(F, Body, Module) + arg(2, Head, HeadAndBody), + ( HeadAndBody = (F :- Body1) -> + true + ; F = HeadAndBody, + Body1 = true + ), + module_asserta_clause(F, Body1, Module) ; '$head_is_dynamic'(user, Head) -> call_asserta(Head, Body, Name, Arity, user) ; '$no_such_predicate'(user, Head) -> @@ -883,8 +888,13 @@ assertz_clause(Head, Body) :- ( Name == (:), Arity =:= 2 -> arg(1, Head, Module), - arg(2, Head, F), - module_assertz_clause(F, Body, Module) + arg(2, Head, HeadAndBody), + ( HeadAndBody = (F :- Body1) -> + true + ; F = HeadAndBody, + Body1 = true + ), + module_assertz_clause(F, Body1, Module) ; '$head_is_dynamic'(user, Head) -> call_assertz(Head, Body, Name, Arity, user) ; '$no_such_predicate'(user, Head) -> @@ -973,8 +983,13 @@ retract_clause(Head, Body) :- ( Name == (:), Arity =:= 2 -> arg(1, Head, Module), - arg(2, Head, F), - retract_module_clause(F, Body, Module) + arg(2, Head, HeadAndBody), + ( HeadAndBody = (F :- Body1) -> + true + ; F = HeadAndBody, + Body1 = true + ), + retract_module_clause(F, Body1, Module) ; '$no_such_predicate'(user, Head) -> '$fail' ; '$head_is_dynamic'(user, Head) -> diff --git a/src/lib/os.pl b/src/lib/os.pl index b5d9608a..f12997b2 100644 --- a/src/lib/os.pl +++ b/src/lib/os.pl @@ -1,4 +1,4 @@ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Predicates for reasoning about the operating system (OS) environment. Written July 2020 by Markus Triska (triska@metalevel.at). diff --git a/src/loader.pl b/src/loader.pl index de6e8c53..7915ae37 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -90,7 +90,7 @@ unload_evacuable(Evacuable) :- run_initialization_goals :- prolog_load_context(module, Module), ( predicate_property(Module:'$initialization_goals'(_), dynamic) -> - findall(Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals), + findall(Module:Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals), abolish(Module:'$initialization_goals'/1), ( maplist(Module:call, Goals) -> true diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 987e88da..bb09fcda 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -103,12 +103,28 @@ fn lower_bound_of_target_clause(skeleton: &PredicateSkeleton, target_pos: usize) return target_pos - 1; } - for index in (0..target_pos - 1).rev() { + let mut index_loc_opt = None; + + for index in (0..target_pos).rev() { let current_arg_num = skeleton.clauses[index].opt_arg_index_key.arg_num(); if current_arg_num == 0 || current_arg_num != arg_num { return index + 1; } + + if let Some(index_loc) = index_loc_opt { + let current_index_loc = skeleton.clauses[index] + .opt_arg_index_key + .switch_on_term_loc(); + + if Some(index_loc) != current_index_loc { + return index + 1; + } + } else { + index_loc_opt = skeleton.clauses[index] + .opt_arg_index_key + .switch_on_term_loc(); + } } 0 @@ -1195,7 +1211,7 @@ fn append_compiled_clause( retraction_info, ); - if lower_bound == 0 { + if lower_bound == 0 && !skeleton.core.is_dynamic { code_ptr_opt = Some(target_pos_clause_start); } } diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index fd034a8b..d0a0d126 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -461,13 +461,21 @@ impl<'a> LoadState<'a> { } } - pub(super) fn remove_replaced_module(&mut self, module_name: ClauseName) { + pub(super) fn remove_replaced_in_situ_module(&mut self, module_name: ClauseName) { let removed_module = match self.wam.indices.modules.remove(&module_name) { Some(module) => module, None => return, }; for (key, code_index) in &removed_module.code_dir { + match removed_module + .local_extensible_predicates + .get(&(CompilationTarget::User, key.clone())) + { + Some(skeleton) if skeleton.is_multifile => continue, + _ => {} + } + if code_index.get() != IndexPtr::Undefined { let old_index_ptr = code_index.replace(IndexPtr::Undefined); @@ -919,7 +927,7 @@ impl<'a> LoadState<'a> { let module_name = module_decl.name.clone(); self.remove_module_exports(module_name.clone()); - self.remove_replaced_module(module_name.clone()); + self.remove_replaced_in_situ_module(module_name.clone()); match self.wam.indices.modules.get_mut(&module_name) { Some(module) => { -- 2.54.0