@@ -17,27 +17,29 @@ macro_rules! err {
17
17
18
18
mod error;
19
19
mod value;
20
+ mod allocation;
20
21
21
22
pub use self :: error:: {
22
23
EvalError , EvalResult , EvalErrorKind , AssertMessage , ConstEvalErr , struct_error,
23
24
FrameInfo , ConstEvalResult ,
24
25
} ;
25
26
26
- pub use self :: value:: { Scalar , ConstValue } ;
27
+ pub use self :: value:: { Scalar , ConstValue , ScalarMaybeUndef } ;
28
+
29
+ pub use self :: allocation:: {
30
+ Allocation , MemoryAccess , AllocationExtra ,
31
+ Relocations , UndefMask ,
32
+ } ;
27
33
28
34
use std:: fmt;
29
35
use mir;
30
36
use hir:: def_id:: DefId ;
31
37
use ty:: { self , TyCtxt , Instance } ;
32
- use ty:: layout:: { self , Align , HasDataLayout , Size } ;
38
+ use ty:: layout:: { self , HasDataLayout , Size } ;
33
39
use middle:: region;
34
- use std:: iter;
35
40
use std:: io;
36
- use std:: ops:: { Deref , DerefMut } ;
37
41
use std:: hash:: Hash ;
38
- use syntax:: ast:: Mutability ;
39
42
use rustc_serialize:: { Encoder , Decodable , Encodable } ;
40
- use rustc_data_structures:: sorted_map:: SortedMap ;
41
43
use rustc_data_structures:: fx:: FxHashMap ;
42
44
use rustc_data_structures:: sync:: { Lock as Mutex , HashMapExt } ;
43
45
use rustc_data_structures:: tiny_list:: TinyList ;
@@ -523,91 +525,6 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
523
525
}
524
526
}
525
527
526
- #[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
527
- pub struct Allocation < Tag =( ) , Extra =( ) > {
528
- /// The actual bytes of the allocation.
529
- /// Note that the bytes of a pointer represent the offset of the pointer
530
- pub bytes : Vec < u8 > ,
531
- /// Maps from byte addresses to extra data for each pointer.
532
- /// Only the first byte of a pointer is inserted into the map; i.e.,
533
- /// every entry in this map applies to `pointer_size` consecutive bytes starting
534
- /// at the given offset.
535
- pub relocations : Relocations < Tag > ,
536
- /// Denotes undefined memory. Reading from undefined memory is forbidden in miri
537
- pub undef_mask : UndefMask ,
538
- /// The alignment of the allocation to detect unaligned reads.
539
- pub align : Align ,
540
- /// Whether the allocation is mutable.
541
- /// Also used by codegen to determine if a static should be put into mutable memory,
542
- /// which happens for `static mut` and `static` with interior mutability.
543
- pub mutability : Mutability ,
544
- /// Extra state for the machine.
545
- pub extra : Extra ,
546
- }
547
-
548
- impl < Tag , Extra : Default > Allocation < Tag , Extra > {
549
- /// Creates a read-only allocation initialized by the given bytes
550
- pub fn from_bytes ( slice : & [ u8 ] , align : Align ) -> Self {
551
- let mut undef_mask = UndefMask :: new ( Size :: ZERO ) ;
552
- undef_mask. grow ( Size :: from_bytes ( slice. len ( ) as u64 ) , true ) ;
553
- Self {
554
- bytes : slice. to_owned ( ) ,
555
- relocations : Relocations :: new ( ) ,
556
- undef_mask,
557
- align,
558
- mutability : Mutability :: Immutable ,
559
- extra : Extra :: default ( ) ,
560
- }
561
- }
562
-
563
- pub fn from_byte_aligned_bytes ( slice : & [ u8 ] ) -> Self {
564
- Allocation :: from_bytes ( slice, Align :: from_bytes ( 1 , 1 ) . unwrap ( ) )
565
- }
566
-
567
- pub fn undef ( size : Size , align : Align ) -> Self {
568
- assert_eq ! ( size. bytes( ) as usize as u64 , size. bytes( ) ) ;
569
- Allocation {
570
- bytes : vec ! [ 0 ; size. bytes( ) as usize ] ,
571
- relocations : Relocations :: new ( ) ,
572
- undef_mask : UndefMask :: new ( size) ,
573
- align,
574
- mutability : Mutability :: Mutable ,
575
- extra : Extra :: default ( ) ,
576
- }
577
- }
578
- }
579
-
580
- impl < ' tcx > :: serialize:: UseSpecializedDecodable for & ' tcx Allocation { }
581
-
582
- #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug , RustcEncodable , RustcDecodable ) ]
583
- pub struct Relocations < Tag =( ) , Id =AllocId > ( SortedMap < Size , ( Tag , Id ) > ) ;
584
-
585
- impl < Tag , Id > Relocations < Tag , Id > {
586
- pub fn new ( ) -> Self {
587
- Relocations ( SortedMap :: new ( ) )
588
- }
589
-
590
- // The caller must guarantee that the given relocations are already sorted
591
- // by address and contain no duplicates.
592
- pub fn from_presorted ( r : Vec < ( Size , ( Tag , Id ) ) > ) -> Self {
593
- Relocations ( SortedMap :: from_presorted_elements ( r) )
594
- }
595
- }
596
-
597
- impl < Tag > Deref for Relocations < Tag > {
598
- type Target = SortedMap < Size , ( Tag , AllocId ) > ;
599
-
600
- fn deref ( & self ) -> & Self :: Target {
601
- & self . 0
602
- }
603
- }
604
-
605
- impl < Tag > DerefMut for Relocations < Tag > {
606
- fn deref_mut ( & mut self ) -> & mut Self :: Target {
607
- & mut self . 0
608
- }
609
- }
610
-
611
528
////////////////////////////////////////////////////////////////////////////////
612
529
// Methods to access integers in the target endianness
613
530
////////////////////////////////////////////////////////////////////////////////
@@ -650,103 +567,3 @@ pub fn truncate(value: u128, size: Size) -> u128 {
650
567
// truncate (shift left to drop out leftover values, shift right to fill with zeroes)
651
568
( value << shift) >> shift
652
569
}
653
-
654
- ////////////////////////////////////////////////////////////////////////////////
655
- // Undefined byte tracking
656
- ////////////////////////////////////////////////////////////////////////////////
657
-
658
- type Block = u64 ;
659
- const BLOCK_SIZE : u64 = 64 ;
660
-
661
- #[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
662
- pub struct UndefMask {
663
- blocks : Vec < Block > ,
664
- len : Size ,
665
- }
666
-
667
- impl_stable_hash_for ! ( struct mir:: interpret:: UndefMask { blocks, len} ) ;
668
-
669
- impl UndefMask {
670
- pub fn new ( size : Size ) -> Self {
671
- let mut m = UndefMask {
672
- blocks : vec ! [ ] ,
673
- len : Size :: ZERO ,
674
- } ;
675
- m. grow ( size, false ) ;
676
- m
677
- }
678
-
679
- /// Check whether the range `start..end` (end-exclusive) is entirely defined.
680
- ///
681
- /// Returns `Ok(())` if it's defined. Otherwise returns the index of the byte
682
- /// at which the first undefined access begins.
683
- #[ inline]
684
- pub fn is_range_defined ( & self , start : Size , end : Size ) -> Result < ( ) , Size > {
685
- if end > self . len {
686
- return Err ( self . len ) ;
687
- }
688
-
689
- let idx = ( start. bytes ( ) ..end. bytes ( ) )
690
- . map ( |i| Size :: from_bytes ( i) )
691
- . find ( |& i| !self . get ( i) ) ;
692
-
693
- match idx {
694
- Some ( idx) => Err ( idx) ,
695
- None => Ok ( ( ) )
696
- }
697
- }
698
-
699
- pub fn set_range ( & mut self , start : Size , end : Size , new_state : bool ) {
700
- let len = self . len ;
701
- if end > len {
702
- self . grow ( end - len, new_state) ;
703
- }
704
- self . set_range_inbounds ( start, end, new_state) ;
705
- }
706
-
707
- pub fn set_range_inbounds ( & mut self , start : Size , end : Size , new_state : bool ) {
708
- for i in start. bytes ( ) ..end. bytes ( ) {
709
- self . set ( Size :: from_bytes ( i) , new_state) ;
710
- }
711
- }
712
-
713
- #[ inline]
714
- pub fn get ( & self , i : Size ) -> bool {
715
- let ( block, bit) = bit_index ( i) ;
716
- ( self . blocks [ block] & 1 << bit) != 0
717
- }
718
-
719
- #[ inline]
720
- pub fn set ( & mut self , i : Size , new_state : bool ) {
721
- let ( block, bit) = bit_index ( i) ;
722
- if new_state {
723
- self . blocks [ block] |= 1 << bit;
724
- } else {
725
- self . blocks [ block] &= !( 1 << bit) ;
726
- }
727
- }
728
-
729
- pub fn grow ( & mut self , amount : Size , new_state : bool ) {
730
- let unused_trailing_bits = self . blocks . len ( ) as u64 * BLOCK_SIZE - self . len . bytes ( ) ;
731
- if amount. bytes ( ) > unused_trailing_bits {
732
- let additional_blocks = amount. bytes ( ) / BLOCK_SIZE + 1 ;
733
- assert_eq ! ( additional_blocks as usize as u64 , additional_blocks) ;
734
- self . blocks . extend (
735
- iter:: repeat ( 0 ) . take ( additional_blocks as usize ) ,
736
- ) ;
737
- }
738
- let start = self . len ;
739
- self . len += amount;
740
- self . set_range_inbounds ( start, start + amount, new_state) ;
741
- }
742
- }
743
-
744
- #[ inline]
745
- fn bit_index ( bits : Size ) -> ( usize , usize ) {
746
- let bits = bits. bytes ( ) ;
747
- let a = bits / BLOCK_SIZE ;
748
- let b = bits % BLOCK_SIZE ;
749
- assert_eq ! ( a as usize as u64 , a) ;
750
- assert_eq ! ( b as usize as u64 , b) ;
751
- ( a as usize , b as usize )
752
- }
0 commit comments