From ea51e320432e547c9240f7658aa57da3ef62c811 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Oct 2018 14:17:01 +0200 Subject: [PATCH 1/8] Make OpTy field op public for priroda --- src/librustc_mir/interpret/operand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 2d6b19ca4a7fc..83b5831f3ad67 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -291,7 +291,7 @@ impl Operand { #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct OpTy<'tcx, Tag=()> { - crate op: Operand, // ideally we'd make this private, but const_prop needs this + pub op: Operand, // This is used by [priroda](https://github.com/oli-obk/priroda) pub layout: TyLayout<'tcx>, } From 3e62ba1af6df5bd14fe210b9f20977e97bbae370 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 19 Oct 2018 14:12:42 +0200 Subject: [PATCH 2/8] Add method to get OpTy for local from arbitrary frame --- src/librustc_mir/interpret/operand.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 83b5831f3ad67..8d2190d22c0dc 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -291,7 +291,7 @@ impl Operand { #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct OpTy<'tcx, Tag=()> { - pub op: Operand, // This is used by [priroda](https://github.com/oli-obk/priroda) + crate op: Operand, // ideally we'd make this private, but const_prop needs this pub layout: TyLayout<'tcx>, } @@ -772,4 +772,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> }) } + /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local + pub fn read_local_of_frame( + &self, + frame: &super::Frame, + local: mir::Local + ) -> EvalResult<'tcx, OpTy<'tcx>> { + let op = frame.locals[local].access()?; + let layout = self.layout_of_local(frame, local)?; + OpTy { op, layout } + } } From 7d406c9146d5a33abcc5e2a105d8856c8c7057d5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 19 Oct 2018 14:23:20 +0200 Subject: [PATCH 3/8] Fix errors --- src/librustc_mir/interpret/operand.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 8d2190d22c0dc..f928997dde798 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -775,11 +775,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local pub fn read_local_of_frame( &self, - frame: &super::Frame, + frame: &super::Frame<'mir, 'tcx>, local: mir::Local ) -> EvalResult<'tcx, OpTy<'tcx>> { - let op = frame.locals[local].access()?; - let layout = self.layout_of_local(frame, local)?; - OpTy { op, layout } + let op = *frame.locals[local].access()?; + let local_ty = frame.mir.local_decls[local].ty; + let local_ty = self.monomorphize(local_ty, frame.instance.substs); + let layout = self.layout_of(local_ty)?; + Ok(OpTy { op, layout }) } } From 37428927493a5e9309b3a3b35a715d7c96201c70 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Oct 2018 11:02:39 +0200 Subject: [PATCH 4/8] Use `read_local_of_frame` in `eval_place_to_op` Also make `layout_of_local` accept any `Frame` --- src/librustc_mir/interpret/eval_context.rs | 12 +++----- src/librustc_mir/interpret/operand.rs | 32 ++++++++++------------ src/librustc_mir/interpret/place.rs | 6 ++-- src/librustc_mir/interpret/terminator.rs | 4 +-- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 92cc09f4867b9..189388921650c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -324,14 +324,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc pub fn layout_of_local( &self, - frame: usize, + frame: &Frame<'mir, 'tcx, M::PointerTag>, local: mir::Local ) -> EvalResult<'tcx, TyLayout<'tcx>> { - let local_ty = self.stack[frame].mir.local_decls[local].ty; - let local_ty = self.monomorphize( - local_ty, - self.stack[frame].instance.substs - ); + let local_ty = frame.mir.local_decls[local].ty; + let local_ty = self.monomorphize(local_ty, frame.instance.substs); self.layout_of(local_ty) } @@ -579,7 +576,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); - let layout = self.layout_of_local(self.cur_frame(), local)?; + let layout = self.layout_of_local(self.frame(), local)?; let init = LocalValue::Live(self.uninit_operand(layout)?); // StorageLive *always* kills the value that's currently stored Ok(mem::replace(&mut self.frame_mut().locals[local], init)) @@ -733,4 +730,3 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc truncate(value, ty.size) } } - diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index f928997dde798..132e3812ed7aa 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -571,6 +571,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> }) } + /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local + pub fn read_local_of_frame( + &self, + frame: &super::Frame<'mir, 'tcx, M::PointerTag>, + local: mir::Local, + layout: Option>, + ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { + let op = *frame.locals[local].access()?; + let layout = from_known_layout(layout, + || self.layout_of_local(frame, local))?; + Ok(OpTy { op, layout }) + } + // Evaluate a place with the goal of reading from it. This lets us sometimes // avoid allocations. If you already know the layout, you can pass it in // to avoid looking it up again. @@ -582,12 +595,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> use rustc::mir::Place::*; let op = match *mir_place { Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), - Local(local) => { - let op = *self.frame().locals[local].access()?; - let layout = from_known_layout(layout, - || self.layout_of_local(self.cur_frame(), local))?; - OpTy { op, layout } - }, + Local(local) => self.read_local_of_frame(self.frame(), local, layout)?, Projection(ref proj) => { let op = self.eval_place_to_op(&proj.base, None)?; @@ -772,16 +780,4 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> }) } - /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local - pub fn read_local_of_frame( - &self, - frame: &super::Frame<'mir, 'tcx>, - local: mir::Local - ) -> EvalResult<'tcx, OpTy<'tcx>> { - let op = *frame.locals[local].access()?; - let local_ty = frame.mir.local_decls[local].ty; - let local_ty = self.monomorphize(local_ty, frame.instance.substs); - let layout = self.layout_of(local_ty)?; - Ok(OpTy { op, layout }) - } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index af3d694862839..a4bb15662d8b2 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -588,7 +588,7 @@ where // their layout on return. PlaceTy { place: *return_place, - layout: self.layout_of_local(self.cur_frame(), mir::RETURN_PLACE)?, + layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE)?, }, None => return err!(InvalidNullPointerUsage), }, @@ -597,7 +597,7 @@ where frame: self.cur_frame(), local, }, - layout: self.layout_of_local(self.cur_frame(), local)?, + layout: self.layout_of_local(self.frame(), local)?, }, Projection(ref proj) => { @@ -856,7 +856,7 @@ where // We need the layout of the local. We can NOT use the layout we got, // that might e.g. be an inner field of a struct with `Scalar` layout, // that has different alignment than the outer field. - let local_layout = self.layout_of_local(frame, local)?; + let local_layout = self.layout_of_local(&self.stack[frame], local)?; let ptr = self.allocate(local_layout, MemoryKind::Stack)?; // We don't have to validate as we can assume the local // was already valid for its type. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index c759727f546c8..faeeb24c6c267 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -310,7 +310,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> mir.spread_arg, mir.args_iter() .map(|local| - (local, self.layout_of_local(self.cur_frame(), local).unwrap().ty) + (local, self.layout_of_local(self.frame(), local).unwrap().ty) ) .collect::>() ); @@ -380,7 +380,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } } else { let callee_layout = - self.layout_of_local(self.cur_frame(), mir::RETURN_PLACE)?; + self.layout_of_local(self.frame(), mir::RETURN_PLACE)?; if !callee_layout.abi.is_uninhabited() { return err!(FunctionRetMismatch( self.tcx.types.never, callee_layout.ty From 825b55e76333e5d0d71ef0a0f603f25901bc45ed Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Oct 2018 11:09:44 +0200 Subject: [PATCH 5/8] Add alloc_map accessor --- src/librustc_mir/interpret/memory.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 9febcceae068e..9fd4068a22f7e 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -603,6 +603,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { self.dump_allocs(leaks); n } + + /// This is used by [priroda](https://github.com/oli-obk/priroda) + pub fn alloc_map_ref(&self) -> &M::MemoryMap { + &self.alloc_map + } } /// Byte accessors From f46e3ba308ffae06a6fdc7f6e2ecd1108519f021 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Oct 2018 13:42:25 +0200 Subject: [PATCH 6/8] Rename alloc_map_ref to alloc_map --- src/librustc_mir/interpret/memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 9fd4068a22f7e..9adca6c429798 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -605,7 +605,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } /// This is used by [priroda](https://github.com/oli-obk/priroda) - pub fn alloc_map_ref(&self) -> &M::MemoryMap { + pub fn alloc_map(&self) -> &M::MemoryMap { &self.alloc_map } } From c32cf25689d7b8f2498a875716f855ee5cdcf16c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 20 Oct 2018 14:39:23 +0200 Subject: [PATCH 7/8] Rename read_local_of_frame to access_local --- src/librustc_mir/interpret/operand.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 132e3812ed7aa..744856c805c4c 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -572,7 +572,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local - pub fn read_local_of_frame( + pub fn access_local( &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag>, local: mir::Local, @@ -595,7 +595,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> use rustc::mir::Place::*; let op = match *mir_place { Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), - Local(local) => self.read_local_of_frame(self.frame(), local, layout)?, + Local(local) => self.access_local(self.frame(), local, layout)?, Projection(ref proj) => { let op = self.eval_place_to_op(&proj.base, None)?; From b178553e555bd3634005878bcd90e2f8295289f6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 21 Oct 2018 16:16:23 +0200 Subject: [PATCH 8/8] Address review comments --- src/librustc_mir/interpret/operand.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 744856c805c4c..71b2f4b53a60c 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -572,12 +572,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } /// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local + /// + /// When you know the layout of the local in advance, you can pass it as last argument pub fn access_local( &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag>, local: mir::Local, layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { + assert_ne!(local, mir::RETURN_PLACE); let op = *frame.locals[local].access()?; let layout = from_known_layout(layout, || self.layout_of_local(frame, local))?;