Skip to content

Commit 05f6482

Browse files
committed
mir-interpret: add method Memory::read wide_string
1 parent b0d5813 commit 05f6482

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/librustc/mir/interpret/value.rs

+10
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,11 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
590590
self.not_undef()?.to_u8()
591591
}
592592

593+
#[inline(always)]
594+
pub fn to_u16(self) -> InterpResult<'tcx, u16> {
595+
self.not_undef()?.to_u16()
596+
}
597+
593598
#[inline(always)]
594599
pub fn to_u32(self) -> InterpResult<'tcx, u32> {
595600
self.not_undef()?.to_u32()
@@ -610,6 +615,11 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
610615
self.not_undef()?.to_i8()
611616
}
612617

618+
#[inline(always)]
619+
pub fn to_i16(self) -> InterpResult<'tcx, i16> {
620+
self.not_undef()?.to_i16()
621+
}
622+
613623
#[inline(always)]
614624
pub fn to_i32(self) -> InterpResult<'tcx, i32> {
615625
self.not_undef()?.to_i32()

src/librustc_mir/interpret/memory.rs

+27
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
791791
self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr)
792792
}
793793

794+
/// Reads a 0x0000-terminated u16-sequence from memory. Returns them as a Vec<u16>.
795+
/// Terminator 0x0000 is not included in the returned Vec<u16>.
796+
///
797+
/// Performs appropriate bounds checks.
798+
pub fn read_wide_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, Vec<u16>> {
799+
let size_2bytes = Size::from_bytes(2);
800+
let align_2bytes = Align::from_bytes(2).unwrap();
801+
// We need to read at least 2 bytes, so we *need* a ptr.
802+
let mut ptr = self.force_ptr(ptr)?;
803+
let allocation = self.get_raw(ptr.alloc_id)?;
804+
let mut u16_seq = Vec::new();
805+
806+
loop {
807+
ptr = self
808+
.check_ptr_access(ptr.into(), size_2bytes, align_2bytes)?
809+
.expect("cannot be a ZST");
810+
let single_u16 = allocation.read_scalar(self, ptr, size_2bytes)?.to_u16()?;
811+
if single_u16 != 0x0000 {
812+
u16_seq.push(single_u16);
813+
ptr = ptr.offset(size_2bytes, self)?;
814+
} else {
815+
break;
816+
}
817+
}
818+
Ok(u16_seq)
819+
}
820+
794821
/// Writes the given stream of bytes into memory.
795822
///
796823
/// Performs appropriate bounds checks.

0 commit comments

Comments
 (0)