]> Repositorios git - scryer-prolog.git/commitdiff
fix retraction of local dynamic predicates (#2215, #2232)
authorMark <[email protected]>
Mon, 18 Dec 2023 20:26:36 +0000 (13:26 -0700)
committerMark <[email protected]>
Mon, 18 Dec 2023 20:28:45 +0000 (13:28 -0700)
src/machine/compile.rs
src/machine/load_state.rs

index fbfaebeed5c1069d89d3f78ac96512e2c5aa8c1f..048631aeae10cc69173e4f9efe3e75b547041553 100644 (file)
@@ -1316,7 +1316,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                         .clause_clause_locs
                         .extend(&clause_clause_locs.make_contiguous()[0..]);
 
-                    let skeleton = cg.skeleton;
+                    let mut skeleton = cg.skeleton;
+                    skeleton.core.is_dynamic = settings.is_dynamic();
 
                     self.add_extensible_predicate(key, skeleton, predicates.compilation_target);
                 }
@@ -2138,7 +2139,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             .map(|skeleton| skeleton.predicate_info())
             .unwrap_or_default();
 
-        let mut predicate_info = self
+        let predicate_info = self
             .wam_prelude
             .indices
             .get_predicate_skeleton(&self.payload.predicates.compilation_target, &key)
@@ -2200,8 +2201,6 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                             (0..skeleton.clauses.len()).map(Some).collect(),
                             false, // the builtin M:'$clause'/2 is never dynamic.
                         );
-
-                        predicate_info.is_dynamic = false;
                     }
 
                     self.payload
index 3cdc10aadadb1071010cf0ac171092be53155711..079ee29eb55cb63c9be200068d8326ae0b8853bd 100644 (file)
@@ -466,13 +466,39 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             None => return,
         };
 
+        let mut skipped_local_predicates = IndexSet::with_hasher(FxBuildHasher::default());
+
+        for ((local_compilation_target, key), skeleton) in
+            removed_module.local_extensible_predicates.iter()
+        {
+            skipped_local_predicates.insert(key);
+
+            if skeleton.is_multifile {
+                continue;
+            }
+
+            if let Some(code_index) = removed_module.code_dir.get_mut(key) {
+                if let Some(global_skeleton) = self
+                    .wam_prelude
+                    .indices
+                    .get_predicate_skeleton(local_compilation_target, key)
+                {
+                    let old_index_ptr = code_index.replace(if global_skeleton.core.is_dynamic {
+                        IndexPtr::dynamic_undefined()
+                    } else {
+                        IndexPtr::undefined()
+                    });
+
+                    self.payload.retraction_info.push_record(
+                        RetractionRecord::ReplacedModulePredicate(module_name, *key, old_index_ptr),
+                    );
+                }
+            }
+        }
+
         for (key, code_index) in removed_module.code_dir.iter_mut() {
-            match removed_module
-                .local_extensible_predicates
-                .get(&(CompilationTarget::User, *key))
-            {
-                Some(skeleton) if skeleton.is_multifile => continue,
-                _ => {}
+            if skipped_local_predicates.contains(&key) {
+                continue;
             }
 
             let old_index_ptr = code_index.replace(IndexPtr::undefined());