2
2
//! All high-level functions to read from memory work on operands as sources.
3
3
4
4
use std:: assert_matches:: assert_matches;
5
+ use std:: collections:: hash_map:: Entry ;
5
6
6
7
use either:: { Either , Left , Right } ;
7
8
@@ -13,9 +14,9 @@ use rustc_middle::{mir, ty};
13
14
use rustc_target:: abi:: { self , Abi , HasDataLayout , Size } ;
14
15
15
16
use 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 ,
19
20
} ;
20
21
21
22
/// 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> {
757
758
}
758
759
mir:: ConstValue :: Scalar ( x) => adjust_scalar ( x) ?. into ( ) ,
759
760
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) => {
761
775
// We rely on mutability being set correctly in `data` to prevent writes
762
776
// where none should happen.
763
777
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
765
781
}
766
782
} ;
767
- Ok ( OpTy { op : Operand :: Immediate ( imm) , layout } )
783
+ Ok ( imm)
768
784
}
769
785
}
770
786
0 commit comments