From 1a0a4acd418c6e29fa3f3dce01523ded433d41c0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 11 Aug 2020 11:35:50 +0200 Subject: [PATCH] Add a function to `TyCtxt` for computing an `Allocation` for a `static` item's initializer --- src/librustc_middle/mir/interpret/queries.rs | 23 ++++++++++++++++++++ src/librustc_mir/interpret/memory.rs | 20 ++++------------- src/librustc_mir/interpret/mod.rs | 2 +- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/librustc_middle/mir/interpret/queries.rs b/src/librustc_middle/mir/interpret/queries.rs index 442e7f6b0f45e..dcc1f8b1a4b3c 100644 --- a/src/librustc_middle/mir/interpret/queries.rs +++ b/src/librustc_middle/mir/interpret/queries.rs @@ -74,4 +74,27 @@ impl<'tcx> TyCtxt<'tcx> { self.const_eval_validated(inputs) } } + + /// Evaluate a static's initializer, returning the allocation of the initializer's memory. + pub fn eval_static_initializer( + self, + def_id: DefId, + ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + trace!("eval_static_initializer: Need to compute {:?}", def_id); + assert!(self.is_static(def_id)); + let instance = ty::Instance::mono(self, def_id); + let gid = GlobalId { instance, promoted: None }; + self.eval_to_allocation(gid, ty::ParamEnv::reveal_all()) + } + + /// Evaluate anything constant-like, returning the allocation of the final memory. + fn eval_to_allocation( + self, + gid: GlobalId<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + trace!("eval_to_allocation: Need to compute {:?}", gid); + let raw_const = self.const_eval_raw(param_env.and(gid))?; + Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) + } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 7dfa913fd08bd..6c9e013eb18ba 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -14,13 +14,12 @@ use std::ptr; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, Instance, ParamEnv, TyCtxt}; +use rustc_middle::ty::{Instance, ParamEnv, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId, - InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, + AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, InterpResult, + Machine, MayLeak, Pointer, PointerArithmetic, Scalar, }; use crate::util::pretty; @@ -119,17 +118,6 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub tcx: TyCtxt<'tcx>, } -/// Return the `tcx` allocation containing the initial value of the given static -pub fn get_static(tcx: TyCtxt<'tcx>, def_id: DefId) -> InterpResult<'tcx, &'tcx Allocation> { - trace!("get_static: Need to compute {:?}", def_id); - let instance = Instance::mono(tcx, def_id); - let gid = GlobalId { instance, promoted: None }; - // Use the raw query here to break validation cycles. Later uses of the static - // will call the full query anyway. - let raw_const = tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid))?; - Ok(tcx.global_alloc(raw_const.alloc_id).unwrap_memory()) -} - impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &TargetDataLayout { @@ -489,7 +477,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { throw_unsup!(ReadExternStatic(def_id)); } - (get_static(tcx, def_id)?, Some(def_id)) + (tcx.eval_static_initializer(def_id)?, Some(def_id)) } }; M::before_access_global(memory_extra, id, alloc, def_id, is_write)?; diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 5218b03d65ecc..a931b0bbe9777 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -21,7 +21,7 @@ pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in pub use self::eval_context::{Frame, FrameInfo, InterpCx, LocalState, LocalValue, StackPopCleanup}; pub use self::intern::{intern_const_alloc_recursive, InternKind}; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; -pub use self::memory::{get_static, AllocCheck, FnVal, Memory, MemoryKind}; +pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Operand}; pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; pub use self::validity::RefTracking;