22//! All high-level functions to read from memory work on operands as sources.
33
44use std:: assert_matches:: assert_matches;
5+ use std:: collections:: hash_map:: Entry ;
56
67use either:: { Either , Left , Right } ;
78
@@ -13,9 +14,9 @@ use rustc_middle::{mir, ty};
1314use rustc_target:: abi:: { self , Abi , HasDataLayout , Size } ;
1415
1516use super :: {
16- alloc_range, from_known_layout, mir_assign_valid_types, AllocId , Frame , InterpCx , InterpResult ,
17- MPlaceTy , Machine , MemPlace , MemPlaceMeta , OffsetMode , PlaceTy , Pointer , Projectable ,
18- Provenance , Scalar ,
17+ alloc_range, from_known_layout, mir_assign_valid_types, AllocId , ConstAllocation , Frame ,
18+ InterpCx , InterpResult , MPlaceTy , Machine , MemPlace , MemPlaceMeta , OffsetMode , PlaceTy ,
19+ Pointer , Projectable , Provenance , Scalar ,
1920} ;
2021
2122/// An `Immediate` represents a single immediate self-contained Rust value.
@@ -757,14 +758,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
757758 }
758759 mir:: ConstValue :: Scalar ( x) => adjust_scalar ( x) ?. into ( ) ,
759760 mir:: ConstValue :: ZeroSized => Immediate :: Uninit ,
760- mir:: ConstValue :: Slice { data, meta } => {
761+ mir:: ConstValue :: Slice { data, meta } => self . const_slice_to_op ( data, meta) ?,
762+ } ;
763+ Ok ( OpTy { op : Operand :: Immediate ( imm) , layout } )
764+ }
765+
766+ fn const_slice_to_op (
767+ & self ,
768+ data : ConstAllocation < ' tcx > ,
769+ meta : u64 ,
770+ ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
771+ let span = self . cur_span ( ) ;
772+ let imm = match self . const_cache . lock ( ) . entry ( ( data, meta, span) ) {
773+ Entry :: Occupied ( e) => e. get ( ) . clone ( ) ,
774+ Entry :: Vacant ( e) => {
761775 // We rely on mutability being set correctly in `data` to prevent writes
762776 // where none should happen.
763777 let ptr = Pointer :: new ( self . tcx . reserve_and_set_memory_alloc ( data) , Size :: ZERO ) ;
764- Immediate :: new_slice ( self . global_base_pointer ( ptr) ?. into ( ) , meta, self )
778+ let imm = Immediate :: new_slice ( self . global_base_pointer ( ptr) ?. into ( ) , meta, self ) ;
779+ e. insert ( imm. clone ( ) ) ;
780+ imm
765781 }
766782 } ;
767- Ok ( OpTy { op : Operand :: Immediate ( imm) , layout } )
783+ Ok ( imm)
768784 }
769785}
770786
0 commit comments