@@ -1018,31 +1018,53 @@ where
1018
1018
self . allocate_dyn ( layout, kind, MemPlaceMeta :: None )
1019
1019
}
1020
1020
1021
- /// Returns a wide MPlace of type `str` to a new 1-aligned allocation.
1022
- /// Immutable strings are deduplicated and stored in global memory.
1023
- pub fn allocate_str (
1021
+ /// Allocates a sequence of bytes in the interpreter's memory.
1022
+ /// For immutable allocations, uses deduplication to reuse existing memory.
1023
+ /// For mutable allocations, creates a new unique allocation.
1024
+ pub fn allocate_bytes (
1024
1025
& mut self ,
1025
- str : & str ,
1026
+ bytes : & [ u8 ] ,
1027
+ align : Align ,
1026
1028
kind : MemoryKind < M :: MemoryKind > ,
1027
1029
mutbl : Mutability ,
1028
1030
) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
1029
- let tcx = self . tcx . tcx ;
1030
-
1031
- // Use cache for immutable strings.
1032
1031
let ptr = if mutbl. is_not ( ) {
1033
- // Use dedup'd allocation function.
1032
+ // Deduplicate immutable allocations using a salted hash
1034
1033
let salt = M :: get_global_alloc_salt ( self , None ) ;
1035
- let id = tcx. allocate_bytes_dedup ( str . as_bytes ( ) , salt) ;
1034
+ let id = self . tcx . allocate_bytes_dedup ( bytes , salt) ;
1036
1035
1037
- // Turn untagged "global" pointers (obtained via `tcx`) into the machine pointer to the allocation.
1036
+ // Transform allocation ID to a machine-specific pointer with proper provenance
1038
1037
M :: adjust_alloc_root_pointer ( & self , Pointer :: from ( id) , Some ( kind) ) ?
1039
1038
} else {
1040
- self . allocate_bytes_ptr ( str. as_bytes ( ) , Align :: ONE , kind, mutbl) ?
1039
+ // Allocate new memory for mutable data
1040
+ self . allocate_bytes_ptr ( bytes, align, kind, mutbl) ?
1041
1041
} ;
1042
- let meta = Scalar :: from_target_usize ( u64:: try_from ( str. len ( ) ) . unwrap ( ) , self ) ;
1042
+
1043
+ let layout = self . layout_of ( self . tcx . types . u8 ) . unwrap ( ) ;
1044
+
1045
+ interp_ok ( self . ptr_to_mplace ( ptr. into ( ) , layout) )
1046
+ }
1047
+
1048
+ /// Allocates a string in the interpreter's memory with metadata for length.
1049
+ /// Uses `allocate_bytes` internally but adds string-specific metadata handling.
1050
+ pub fn allocate_str (
1051
+ & mut self ,
1052
+ str : & str ,
1053
+ kind : MemoryKind < M :: MemoryKind > ,
1054
+ mutbl : Mutability ,
1055
+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
1056
+ let bytes = str. as_bytes ( ) ;
1057
+ let mplace_type = self . allocate_bytes ( bytes, Align :: ONE , kind, mutbl) ?;
1058
+
1059
+ // Create length metadata for the string
1060
+ let meta = Scalar :: from_target_usize ( u64:: try_from ( bytes. len ( ) ) . unwrap ( ) , self ) ;
1061
+
1062
+ // Get layout for Rust's str type
1043
1063
let layout = self . layout_of ( self . tcx . types . str_ ) . unwrap ( ) ;
1064
+
1065
+ // Combine pointer and metadata into a wide pointer
1044
1066
interp_ok ( self . ptr_with_meta_to_mplace (
1045
- ptr. into ( ) ,
1067
+ mplace_type . ptr ( ) . into ( ) ,
1046
1068
MemPlaceMeta :: Meta ( meta) ,
1047
1069
layout,
1048
1070
/*unaligned*/ false ,
0 commit comments