about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-08-23 21:22:27 +0200
committerRalf Jung <post@ralfj.de>2018-08-27 18:12:49 +0200
commit286fc5caa24520a85907bd2c28414ec387a7e7ca (patch)
treee351a600b68604c7fed66331f49dace32431b863
parent2592b20347ad49b99dd1eda58260e73ac553ed83 (diff)
downloadrust-286fc5caa24520a85907bd2c28414ec387a7e7ca.tar.gz
rust-286fc5caa24520a85907bd2c28414ec387a7e7ca.zip
allow Machine to hook into foreign statics; remove unused HasMemory trait
-rw-r--r--src/librustc_mir/interpret/const_eval.rs61
-rw-r--r--src/librustc_mir/interpret/machine.rs21
-rw-r--r--src/librustc_mir/interpret/memory.rs113
-rw-r--r--src/librustc_mir/interpret/mod.rs3
4 files changed, 72 insertions, 126 deletions
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index dbdaf0aab34..9840fb2cfd7 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -11,10 +11,10 @@
 use std::fmt;
 use std::error::Error;
 
-use rustc::hir;
+use rustc::hir::{self, def_id::DefId};
 use rustc::mir::interpret::ConstEvalErr;
 use rustc::mir;
-use rustc::ty::{self, ParamEnv, TyCtxt, Instance, query::TyCtxtAt};
+use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
 use rustc::ty::layout::{LayoutOf, TyLayout};
 use rustc::ty::subst::Subst;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -325,6 +325,13 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
         }
     }
 
+    fn find_foreign_static<'a>(
+        _tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
+        _def_id: DefId,
+    ) -> EvalResult<'tcx, &'tcx Allocation> {
+        err!(ReadForeignStatic)
+    }
+
     fn box_alloc<'a>(
         _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
         _dest: PlaceTy<'tcx>,
@@ -333,16 +340,6 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
             ConstEvalError::NeedsRfc("heap allocations via `box` keyword".to_string()).into(),
         )
     }
-
-    fn global_item_with_linkage<'a>(
-        _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
-        _instance: ty::Instance<'tcx>,
-        _mutability: Mutability,
-    ) -> EvalResult<'tcx> {
-        Err(
-            ConstEvalError::NotConst("statics with `linkage` attribute".to_string()).into(),
-        )
-    }
 }
 
 /// Project to a field of a (variant of a) const
@@ -481,43 +478,3 @@ pub fn const_eval_provider<'a, 'tcx>(
         err.into()
     })
 }
-
-
-/// Helper function to obtain the global (tcx) allocation for a static
-pub fn static_alloc<'a, 'tcx>(
-    tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
-    id: AllocId,
-) -> EvalResult<'tcx, &'tcx Allocation> {
-    let alloc = tcx.alloc_map.lock().get(id);
-    let def_id = match alloc {
-        Some(AllocType::Memory(mem)) => {
-            return Ok(mem)
-        }
-        Some(AllocType::Function(..)) => {
-            return err!(DerefFunctionPointer)
-        }
-        Some(AllocType::Static(did)) => {
-            did
-        }
-        None =>
-            return err!(DanglingPointerDeref),
-    };
-    // We got a "lazy" static that has not been computed yet, do some work
-    trace!("static_alloc: Need to compute {:?}", def_id);
-    if tcx.is_foreign_item(def_id) {
-        return err!(ReadForeignStatic);
-    }
-    let instance = Instance::mono(tcx.tcx, def_id);
-    let gid = GlobalId {
-        instance,
-        promoted: None,
-    };
-    tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
-        // no need to report anything, the const_eval call takes care of that for statics
-        assert!(tcx.is_static(def_id).is_some());
-        EvalErrorKind::ReferencedConstant(err).into()
-    }).map(|val| {
-        // FIXME We got our static (will be a ByRef), now we make a *copy*?!?
-        tcx.const_to_allocation(val)
-    })
-}
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 714b2f9e025..b3e7370b66b 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -14,12 +14,12 @@
 
 use std::hash::Hash;
 
+use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::{AllocId, Allocation, EvalResult, Scalar};
-use super::{EvalContext, PlaceTy, OpTy, Memory};
-
 use rustc::mir;
-use rustc::ty::{self, layout::TyLayout};
-use syntax::ast::Mutability;
+use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};
+
+use super::{EvalContext, PlaceTy, OpTy, Memory};
 
 /// Used by the machine to tell if a certain allocation is for static memory
 pub trait IsStatic {
@@ -62,6 +62,12 @@ pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
         dest: PlaceTy<'tcx>,
     ) -> EvalResult<'tcx>;
 
+    /// Called for read access to a foreign static item.
+    fn find_foreign_static<'a>(
+        tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
+        def_id: DefId,
+    ) -> EvalResult<'tcx, &'tcx Allocation>;
+
     /// Called for all binary operations except on float types.
     ///
     /// Returns `None` if the operation should be handled by the integer
@@ -91,13 +97,6 @@ pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
         dest: PlaceTy<'tcx>,
     ) -> EvalResult<'tcx>;
 
-    /// Called when trying to access a global declared with a `linkage` attribute
-    fn global_item_with_linkage<'a>(
-        ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
-        instance: ty::Instance<'tcx>,
-        mutability: Mutability,
-    ) -> EvalResult<'tcx>;
-
     /// Execute a validation operation
     fn validation_op<'a>(
         _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 41d48738567..e570468a467 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -20,21 +20,16 @@ use std::collections::VecDeque;
 use std::hash::{Hash, Hasher};
 use std::ptr;
 
-use rustc::ty::Instance;
-use rustc::ty::query::TyCtxtAt;
-use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
-use rustc::mir::interpret::{Pointer, AllocId, Allocation, ScalarMaybeUndef,
+use rustc::ty::{self, Instance, query::TyCtxtAt};
+use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout};
+use rustc::mir::interpret::{Pointer, AllocId, Allocation, ScalarMaybeUndef, GlobalId,
                             EvalResult, Scalar, EvalErrorKind, AllocType, truncate};
 pub use rustc::mir::interpret::{write_target_uint, read_target_uint};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap, FxHasher};
 
 use syntax::ast::Mutability;
 
-use super::{EvalContext, Machine, IsStatic, static_alloc};
-
-////////////////////////////////////////////////////////////////////////////////
-// Allocations and pointers
-////////////////////////////////////////////////////////////////////////////////
+use super::{Machine, IsStatic};
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
 pub enum MemoryKind<T> {
@@ -53,10 +48,6 @@ impl<T: IsStatic> IsStatic for MemoryKind<T> {
     }
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// Top-level interpreter memory
-////////////////////////////////////////////////////////////////////////////////
-
 #[derive(Clone)]
 pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// Additional data required by the Machine
@@ -70,6 +61,13 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     pub tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
 }
 
+impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for &'a Memory<'a, 'mir, 'tcx, M> {
+    #[inline]
+    fn data_layout(&self) -> &TargetDataLayout {
+        &self.tcx.data_layout
+    }
+}
+
 impl<'a, 'mir, 'tcx, M> Eq for Memory<'a, 'mir, 'tcx, M>
     where M: Machine<'mir, 'tcx>,
           'tcx: 'a + 'mir,
@@ -122,6 +120,45 @@ impl<'a, 'mir, 'tcx, M> Hash for Memory<'a, 'mir, 'tcx, M>
     }
 }
 
+/// Helper function to obtain the global (tcx) allocation for a static
+fn const_eval_static<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>>(
+    tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
+    id: AllocId
+) -> EvalResult<'tcx, &'tcx Allocation> {
+    let alloc = tcx.alloc_map.lock().get(id);
+    let def_id = match alloc {
+        Some(AllocType::Memory(mem)) => {
+            return Ok(mem)
+        }
+        Some(AllocType::Function(..)) => {
+            return err!(DerefFunctionPointer)
+        }
+        Some(AllocType::Static(did)) => {
+            did
+        }
+        None =>
+            return err!(DanglingPointerDeref),
+    };
+    // We got a "lazy" static that has not been computed yet, do some work
+    trace!("static_alloc: Need to compute {:?}", def_id);
+    if tcx.is_foreign_item(def_id) {
+        return M::find_foreign_static(tcx, def_id);
+    }
+    let instance = Instance::mono(tcx.tcx, def_id);
+    let gid = GlobalId {
+        instance,
+        promoted: None,
+    };
+    tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
+        // no need to report anything, the const_eval call takes care of that for statics
+        assert!(tcx.is_static(def_id).is_some());
+        EvalErrorKind::ReferencedConstant(err).into()
+    }).map(|val| {
+        // FIXME We got our static (will be a ByRef), now we make a *copy*?!?
+        tcx.const_to_allocation(val)
+    })
+}
+
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
     pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
         Memory {
@@ -322,7 +359,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
             Some(alloc) => Ok(&alloc.1),
             // No need to make any copies, just provide read access to the global static
             // memory in tcx.
-            None => static_alloc(self.tcx, id),
+            None => const_eval_static::<M>(self.tcx, id),
         }
     }
 
@@ -588,7 +625,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         id: AllocId,
         kind: MemoryKind<M::MemoryKinds>,
     ) -> EvalResult<'tcx> {
-        let alloc = static_alloc(self.tcx, id)?;
+        let alloc = const_eval_static::<M>(self.tcx, id)?;
         if alloc.mutability == Mutability::Immutable {
             return err!(ModifiedConstantMemory);
         }
@@ -980,49 +1017,3 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         Ok(())
     }
 }
-
-////////////////////////////////////////////////////////////////////////////////
-// Unaligned accesses
-////////////////////////////////////////////////////////////////////////////////
-
-pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
-    fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M>;
-    fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M>;
-}
-
-impl<'a, 'mir, 'tcx, M> HasMemory<'a, 'mir, 'tcx, M> for Memory<'a, 'mir, 'tcx, M>
-    where M: Machine<'mir, 'tcx>
-{
-    #[inline]
-    fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M> {
-        self
-    }
-
-    #[inline]
-    fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
-        self
-    }
-}
-
-impl<'a, 'mir, 'tcx, M> HasMemory<'a, 'mir, 'tcx, M> for EvalContext<'a, 'mir, 'tcx, M>
-    where M: Machine<'mir, 'tcx>
-{
-    #[inline]
-    fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M> {
-        &mut self.memory
-    }
-
-    #[inline]
-    fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
-        &self.memory
-    }
-}
-
-impl<'a, 'mir, 'tcx, M> layout::HasDataLayout for &'a Memory<'a, 'mir, 'tcx, M>
-    where M: Machine<'mir, 'tcx>
-{
-    #[inline]
-    fn data_layout(&self) -> &TargetDataLayout {
-        &self.tcx.data_layout
-    }
-}
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index 129c098099a..8559686fa41 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -30,7 +30,7 @@ pub use self::eval_context::{
 
 pub use self::place::{Place, PlaceExtra, PlaceTy, MemPlace, MPlaceTy};
 
-pub use self::memory::{Memory, MemoryKind, HasMemory};
+pub use self::memory::{Memory, MemoryKind};
 
 pub use self::const_eval::{
     eval_promoted,
@@ -42,7 +42,6 @@ pub use self::const_eval::{
     const_field,
     const_variant_index,
     op_to_const,
-    static_alloc,
 };
 
 pub use self::machine::{Machine, IsStatic};