From: Mark Date: Tue, 26 Sep 2023 01:20:11 +0000 (-0600) Subject: throw an error instead of allowing builtin modules to be overwritten (#2042) X-Git-Tag: remove~85 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=280ff8b5d08ae398c946fc123af11315c00a1e77;p=scryer-prolog.git throw an error instead of allowing builtin modules to be overwritten (#2042) --- diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index fd857f3d..308ddf4c 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -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> { diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 59db0208..467bfb80 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -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)); diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 5b4e4479..b80620a9 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -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::(), ) } + 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),