@@ -1018,29 +1018,48 @@ 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 ,
1028- ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
1029- let tcx = self . tcx . tcx ;
1030-
1030+ ) -> InterpResult < ' tcx , Pointer < M :: Provenance > > {
10311031 // Use cache for immutable strings.
1032- let ptr = if mutbl. is_not ( ) {
1032+ if mutbl. is_not ( ) {
10331033 // Use dedup'd allocation function.
10341034 let salt = M :: get_global_alloc_salt ( self , None ) ;
1035- let id = tcx. allocate_bytes_dedup ( str . as_bytes ( ) , salt) ;
1035+ let id = self . tcx . allocate_bytes_dedup ( bytes , salt) ;
10361036
10371037 // Turn untagged "global" pointers (obtained via `tcx`) into the machine pointer to the allocation.
1038- M :: adjust_alloc_root_pointer ( & self , Pointer :: from ( id) , Some ( kind) ) ?
1038+ M :: adjust_alloc_root_pointer ( & self , Pointer :: from ( id) , Some ( kind) )
10391039 } else {
1040- self . allocate_bytes_ptr ( str. as_bytes ( ) , Align :: ONE , kind, mutbl) ?
1041- } ;
1042- let meta = Scalar :: from_target_usize ( u64:: try_from ( str. len ( ) ) . unwrap ( ) , self ) ;
1040+ // Allocate new memory for mutable data.
1041+ self . allocate_bytes_ptr ( bytes, align, kind, mutbl)
1042+ }
1043+ }
1044+
1045+ /// Allocates a string in the interpreter's memory with metadata for length.
1046+ /// Uses `allocate_bytes` internally but adds string-specific metadata handling.
1047+ pub fn allocate_str (
1048+ & mut self ,
1049+ str : & str ,
1050+ kind : MemoryKind < M :: MemoryKind > ,
1051+ mutbl : Mutability ,
1052+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
1053+ let bytes = str. as_bytes ( ) ;
1054+ let ptr = self . allocate_bytes ( bytes, Align :: ONE , kind, mutbl) ?;
1055+
1056+ // Create length metadata for the string.
1057+ let meta = Scalar :: from_target_usize ( u64:: try_from ( bytes. len ( ) ) . unwrap ( ) , self ) ;
1058+
1059+ // Get layout for Rust's str type.
10431060 let layout = self . layout_of ( self . tcx . types . str_ ) . unwrap ( ) ;
1061+
1062+ // Combine pointer and metadata into a wide pointer.
10441063 interp_ok ( self . ptr_with_meta_to_mplace (
10451064 ptr. into ( ) ,
10461065 MemPlaceMeta :: Meta ( meta) ,
0 commit comments