]> Repositorios git - scryer-prolog.git/commitdiff
throw an error instead of allowing builtin modules to be overwritten (#2042)
authorMark <[email protected]>
Tue, 26 Sep 2023 01:20:11 +0000 (19:20 -0600)
committerMark <[email protected]>
Tue, 26 Sep 2023 01:21:34 +0000 (19:21 -0600)
src/machine/load_state.rs
src/machine/loader.rs
src/machine/machine_errors.rs

index fd857f3d89622bd499321a7308f4c998a9bb4fd1..308ddf4c3c86b789022fe6f71dd9412fc4349bd7 100644 (file)
@@ -9,7 +9,7 @@ use crate::parser::ast::*;
 
 use fxhash::FxBuildHasher;
 use indexmap::IndexSet;
-use ref_thread_local::RefThreadLocal;
+pub use ref_thread_local::RefThreadLocal;
 
 use std::collections::VecDeque;
 use std::fs::File;
@@ -1004,10 +1004,22 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         }
     }
 
-    pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
-        self.reset_in_situ_module(module_decl.clone(), &listing_src);
+    pub(crate) fn add_module(
+        &mut self,
+        module_decl: ModuleDecl,
+        listing_src: ListingSource,
+    ) -> Result<(), SessionError> {
         let module_name = module_decl.name;
 
+        if let Some(module) = self.wam_prelude.indices.modules.get(&module_name) {
+            if let ListingSource::DynamicallyGenerated = module.listing_src {
+            } else {
+                LS::err_on_builtin_module_overwrite(module_name)?;
+            }
+        }
+
+        self.reset_in_situ_module(module_decl.clone(), &listing_src);
+
         let mut module = match self.wam_prelude.indices.modules.remove(&module_name) {
             Some(mut module) => {
                 module.listing_src = listing_src;
@@ -1045,6 +1057,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         }
 
         self.wam_prelude.indices.modules.insert(module_name, module);
+
+        Ok(())
     }
 
     pub(super) fn import_module(&mut self, module_name: Atom) -> Result<(), SessionError> {
index 59db0208f4246a36a202bb7d0fa3bb1140548965..467bfb8056cd3892d012aa2f76f935d913eafb34 100644 (file)
@@ -265,6 +265,10 @@ pub trait LoadState<'a>: Sized {
         loader: &Loader<'a, Self>,
         key: PredicateKey,
     ) -> Result<(), SessionError>;
+
+    fn err_on_builtin_module_overwrite(_module_name: Atom) -> Result<(), SessionError> {
+        Ok(())
+    }
 }
 
 pub struct LiveLoadAndMachineState<'a> {
@@ -353,6 +357,15 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> {
 
         Ok(())
     }
+
+    #[inline]
+    fn err_on_builtin_module_overwrite(module_name: Atom) -> Result<(), SessionError> {
+        if LIBRARIES.borrow().contains_key(&*module_name.as_str()) {
+            Err(SessionError::CannotOverwriteBuiltInModule(module_name))
+        } else {
+            Ok(())
+        }
+    }
 }
 
 impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
@@ -533,11 +546,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                 self.add_meta_predicate_record(module_name, name, meta_specs);
             }
             Declaration::Module(module_decl) => {
-                self.payload.compilation_target = CompilationTarget::Module(module_decl.name);
+                let module_name = module_decl.name;
+
+                self.payload.compilation_target = CompilationTarget::Module(module_name);
                 self.payload.predicates.compilation_target = self.payload.compilation_target;
 
                 let listing_src = self.payload.term_stream.listing_src().clone();
-                self.add_module(module_decl, listing_src);
+                self.add_module(module_decl, listing_src)?;
             }
             Declaration::NonCountedBacktracking(name, arity) => {
                 self.payload.non_counted_bt_preds.insert((name, arity));
@@ -1849,9 +1864,7 @@ impl Machine {
             2,
         )?;
 
-        let path = cell_as_atom!(self
-            .machine_st
-            .store(self.machine_st.deref(self.machine_st.registers[2])));
+        let path = cell_as_atom!(self.deref_register(2));
 
         self.load_contexts
             .push(LoadContext::new(&*path.as_str(), stream));
index 5b4e4479e9a5c989f5a26b236da23cf69cd35c6d..b80620a962e85f004ef61cc27c7be95f73badc36 100644 (file)
@@ -161,6 +161,26 @@ pub(crate) trait PermissionError {
     ) -> MachineError;
 }
 
+impl PermissionError for Atom {
+    fn permission_error(
+        self,
+        _machine_st: &mut MachineState,
+        index_atom: Atom,
+        perm: Permission,
+    ) -> MachineError {
+        let stub = functor!(
+            atom!("permission_error"),
+            [atom(perm.as_atom()), atom(index_atom), cell(atom_as_cell!(self))]
+        );
+
+        MachineError {
+            stub,
+            location: None,
+            from: ErrorProvenance::Received,
+        }
+    }
+}
+
 impl PermissionError for HeapCellValue {
     fn permission_error(
         self,
@@ -459,7 +479,6 @@ impl MachineState {
     pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
         match err {
             SessionError::CannotOverwriteBuiltIn(key) => {
-                // SessionError::CannotOverwriteImport(pred_atom) => {
                 self.permission_error(
                     Permission::Modify,
                     atom!("static_procedure"),
@@ -468,10 +487,14 @@ impl MachineState {
                         .collect::<MachineStub>(),
                 )
             }
+            SessionError::CannotOverwriteBuiltInModule(module) => {
+                self.permission_error(
+                    Permission::Modify,
+                    atom!("static_module"),
+                    module,
+                )
+            }
             SessionError::ExistenceError(err) => self.existence_error(err),
-            // SessionError::InvalidFileName(filename) => {
-            //     Self::existence_error(h, ExistenceError::Module(filename))
-            // }
             SessionError::ModuleDoesNotContainExport(..) => {
                 let error_atom = atom!("module_does_not_contain_claimed_export");
 
@@ -977,6 +1000,7 @@ pub enum ExistenceError {
 pub enum SessionError {
     CompilationError(CompilationError),
     CannotOverwriteBuiltIn(PredicateKey),
+    CannotOverwriteBuiltInModule(Atom),
     ExistenceError(ExistenceError),
     ModuleDoesNotContainExport(Atom, PredicateKey),
     ModuleCannotImportSelf(Atom),