throw error instead of overwriting builtin export (#1225)

This commit is contained in:
Mark Thom
2022-01-18 19:16:14 -07:00
parent 59992c8af2
commit 5a132aaff4
6 changed files with 98 additions and 685 deletions

View File

@@ -1295,7 +1295,7 @@ fn mergeable_indexed_subsequences(
fn print_overwrite_warning(
compilation_target: &CompilationTarget,
code_ptr: IndexPtr,
key: &PredicateKey,
key: PredicateKey,
is_dynamic: bool,
) {
if let CompilationTarget::Module(module_name) = compilation_target {
@@ -1372,6 +1372,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
) -> Result<CodeIndex, SessionError> {
let code_index = self.get_or_insert_code_index(key, predicates.compilation_target);
LS::err_on_builtin_overwrite(self, key)?;
let code_len = self.wam_prelude.code.len();
let mut code_ptr = code_len;
@@ -1463,7 +1465,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
print_overwrite_warning(
&predicates.compilation_target,
code_index.get(),
&key,
key,
settings.is_dynamic(),
);

View File

@@ -18,6 +18,7 @@ use slice_deque::{sdeq, SliceDeque};
use std::cell::Cell;
use std::convert::TryFrom;
use std::fmt;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
@@ -156,6 +157,15 @@ pub enum CompilationTarget {
User,
}
impl fmt::Display for CompilationTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CompilationTarget::User => write!(f, "user"),
CompilationTarget::Module(ref module_name) => write!(f, "{}", module_name.as_str()),
}
}
}
impl Default for CompilationTarget {
#[inline]
fn default() -> Self {
@@ -252,6 +262,10 @@ pub trait LoadState<'a>: Sized {
fn should_drop_load_state(loader: &Loader<'a, Self>) -> bool;
fn reset_machine(loader: &mut Loader<'a, Self>);
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState;
fn err_on_builtin_overwrite(
loader: &Loader<'a, Self>,
key: PredicateKey,
) -> Result<(), SessionError>;
}
pub struct LiveLoadAndMachineState<'a> {
@@ -309,6 +323,20 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> {
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState {
loader.machine_st
}
#[inline(always)]
fn err_on_builtin_overwrite(
loader: &Loader<'a, Self>,
key: PredicateKey,
) -> Result<(), SessionError> {
if let Some(builtins) = loader.wam_prelude.indices.modules.get(&atom!("builtins")) {
if builtins.module_decl.exports.contains(&ModuleExport::PredicateKey(key)) {
return Err(SessionError::CannotOverwriteBuiltIn(key));
}
}
Ok(())
}
}
impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
@@ -352,6 +380,14 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState {
&mut loader.term_stream.parser.lexer.machine_st
}
#[inline(always)]
fn err_on_builtin_overwrite(
_loader: &Loader<'a, Self>,
_key: PredicateKey,
) -> Result<(), SessionError> {
Ok(())
}
}
pub struct Loader<'a, LS: LoadState<'a>> {

View File

@@ -401,18 +401,14 @@ impl MachineState {
pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
match err {
// SessionError::CannotOverwriteBuiltIn(pred_str) |
/*
SessionError::CannotOverwriteImport(pred_str) => {
Self::permission_error(
atom_tbl,
h,
SessionError::CannotOverwriteBuiltIn(key) => {
// SessionError::CannotOverwriteImport(pred_atom) => {
self.permission_error(
Permission::Modify,
atom!("private_procedure"),
functor!(atom(pred_str)),
functor_stub(key.0, key.1).into_iter().collect::<MachineStub>(),
)
}
*/
SessionError::ExistenceError(err) => self.existence_error(err),
// SessionError::InvalidFileName(filename) => {
// Self::existence_error(h, ExistenceError::Module(filename))
@@ -903,7 +899,7 @@ pub enum ExistenceError {
#[derive(Debug)]
pub enum SessionError {
CompilationError(CompilationError),
// CannotOverwriteBuiltIn(Atom),
CannotOverwriteBuiltIn(PredicateKey),
// CannotOverwriteImport(Atom),
ExistenceError(ExistenceError),
// InvalidFileName(Atom),