@@ -1018,31 +1018,53 @@ where
10181018 self . allocate_dyn ( layout, kind, MemPlaceMeta :: None )
10191019 }
10201020
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 (
10241025 & mut self ,
1025- str : & str ,
1026+ bytes : & [ u8 ] ,
1027+ align : Align ,
10261028 kind : MemoryKind < M :: MemoryKind > ,
10271029 mutbl : Mutability ,
10281030 ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
1029- let tcx = self . tcx . tcx ;
1030-
1031- // Use cache for immutable strings.
10321031 let ptr = if mutbl. is_not ( ) {
1033- // Use dedup'd allocation function.
1032+ // Deduplicate immutable allocations using a salted hash
10341033 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) ;
10361035
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
10381037 M :: adjust_alloc_root_pointer ( & self , Pointer :: from ( id) , Some ( kind) ) ?
10391038 } 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) ?
10411041 } ;
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
10431063 let layout = self . layout_of ( self . tcx . types . str_ ) . unwrap ( ) ;
1064+
1065+ // Combine pointer and metadata into a wide pointer
10441066 interp_ok ( self . ptr_with_meta_to_mplace (
1045- ptr. into ( ) ,
1067+ mplace_type . ptr ( ) . into ( ) ,
10461068 MemPlaceMeta :: Meta ( meta) ,
10471069 layout,
10481070 /*unaligned*/ false ,
0 commit comments