Skip to content

Commit a6096fb

Browse files
authored
Merge pull request rust-lang#292 from oli-obk/static_alloc_ids
Prepare for splitting off static alloc ids from local alloc ids
2 parents 14e8f50 + 91db25b commit a6096fb

File tree

20 files changed

+413
-417
lines changed

20 files changed

+413
-417
lines changed

miri/fn_call.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ use super::{
1616

1717
use tls::MemoryExt;
1818

19-
use super::memory::Kind;
19+
use super::memory::MemoryKind;
2020

2121
pub trait EvalContextExt<'tcx> {
2222
fn call_c_abi(
2323
&mut self,
2424
def_id: DefId,
2525
arg_operands: &[mir::Operand<'tcx>],
26-
dest: Lvalue<'tcx>,
26+
dest: Lvalue,
2727
dest_ty: Ty<'tcx>,
2828
dest_block: mir::BasicBlock,
2929
) -> EvalResult<'tcx>;
@@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx> {
3333
fn call_missing_fn(
3434
&mut self,
3535
instance: ty::Instance<'tcx>,
36-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
36+
destination: Option<(Lvalue, mir::BasicBlock)>,
3737
arg_operands: &[mir::Operand<'tcx>],
3838
sig: ty::FnSig<'tcx>,
3939
path: String,
@@ -42,7 +42,7 @@ pub trait EvalContextExt<'tcx> {
4242
fn eval_fn_call(
4343
&mut self,
4444
instance: ty::Instance<'tcx>,
45-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
45+
destination: Option<(Lvalue, mir::BasicBlock)>,
4646
arg_operands: &[mir::Operand<'tcx>],
4747
span: Span,
4848
sig: ty::FnSig<'tcx>,
@@ -53,7 +53,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
5353
fn eval_fn_call(
5454
&mut self,
5555
instance: ty::Instance<'tcx>,
56-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
56+
destination: Option<(Lvalue, mir::BasicBlock)>,
5757
arg_operands: &[mir::Operand<'tcx>],
5858
span: Span,
5959
sig: ty::FnSig<'tcx>,
@@ -89,7 +89,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
8989
&mut self,
9090
def_id: DefId,
9191
arg_operands: &[mir::Operand<'tcx>],
92-
dest: Lvalue<'tcx>,
92+
dest: Lvalue,
9393
dest_ty: Ty<'tcx>,
9494
dest_block: mir::BasicBlock,
9595
) -> EvalResult<'tcx> {
@@ -113,15 +113,15 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
113113
self.write_null(dest, dest_ty)?;
114114
} else {
115115
let align = self.memory.pointer_size();
116-
let ptr = self.memory.allocate(size, align, Kind::C.into())?;
116+
let ptr = self.memory.allocate(size, align, MemoryKind::C.into())?;
117117
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
118118
}
119119
}
120120

121121
"free" => {
122122
let ptr = args[0].into_ptr(&mut self.memory)?;
123123
if !ptr.is_null()? {
124-
self.memory.deallocate(ptr.to_ptr()?, None, Kind::C.into())?;
124+
self.memory.deallocate(ptr.to_ptr()?, None, MemoryKind::C.into())?;
125125
}
126126
}
127127

@@ -251,7 +251,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
251251
}
252252
if let Some(old) = success {
253253
if let Some(var) = old {
254-
self.memory.deallocate(var, None, Kind::Env.into())?;
254+
self.memory.deallocate(var, None, MemoryKind::Env.into())?;
255255
}
256256
self.write_null(dest, dest_ty)?;
257257
} else {
@@ -274,12 +274,12 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
274274
}
275275
if let Some((name, value)) = new {
276276
// +1 for the null terminator
277-
let value_copy = self.memory.allocate((value.len() + 1) as u64, 1, Kind::Env.into())?;
277+
let value_copy = self.memory.allocate((value.len() + 1) as u64, 1, MemoryKind::Env.into())?;
278278
self.memory.write_bytes(value_copy.into(), &value)?;
279279
let trailing_zero_ptr = value_copy.offset(value.len() as u64, &self)?.into();
280280
self.memory.write_bytes(trailing_zero_ptr, &[0])?;
281281
if let Some(var) = self.machine_data.env_vars.insert(name.to_owned(), value_copy) {
282-
self.memory.deallocate(var, None, Kind::Env.into())?;
282+
self.memory.deallocate(var, None, MemoryKind::Env.into())?;
283283
}
284284
self.write_null(dest, dest_ty)?;
285285
} else {
@@ -317,7 +317,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
317317
}
318318

319319
"sysconf" => {
320-
let name = self.value_to_primval(args[0], usize)?.to_u64()?;
320+
let c_int = self.operand_ty(&arg_operands[0]);
321+
let name = self.value_to_primval(args[0], c_int)?.to_u64()?;
321322
trace!("sysconf() called with name {}", name);
322323
// cache the sysconf integers via miri's global cache
323324
let paths = &[
@@ -329,8 +330,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
329330
if let Ok(instance) = self.resolve_path(path) {
330331
let cid = GlobalId { instance, promoted: None };
331332
// compute global if not cached
332-
let val = match self.globals.get(&cid).map(|glob| glob.value) {
333-
Some(value) => self.value_to_primval(value, usize)?.to_u64()?,
333+
let val = match self.globals.get(&cid).cloned() {
334+
Some(ptr) => self.value_to_primval(Value::ByRef(ptr), c_int)?.to_u64()?,
334335
None => eval_body_as_primval(self.tcx, instance)?.0.to_u64()?,
335336
};
336337
if val == name {
@@ -459,7 +460,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
459460
fn call_missing_fn(
460461
&mut self,
461462
instance: ty::Instance<'tcx>,
462-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
463+
destination: Option<(Lvalue, mir::BasicBlock)>,
463464
arg_operands: &[mir::Operand<'tcx>],
464465
sig: ty::FnSig<'tcx>,
465466
path: String,
@@ -500,7 +501,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
500501
if !align.is_power_of_two() {
501502
return err!(HeapAllocNonPowerOfTwoAlignment(align));
502503
}
503-
let ptr = self.memory.allocate(size, align, Kind::Rust.into())?;
504+
let ptr = self.memory.allocate(size, align, MemoryKind::Rust.into())?;
504505
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
505506
}
506507
"alloc::heap::::__rust_alloc_zeroed" => {
@@ -512,7 +513,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
512513
if !align.is_power_of_two() {
513514
return err!(HeapAllocNonPowerOfTwoAlignment(align));
514515
}
515-
let ptr = self.memory.allocate(size, align, Kind::Rust.into())?;
516+
let ptr = self.memory.allocate(size, align, MemoryKind::Rust.into())?;
516517
self.memory.write_repeat(ptr.into(), 0, size)?;
517518
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
518519
}
@@ -526,7 +527,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
526527
if !align.is_power_of_two() {
527528
return err!(HeapAllocNonPowerOfTwoAlignment(align));
528529
}
529-
self.memory.deallocate(ptr, Some((old_size, align)), Kind::Rust.into())?;
530+
self.memory.deallocate(ptr, Some((old_size, align)), MemoryKind::Rust.into())?;
530531
}
531532
"alloc::heap::::__rust_realloc" => {
532533
let ptr = args[0].into_ptr(&mut self.memory)?.to_ptr()?;
@@ -543,7 +544,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
543544
if !new_align.is_power_of_two() {
544545
return err!(HeapAllocNonPowerOfTwoAlignment(new_align));
545546
}
546-
let new_ptr = self.memory.reallocate(ptr, old_size, old_align, new_size, new_align, Kind::Rust.into())?;
547+
let new_ptr = self.memory.reallocate(ptr, old_size, old_align, new_size, new_align, MemoryKind::Rust.into())?;
547548
self.write_primval(dest, PrimVal::Ptr(new_ptr), dest_ty)?;
548549
}
549550

miri/intrinsic.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_miri::interpret::{
88
Lvalue, LvalueExtra,
99
PrimVal, PrimValKind, Value, Pointer,
1010
HasMemory,
11-
EvalContext,
11+
EvalContext, PtrAndAlign,
1212
};
1313

1414
use helpers::EvalContextExt as HelperEvalContextExt;
@@ -18,7 +18,7 @@ pub trait EvalContextExt<'tcx> {
1818
&mut self,
1919
instance: ty::Instance<'tcx>,
2020
args: &[mir::Operand<'tcx>],
21-
dest: Lvalue<'tcx>,
21+
dest: Lvalue,
2222
dest_ty: Ty<'tcx>,
2323
dest_layout: &'tcx Layout,
2424
target: mir::BasicBlock,
@@ -30,7 +30,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
3030
&mut self,
3131
instance: ty::Instance<'tcx>,
3232
args: &[mir::Operand<'tcx>],
33-
dest: Lvalue<'tcx>,
33+
dest: Lvalue,
3434
dest_ty: Ty<'tcx>,
3535
dest_layout: &'tcx Layout,
3636
target: mir::BasicBlock,
@@ -266,10 +266,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
266266
let size = self.type_size(dest_ty)?.expect("cannot zero unsized value");
267267
let init = |this: &mut Self, val: Value| {
268268
let zero_val = match val {
269-
Value::ByRef { ptr, aligned } => {
269+
Value::ByRef(PtrAndAlign { ptr, .. }) => {
270270
// These writes have no alignment restriction anyway.
271271
this.memory.write_repeat(ptr, 0, size)?;
272-
Value::ByRef { ptr, aligned }
272+
val
273273
},
274274
// TODO(solson): Revisit this, it's fishy to check for Undef here.
275275
Value::ByVal(PrimVal::Undef) => match this.ty_to_primval_kind(dest_ty) {
@@ -289,9 +289,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
289289
};
290290
match dest {
291291
Lvalue::Local { frame, local } => self.modify_local(frame, local, init)?,
292-
Lvalue::Ptr { ptr, extra: LvalueExtra::None, aligned: true } => self.memory.write_repeat(ptr, 0, size)?,
292+
Lvalue::Ptr { ptr: PtrAndAlign { ptr, aligned: true }, extra: LvalueExtra::None } => self.memory.write_repeat(ptr, 0, size)?,
293293
Lvalue::Ptr { .. } => bug!("init intrinsic tried to write to fat or unaligned ptr target"),
294-
Lvalue::Global(cid) => self.modify_global(cid, init)?,
295294
}
296295
}
297296

@@ -457,19 +456,18 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
457456
let size = dest_layout.size(&self.tcx.data_layout).bytes();
458457
let uninit = |this: &mut Self, val: Value| {
459458
match val {
460-
Value::ByRef { ptr, aligned } => {
459+
Value::ByRef(PtrAndAlign { ptr, .. }) => {
461460
this.memory.mark_definedness(ptr, size, false)?;
462-
Ok(Value::ByRef { ptr, aligned })
461+
Ok(val)
463462
},
464463
_ => Ok(Value::ByVal(PrimVal::Undef)),
465464
}
466465
};
467466
match dest {
468467
Lvalue::Local { frame, local } => self.modify_local(frame, local, uninit)?,
469-
Lvalue::Ptr { ptr, extra: LvalueExtra::None, aligned: true } =>
468+
Lvalue::Ptr { ptr: PtrAndAlign { ptr, aligned: true }, extra: LvalueExtra::None } =>
470469
self.memory.mark_definedness(ptr, size, false)?,
471470
Lvalue::Ptr { .. } => bug!("uninit intrinsic tried to write to fat or unaligned ptr target"),
472-
Lvalue::Global(cid) => self.modify_global(cid, uninit)?,
473471
}
474472
}
475473

miri/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
7171
// Return value
7272
let size = ecx.tcx.data_layout.pointer_size.bytes();
7373
let align = ecx.tcx.data_layout.pointer_align.abi();
74-
let ret_ptr = ecx.memory_mut().allocate(size, align, Kind::Stack)?;
74+
let ret_ptr = ecx.memory_mut().allocate(size, align, MemoryKind::Stack)?;
7575
cleanup_ptr = Some(ret_ptr);
7676

7777
// Push our stack frame
@@ -114,7 +114,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
114114
while ecx.step()? {}
115115
ecx.run_tls_dtors()?;
116116
if let Some(cleanup_ptr) = cleanup_ptr {
117-
ecx.memory_mut().deallocate(cleanup_ptr, None, Kind::Stack)?;
117+
ecx.memory_mut().deallocate(cleanup_ptr, None, MemoryKind::Stack)?;
118118
}
119119
Ok(())
120120
}
@@ -161,13 +161,13 @@ struct MemoryData<'tcx> {
161161
impl<'tcx> Machine<'tcx> for Evaluator {
162162
type Data = EvaluatorData;
163163
type MemoryData = MemoryData<'tcx>;
164-
type MemoryKinds = memory::Kind;
164+
type MemoryKinds = memory::MemoryKind;
165165

166166
/// Returns Ok() when the function was handled, fail otherwise
167167
fn eval_fn_call<'a>(
168168
ecx: &mut EvalContext<'a, 'tcx, Self>,
169169
instance: ty::Instance<'tcx>,
170-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
170+
destination: Option<(Lvalue, mir::BasicBlock)>,
171171
arg_operands: &[mir::Operand<'tcx>],
172172
span: Span,
173173
sig: ty::FnSig<'tcx>,
@@ -179,7 +179,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
179179
ecx: &mut rustc_miri::interpret::EvalContext<'a, 'tcx, Self>,
180180
instance: ty::Instance<'tcx>,
181181
args: &[mir::Operand<'tcx>],
182-
dest: Lvalue<'tcx>,
182+
dest: Lvalue,
183183
dest_ty: ty::Ty<'tcx>,
184184
dest_layout: &'tcx Layout,
185185
target: mir::BasicBlock,
@@ -198,8 +198,8 @@ impl<'tcx> Machine<'tcx> for Evaluator {
198198
ecx.ptr_op(bin_op, left, left_ty, right, right_ty)
199199
}
200200

201-
fn mark_static_initialized(m: memory::Kind) -> EvalResult<'tcx> {
202-
use memory::Kind::*;
201+
fn mark_static_initialized(m: memory::MemoryKind) -> EvalResult<'tcx> {
202+
use memory::MemoryKind::*;
203203
match m {
204204
// FIXME: This could be allowed, but not for env vars set during miri execution
205205
Env => err!(Unimplemented("statics can't refer to env vars".to_owned())),
@@ -218,7 +218,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
218218
Ok(PrimVal::Bytes(align.into()))
219219
} else {
220220
ecx.memory
221-
.allocate(size, align, Kind::Machine(memory::Kind::Rust))
221+
.allocate(size, align, MemoryKind::Machine(memory::MemoryKind::Rust))
222222
.map(PrimVal::Ptr)
223223
}
224224
}

miri/memory.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
#[derive(Debug, PartialEq, Copy, Clone)]
3-
pub enum Kind {
3+
pub enum MemoryKind {
44
/// Error if deallocated any other way than `rust_deallocate`
55
Rust,
66
/// Error if deallocated any other way than `free`
@@ -9,8 +9,8 @@ pub enum Kind {
99
Env,
1010
}
1111

12-
impl Into<::rustc_miri::interpret::Kind<Kind>> for Kind {
13-
fn into(self) -> ::rustc_miri::interpret::Kind<Kind> {
14-
::rustc_miri::interpret::Kind::Machine(self)
12+
impl Into<::rustc_miri::interpret::MemoryKind<MemoryKind>> for MemoryKind {
13+
fn into(self) -> ::rustc_miri::interpret::MemoryKind<MemoryKind> {
14+
::rustc_miri::interpret::MemoryKind::Machine(self)
1515
}
1616
}

src/librustc_mir/interpret/const_eval.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ use syntax::codemap::Span;
77

88
use super::{
99
EvalResult, EvalError, EvalErrorKind,
10-
Global, GlobalId, Lvalue,
10+
GlobalId, Lvalue, Value,
1111
PrimVal,
12-
EvalContext, StackPopCleanup,
12+
EvalContext, StackPopCleanup, PtrAndAlign,
13+
MemoryKind,
1314
};
1415

1516
use rustc_const_math::ConstInt;
@@ -30,7 +31,11 @@ pub fn eval_body_as_primval<'a, 'tcx>(
3031

3132
let mir = ecx.load_mir(instance.def)?;
3233
if !ecx.globals.contains_key(&cid) {
33-
ecx.globals.insert(cid, Global::uninitialized(mir.return_ty));
34+
let size = ecx.type_size_with_substs(mir.return_ty, instance.substs)?.expect("unsized global");
35+
let align = ecx.type_align_with_substs(mir.return_ty, instance.substs)?;
36+
let ptr = ecx.memory.allocate(size, align, MemoryKind::UninitializedStatic)?;
37+
let aligned = !ecx.is_packed(mir.return_ty)?;
38+
ecx.globals.insert(cid, PtrAndAlign { ptr: ptr.into(), aligned });
3439
let mutable = !mir.return_ty.is_freeze(
3540
ecx.tcx,
3641
ty::ParamEnv::empty(Reveal::All),
@@ -42,18 +47,18 @@ pub fn eval_body_as_primval<'a, 'tcx>(
4247
};
4348
let cleanup = StackPopCleanup::MarkStatic(mutability);
4449
let name = ty::tls::with(|tcx| tcx.item_path_str(instance.def_id()));
45-
trace!("pushing stack frame for global: {}", name);
50+
trace!("const_eval: pushing stack frame for global: {}", name);
4651
ecx.push_stack_frame(
4752
instance,
4853
mir.span,
4954
mir,
50-
Lvalue::Global(cid),
55+
Lvalue::from_ptr(ptr),
5156
cleanup,
5257
)?;
5358

5459
while ecx.step()? {}
5560
}
56-
let value = ecx.globals.get(&cid).expect("global not cached").value;
61+
let value = Value::ByRef(*ecx.globals.get(&cid).expect("global not cached"));
5762
Ok((ecx.value_to_primval(value, mir.return_ty)?, mir.return_ty))
5863
}
5964

@@ -132,7 +137,7 @@ impl<'tcx> super::Machine<'tcx> for CompileTimeFunctionEvaluator {
132137
fn eval_fn_call<'a>(
133138
ecx: &mut EvalContext<'a, 'tcx, Self>,
134139
instance: ty::Instance<'tcx>,
135-
destination: Option<(Lvalue<'tcx>, mir::BasicBlock)>,
140+
destination: Option<(Lvalue, mir::BasicBlock)>,
136141
_arg_operands: &[mir::Operand<'tcx>],
137142
span: Span,
138143
_sig: ty::FnSig<'tcx>,
@@ -168,7 +173,7 @@ impl<'tcx> super::Machine<'tcx> for CompileTimeFunctionEvaluator {
168173
_ecx: &mut EvalContext<'a, 'tcx, Self>,
169174
_instance: ty::Instance<'tcx>,
170175
_args: &[mir::Operand<'tcx>],
171-
_dest: Lvalue<'tcx>,
176+
_dest: Lvalue,
172177
_dest_ty: Ty<'tcx>,
173178
_dest_layout: &'tcx layout::Layout,
174179
_target: mir::BasicBlock,

src/librustc_mir/interpret/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<'tcx> Error for EvalError<'tcx> {
139139
DoubleFree =>
140140
"tried to deallocate dangling pointer",
141141
InvalidFunctionPointer =>
142-
"tried to use an integer pointer or a dangling pointer as a function pointer",
142+
"tried to use a function pointer after offsetting it",
143143
InvalidBool =>
144144
"invalid boolean value read",
145145
InvalidDiscriminant =>

0 commit comments

Comments
 (0)