Skip to content

Commit 286fc5c

Browse files
committed
allow Machine to hook into foreign statics; remove unused HasMemory trait
1 parent 2592b20 commit 286fc5c

File tree

4 files changed

+72
-126
lines changed

4 files changed

+72
-126
lines changed

src/librustc_mir/interpret/const_eval.rs

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
use std::fmt;
1212
use std::error::Error;
1313

14-
use rustc::hir;
14+
use rustc::hir::{self, def_id::DefId};
1515
use rustc::mir::interpret::ConstEvalErr;
1616
use rustc::mir;
17-
use rustc::ty::{self, ParamEnv, TyCtxt, Instance, query::TyCtxtAt};
17+
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
1818
use rustc::ty::layout::{LayoutOf, TyLayout};
1919
use rustc::ty::subst::Subst;
2020
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -325,6 +325,13 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
325325
}
326326
}
327327

328+
fn find_foreign_static<'a>(
329+
_tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
330+
_def_id: DefId,
331+
) -> EvalResult<'tcx, &'tcx Allocation> {
332+
err!(ReadForeignStatic)
333+
}
334+
328335
fn box_alloc<'a>(
329336
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
330337
_dest: PlaceTy<'tcx>,
@@ -333,16 +340,6 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
333340
ConstEvalError::NeedsRfc("heap allocations via `box` keyword".to_string()).into(),
334341
)
335342
}
336-
337-
fn global_item_with_linkage<'a>(
338-
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
339-
_instance: ty::Instance<'tcx>,
340-
_mutability: Mutability,
341-
) -> EvalResult<'tcx> {
342-
Err(
343-
ConstEvalError::NotConst("statics with `linkage` attribute".to_string()).into(),
344-
)
345-
}
346343
}
347344

348345
/// Project to a field of a (variant of a) const
@@ -481,43 +478,3 @@ pub fn const_eval_provider<'a, 'tcx>(
481478
err.into()
482479
})
483480
}
484-
485-
486-
/// Helper function to obtain the global (tcx) allocation for a static
487-
pub fn static_alloc<'a, 'tcx>(
488-
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
489-
id: AllocId,
490-
) -> EvalResult<'tcx, &'tcx Allocation> {
491-
let alloc = tcx.alloc_map.lock().get(id);
492-
let def_id = match alloc {
493-
Some(AllocType::Memory(mem)) => {
494-
return Ok(mem)
495-
}
496-
Some(AllocType::Function(..)) => {
497-
return err!(DerefFunctionPointer)
498-
}
499-
Some(AllocType::Static(did)) => {
500-
did
501-
}
502-
None =>
503-
return err!(DanglingPointerDeref),
504-
};
505-
// We got a "lazy" static that has not been computed yet, do some work
506-
trace!("static_alloc: Need to compute {:?}", def_id);
507-
if tcx.is_foreign_item(def_id) {
508-
return err!(ReadForeignStatic);
509-
}
510-
let instance = Instance::mono(tcx.tcx, def_id);
511-
let gid = GlobalId {
512-
instance,
513-
promoted: None,
514-
};
515-
tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
516-
// no need to report anything, the const_eval call takes care of that for statics
517-
assert!(tcx.is_static(def_id).is_some());
518-
EvalErrorKind::ReferencedConstant(err).into()
519-
}).map(|val| {
520-
// FIXME We got our static (will be a ByRef), now we make a *copy*?!?
521-
tcx.const_to_allocation(val)
522-
})
523-
}

src/librustc_mir/interpret/machine.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
1515
use std::hash::Hash;
1616

17+
use rustc::hir::def_id::DefId;
1718
use rustc::mir::interpret::{AllocId, Allocation, EvalResult, Scalar};
18-
use super::{EvalContext, PlaceTy, OpTy, Memory};
19-
2019
use rustc::mir;
21-
use rustc::ty::{self, layout::TyLayout};
22-
use syntax::ast::Mutability;
20+
use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};
21+
22+
use super::{EvalContext, PlaceTy, OpTy, Memory};
2323

2424
/// Used by the machine to tell if a certain allocation is for static memory
2525
pub trait IsStatic {
@@ -62,6 +62,12 @@ pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
6262
dest: PlaceTy<'tcx>,
6363
) -> EvalResult<'tcx>;
6464

65+
/// Called for read access to a foreign static item.
66+
fn find_foreign_static<'a>(
67+
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
68+
def_id: DefId,
69+
) -> EvalResult<'tcx, &'tcx Allocation>;
70+
6571
/// Called for all binary operations except on float types.
6672
///
6773
/// Returns `None` if the operation should be handled by the integer
@@ -91,13 +97,6 @@ pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
9197
dest: PlaceTy<'tcx>,
9298
) -> EvalResult<'tcx>;
9399

94-
/// Called when trying to access a global declared with a `linkage` attribute
95-
fn global_item_with_linkage<'a>(
96-
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
97-
instance: ty::Instance<'tcx>,
98-
mutability: Mutability,
99-
) -> EvalResult<'tcx>;
100-
101100
/// Execute a validation operation
102101
fn validation_op<'a>(
103102
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,

src/librustc_mir/interpret/memory.rs

Lines changed: 52 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,16 @@ use std::collections::VecDeque;
2020
use std::hash::{Hash, Hasher};
2121
use std::ptr;
2222

23-
use rustc::ty::Instance;
24-
use rustc::ty::query::TyCtxtAt;
25-
use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
26-
use rustc::mir::interpret::{Pointer, AllocId, Allocation, ScalarMaybeUndef,
23+
use rustc::ty::{self, Instance, query::TyCtxtAt};
24+
use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout};
25+
use rustc::mir::interpret::{Pointer, AllocId, Allocation, ScalarMaybeUndef, GlobalId,
2726
EvalResult, Scalar, EvalErrorKind, AllocType, truncate};
2827
pub use rustc::mir::interpret::{write_target_uint, read_target_uint};
2928
use rustc_data_structures::fx::{FxHashSet, FxHashMap, FxHasher};
3029

3130
use syntax::ast::Mutability;
3231

33-
use super::{EvalContext, Machine, IsStatic, static_alloc};
34-
35-
////////////////////////////////////////////////////////////////////////////////
36-
// Allocations and pointers
37-
////////////////////////////////////////////////////////////////////////////////
32+
use super::{Machine, IsStatic};
3833

3934
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
4035
pub enum MemoryKind<T> {
@@ -53,10 +48,6 @@ impl<T: IsStatic> IsStatic for MemoryKind<T> {
5348
}
5449
}
5550

56-
////////////////////////////////////////////////////////////////////////////////
57-
// Top-level interpreter memory
58-
////////////////////////////////////////////////////////////////////////////////
59-
6051
#[derive(Clone)]
6152
pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
6253
/// Additional data required by the Machine
@@ -70,6 +61,13 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
7061
pub tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
7162
}
7263

64+
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for &'a Memory<'a, 'mir, 'tcx, M> {
65+
#[inline]
66+
fn data_layout(&self) -> &TargetDataLayout {
67+
&self.tcx.data_layout
68+
}
69+
}
70+
7371
impl<'a, 'mir, 'tcx, M> Eq for Memory<'a, 'mir, 'tcx, M>
7472
where M: Machine<'mir, 'tcx>,
7573
'tcx: 'a + 'mir,
@@ -122,6 +120,45 @@ impl<'a, 'mir, 'tcx, M> Hash for Memory<'a, 'mir, 'tcx, M>
122120
}
123121
}
124122

123+
/// Helper function to obtain the global (tcx) allocation for a static
124+
fn const_eval_static<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>>(
125+
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
126+
id: AllocId
127+
) -> EvalResult<'tcx, &'tcx Allocation> {
128+
let alloc = tcx.alloc_map.lock().get(id);
129+
let def_id = match alloc {
130+
Some(AllocType::Memory(mem)) => {
131+
return Ok(mem)
132+
}
133+
Some(AllocType::Function(..)) => {
134+
return err!(DerefFunctionPointer)
135+
}
136+
Some(AllocType::Static(did)) => {
137+
did
138+
}
139+
None =>
140+
return err!(DanglingPointerDeref),
141+
};
142+
// We got a "lazy" static that has not been computed yet, do some work
143+
trace!("static_alloc: Need to compute {:?}", def_id);
144+
if tcx.is_foreign_item(def_id) {
145+
return M::find_foreign_static(tcx, def_id);
146+
}
147+
let instance = Instance::mono(tcx.tcx, def_id);
148+
let gid = GlobalId {
149+
instance,
150+
promoted: None,
151+
};
152+
tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
153+
// no need to report anything, the const_eval call takes care of that for statics
154+
assert!(tcx.is_static(def_id).is_some());
155+
EvalErrorKind::ReferencedConstant(err).into()
156+
}).map(|val| {
157+
// FIXME We got our static (will be a ByRef), now we make a *copy*?!?
158+
tcx.const_to_allocation(val)
159+
})
160+
}
161+
125162
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
126163
pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
127164
Memory {
@@ -322,7 +359,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
322359
Some(alloc) => Ok(&alloc.1),
323360
// No need to make any copies, just provide read access to the global static
324361
// memory in tcx.
325-
None => static_alloc(self.tcx, id),
362+
None => const_eval_static::<M>(self.tcx, id),
326363
}
327364
}
328365

@@ -588,7 +625,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
588625
id: AllocId,
589626
kind: MemoryKind<M::MemoryKinds>,
590627
) -> EvalResult<'tcx> {
591-
let alloc = static_alloc(self.tcx, id)?;
628+
let alloc = const_eval_static::<M>(self.tcx, id)?;
592629
if alloc.mutability == Mutability::Immutable {
593630
return err!(ModifiedConstantMemory);
594631
}
@@ -980,49 +1017,3 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
9801017
Ok(())
9811018
}
9821019
}
983-
984-
////////////////////////////////////////////////////////////////////////////////
985-
// Unaligned accesses
986-
////////////////////////////////////////////////////////////////////////////////
987-
988-
pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
989-
fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M>;
990-
fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M>;
991-
}
992-
993-
impl<'a, 'mir, 'tcx, M> HasMemory<'a, 'mir, 'tcx, M> for Memory<'a, 'mir, 'tcx, M>
994-
where M: Machine<'mir, 'tcx>
995-
{
996-
#[inline]
997-
fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M> {
998-
self
999-
}
1000-
1001-
#[inline]
1002-
fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
1003-
self
1004-
}
1005-
}
1006-
1007-
impl<'a, 'mir, 'tcx, M> HasMemory<'a, 'mir, 'tcx, M> for EvalContext<'a, 'mir, 'tcx, M>
1008-
where M: Machine<'mir, 'tcx>
1009-
{
1010-
#[inline]
1011-
fn memory_mut(&mut self) -> &mut Memory<'a, 'mir, 'tcx, M> {
1012-
&mut self.memory
1013-
}
1014-
1015-
#[inline]
1016-
fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
1017-
&self.memory
1018-
}
1019-
}
1020-
1021-
impl<'a, 'mir, 'tcx, M> layout::HasDataLayout for &'a Memory<'a, 'mir, 'tcx, M>
1022-
where M: Machine<'mir, 'tcx>
1023-
{
1024-
#[inline]
1025-
fn data_layout(&self) -> &TargetDataLayout {
1026-
&self.tcx.data_layout
1027-
}
1028-
}

src/librustc_mir/interpret/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use self::eval_context::{
3030

3131
pub use self::place::{Place, PlaceExtra, PlaceTy, MemPlace, MPlaceTy};
3232

33-
pub use self::memory::{Memory, MemoryKind, HasMemory};
33+
pub use self::memory::{Memory, MemoryKind};
3434

3535
pub use self::const_eval::{
3636
eval_promoted,
@@ -42,7 +42,6 @@ pub use self::const_eval::{
4242
const_field,
4343
const_variant_index,
4444
op_to_const,
45-
static_alloc,
4645
};
4746

4847
pub use self::machine::{Machine, IsStatic};

0 commit comments

Comments
 (0)