]> git.lizzy.rs Git - rust.git/commitdiff
add write_int_fields to replace write_packed_immediates
authorRalf Jung <post@ralfj.de>
Sat, 12 Mar 2022 16:21:45 +0000 (11:21 -0500)
committerRalf Jung <post@ralfj.de>
Sat, 12 Mar 2022 17:17:23 +0000 (12:17 -0500)
for stat, lookup fields by name

src/helpers.rs
src/shims/posix/fs.rs
src/shims/time.rs

index 84792c2394e375f61d7c66427d26479c064384c3..ba12e0a7e394e1ef8680770913db65175436b18b 100644 (file)
@@ -57,8 +57,8 @@ fn resolve_path(&self, path: &[&str]) -> ty::Instance<'tcx> {
 
     /// Evaluates the scalar at the specified path. Returns Some(val)
     /// if the path could be resolved, and None otherwise
-    fn eval_path_scalar(&mut self, path: &[&str]) -> InterpResult<'tcx, Scalar<Tag>> {
-        let this = self.eval_context_mut();
+    fn eval_path_scalar(&self, path: &[&str]) -> InterpResult<'tcx, Scalar<Tag>> {
+        let this = self.eval_context_ref();
         let instance = this.resolve_path(path);
         let cid = GlobalId { instance, promoted: None };
         let const_val = this.eval_to_allocation(cid)?;
@@ -67,51 +67,98 @@ fn eval_path_scalar(&mut self, path: &[&str]) -> InterpResult<'tcx, Scalar<Tag>>
     }
 
     /// Helper function to get a `libc` constant as a `Scalar`.
-    fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
-        self.eval_context_mut().eval_path_scalar(&["libc", name])
+    fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
+        self.eval_path_scalar(&["libc", name])
     }
 
     /// Helper function to get a `libc` constant as an `i32`.
-    fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
+    fn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32> {
         // TODO: Cache the result.
         self.eval_libc(name)?.to_i32()
     }
 
     /// Helper function to get a `windows` constant as a `Scalar`.
-    fn eval_windows(&mut self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
-        self.eval_context_mut().eval_path_scalar(&["std", "sys", "windows", module, name])
+    fn eval_windows(&self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
+        self.eval_context_ref().eval_path_scalar(&["std", "sys", "windows", module, name])
     }
 
     /// Helper function to get a `windows` constant as a `u64`.
-    fn eval_windows_u64(&mut self, module: &str, name: &str) -> InterpResult<'tcx, u64> {
+    fn eval_windows_u64(&self, module: &str, name: &str) -> InterpResult<'tcx, u64> {
         // TODO: Cache the result.
         self.eval_windows(module, name)?.to_u64()
     }
 
     /// Helper function to get the `TyAndLayout` of a `libc` type
-    fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-        let this = self.eval_context_mut();
+    fn libc_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+        let this = self.eval_context_ref();
         let ty = this.resolve_path(&["libc", name]).ty(*this.tcx, ty::ParamEnv::reveal_all());
         this.layout_of(ty)
     }
 
     /// Helper function to get the `TyAndLayout` of a `windows` type
-    fn windows_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-        let this = self.eval_context_mut();
+    fn windows_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+        let this = self.eval_context_ref();
         let ty = this
             .resolve_path(&["std", "sys", "windows", "c", name])
             .ty(*this.tcx, ty::ParamEnv::reveal_all());
         this.layout_of(ty)
     }
 
-    /// Write a uint of the appropriate size to `dest`.
-    fn write_uint(&mut self, i: impl Into<u128>, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
-        self.eval_context_mut().write_scalar(Scalar::from_uint(i, dest.layout.size), dest)
+    /// Project to the given *named* field of the mplace (which must be a struct or union type).
+    fn mplace_field_named(
+        &self,
+        mplace: &MPlaceTy<'tcx, Tag>,
+        name: &str,
+    ) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
+        let this = self.eval_context_ref();
+        let adt = mplace.layout.ty.ty_adt_def().unwrap();
+        for (idx, field) in adt.non_enum_variant().fields.iter().enumerate() {
+            if field.name.as_str() == name {
+                return this.mplace_field(mplace, idx);
+            }
+        }
+        bug!("No field named {} in type {}", name, mplace.layout.ty);
     }
 
-    /// Write an int of the appropriate size to `dest`.
+    /// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned,
+    /// we try to do the right thing anyway. `i128` can fit all integer types except for `u128` so
+    /// this method is fine for almost all integer types.
     fn write_int(&mut self, i: impl Into<i128>, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
-        self.eval_context_mut().write_scalar(Scalar::from_int(i, dest.layout.size), dest)
+        assert!(dest.layout.abi.is_scalar(), "write_int on non-scalar type {}", dest.layout.ty);
+        let val = if dest.layout.abi.is_signed() {
+            Scalar::from_int(i, dest.layout.size)
+        } else {
+            Scalar::from_uint(u64::try_from(i.into()).unwrap(), dest.layout.size)
+        };
+        self.eval_context_mut().write_scalar(val, dest)
+    }
+
+    /// Write the first N fields of the given place.
+    fn write_int_fields(
+        &mut self,
+        values: &[i128],
+        dest: &MPlaceTy<'tcx, Tag>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        for (idx, &val) in values.iter().enumerate() {
+            let field = this.mplace_field(dest, idx)?;
+            this.write_int(val, &field.into())?;
+        }
+        Ok(())
+    }
+
+    /// Write the given fields of the given place.
+    fn write_int_fields_named(
+        &mut self,
+        values: &[(&str, i128)],
+        dest: &MPlaceTy<'tcx, Tag>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        for &(name, val) in values.iter() {
+            let field = this.mplace_field_named(dest, name)?;
+            this.write_int(val, &field.into())?;
+        }
+        Ok(())
     }
 
     /// Write a 0 of the appropriate size to `dest`.
@@ -383,27 +430,6 @@ fn visit_union(
         }
     }
 
-    // Writes several `ImmTy`s contiguously into memory. This is useful when you have to pack
-    // different values into a struct.
-    fn write_packed_immediates(
-        &mut self,
-        place: &MPlaceTy<'tcx, Tag>,
-        imms: &[ImmTy<'tcx, Tag>],
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-
-        let mut offset = Size::from_bytes(0);
-
-        for &imm in imms {
-            this.write_immediate(
-                *imm,
-                &place.offset(offset, MemPlaceMeta::None, imm.layout, &*this.tcx)?.into(),
-            )?;
-            offset += imm.layout.size;
-        }
-        Ok(())
-    }
-
     /// Helper function used inside the shims of foreign functions to check that isolation is
     /// disabled. It returns an error using the `name` of the foreign function if this is not the
     /// case.
@@ -750,26 +776,6 @@ pub fn isolation_abort_error(name: &str) -> InterpResult<'static> {
     )))
 }
 
-pub fn immty_from_int_checked<'tcx>(
-    int: impl Into<i128>,
-    layout: TyAndLayout<'tcx>,
-) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
-    let int = int.into();
-    Ok(ImmTy::try_from_int(int, layout).ok_or_else(|| {
-        err_unsup_format!("signed value {:#x} does not fit in {} bits", int, layout.size.bits())
-    })?)
-}
-
-pub fn immty_from_uint_checked<'tcx>(
-    int: impl Into<u128>,
-    layout: TyAndLayout<'tcx>,
-) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
-    let int = int.into();
-    Ok(ImmTy::try_from_uint(int, layout).ok_or_else(|| {
-        err_unsup_format!("unsigned value {:#x} does not fit in {} bits", int, layout.size.bits())
-    })?)
-}
-
 pub fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Tag> {
     // SIMD uses all-1 as pattern for "true"
     let val = if b { -1 } else { 0 };
index efb11b3bee9f6e62d0f2196dd66f312232c39ce2..b71f53cce566e4a84c973f501c647aff41b2b80c 100644 (file)
@@ -15,7 +15,7 @@
 use rustc_target::abi::{Align, Size};
 
 use crate::*;
-use helpers::{check_arg_count, immty_from_int_checked, immty_from_uint_checked};
+use helpers::check_arg_count;
 use shims::os_str::os_str_to_bytes;
 use shims::time::system_time_to_duration;
 
@@ -318,45 +318,32 @@ fn macos_stat_write_buf(
         let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
         let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
 
-        let dev_t_layout = this.libc_ty_layout("dev_t")?;
-        let mode_t_layout = this.libc_ty_layout("mode_t")?;
-        let nlink_t_layout = this.libc_ty_layout("nlink_t")?;
-        let ino_t_layout = this.libc_ty_layout("ino_t")?;
-        let uid_t_layout = this.libc_ty_layout("uid_t")?;
-        let gid_t_layout = this.libc_ty_layout("gid_t")?;
-        let time_t_layout = this.libc_ty_layout("time_t")?;
-        let long_layout = this.libc_ty_layout("c_long")?;
-        let off_t_layout = this.libc_ty_layout("off_t")?;
-        let blkcnt_t_layout = this.libc_ty_layout("blkcnt_t")?;
-        let blksize_t_layout = this.libc_ty_layout("blksize_t")?;
-        let uint32_t_layout = this.libc_ty_layout("uint32_t")?;
-
-        let imms = [
-            immty_from_uint_checked(0u128, dev_t_layout)?, // st_dev
-            immty_from_uint_checked(mode, mode_t_layout)?, // st_mode
-            immty_from_uint_checked(0u128, nlink_t_layout)?, // st_nlink
-            immty_from_uint_checked(0u128, ino_t_layout)?, // st_ino
-            immty_from_uint_checked(0u128, uid_t_layout)?, // st_uid
-            immty_from_uint_checked(0u128, gid_t_layout)?, // st_gid
-            immty_from_uint_checked(0u128, dev_t_layout)?, // st_rdev
-            immty_from_uint_checked(0u128, uint32_t_layout)?, // padding
-            immty_from_uint_checked(access_sec, time_t_layout)?, // st_atime
-            immty_from_uint_checked(access_nsec, long_layout)?, // st_atime_nsec
-            immty_from_uint_checked(modified_sec, time_t_layout)?, // st_mtime
-            immty_from_uint_checked(modified_nsec, long_layout)?, // st_mtime_nsec
-            immty_from_uint_checked(0u128, time_t_layout)?, // st_ctime
-            immty_from_uint_checked(0u128, long_layout)?,  // st_ctime_nsec
-            immty_from_uint_checked(created_sec, time_t_layout)?, // st_birthtime
-            immty_from_uint_checked(created_nsec, long_layout)?, // st_birthtime_nsec
-            immty_from_uint_checked(metadata.size, off_t_layout)?, // st_size
-            immty_from_uint_checked(0u128, blkcnt_t_layout)?, // st_blocks
-            immty_from_uint_checked(0u128, blksize_t_layout)?, // st_blksize
-            immty_from_uint_checked(0u128, uint32_t_layout)?, // st_flags
-            immty_from_uint_checked(0u128, uint32_t_layout)?, // st_gen
-        ];
-
         let buf = this.deref_operand(buf_op)?;
-        this.write_packed_immediates(&buf, &imms)?;
+        this.write_int_fields_named(
+            &[
+                ("st_dev", 0),
+                ("st_mode", mode.into()),
+                ("st_nlink", 0),
+                ("st_ino", 0),
+                ("st_uid", 0),
+                ("st_gid", 0),
+                ("st_rdev", 0),
+                ("st_atime", access_sec.into()),
+                ("st_atime_nsec", access_nsec.into()),
+                ("st_mtime", modified_sec.into()),
+                ("st_mtime_nsec", modified_nsec.into()),
+                ("st_ctime", 0),
+                ("st_ctime_nsec", 0),
+                ("st_birthtime", created_sec.into()),
+                ("st_birthtime_nsec", created_nsec.into()),
+                ("st_size", metadata.size.into()),
+                ("st_blocks", 0),
+                ("st_blksize", 0),
+                ("st_flags", 0),
+                ("st_gen", 0),
+            ],
+            &buf,
+        )?;
 
         Ok(0)
     }
@@ -954,7 +941,7 @@ fn linux_statx(
         // `syscall` function is untyped. This means that all the `statx` parameters are provided
         // as `isize`s instead of having the proper types. Thus, we have to recover the layout of
         // `statxbuf_op` by using the `libc::statx` struct type.
-        let statxbuf_place = {
+        let statxbuf = {
             // FIXME: This long path is required because `libc::statx` is an struct and also a
             // function and `resolve_path` is returning the latter.
             let statx_ty = this
@@ -1064,44 +1051,55 @@ fn linux_statx(
             })
             .unwrap_or(Ok((0, 0)))?;
 
-        let __u32_layout = this.libc_ty_layout("__u32")?;
-        let __u64_layout = this.libc_ty_layout("__u64")?;
-        let __u16_layout = this.libc_ty_layout("__u16")?;
-
-        // Now we transform all this fields into `ImmTy`s and write them to `statxbuf`. We write a
-        // zero for the unavailable fields.
-        let imms = [
-            immty_from_uint_checked(mask, __u32_layout)?, // stx_mask
-            immty_from_uint_checked(0u128, __u32_layout)?, // stx_blksize
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_attributes
-            immty_from_uint_checked(0u128, __u32_layout)?, // stx_nlink
-            immty_from_uint_checked(0u128, __u32_layout)?, // stx_uid
-            immty_from_uint_checked(0u128, __u32_layout)?, // stx_gid
-            immty_from_uint_checked(mode, __u16_layout)?, // stx_mode
-            immty_from_uint_checked(0u128, __u16_layout)?, // statx padding
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_ino
-            immty_from_uint_checked(metadata.size, __u64_layout)?, // stx_size
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_blocks
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_attributes
-            immty_from_uint_checked(access_sec, __u64_layout)?, // stx_atime.tv_sec
-            immty_from_uint_checked(access_nsec, __u32_layout)?, // stx_atime.tv_nsec
-            immty_from_uint_checked(0u128, __u32_layout)?, // statx_timestamp padding
-            immty_from_uint_checked(created_sec, __u64_layout)?, // stx_btime.tv_sec
-            immty_from_uint_checked(created_nsec, __u32_layout)?, // stx_btime.tv_nsec
-            immty_from_uint_checked(0u128, __u32_layout)?, // statx_timestamp padding
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_ctime.tv_sec
-            immty_from_uint_checked(0u128, __u32_layout)?, // stx_ctime.tv_nsec
-            immty_from_uint_checked(0u128, __u32_layout)?, // statx_timestamp padding
-            immty_from_uint_checked(modified_sec, __u64_layout)?, // stx_mtime.tv_sec
-            immty_from_uint_checked(modified_nsec, __u32_layout)?, // stx_mtime.tv_nsec
-            immty_from_uint_checked(0u128, __u32_layout)?, // statx_timestamp padding
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_rdev_major
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_rdev_minor
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_dev_major
-            immty_from_uint_checked(0u128, __u64_layout)?, // stx_dev_minor
-        ];
-
-        this.write_packed_immediates(&statxbuf_place, &imms)?;
+        // Now we write everything to `statxbuf`. We write a zero for the unavailable fields.
+        this.write_int_fields_named(
+            &[
+                ("stx_mask", mask.into()),
+                ("stx_blksize", 0),
+                ("stx_attributes", 0),
+                ("stx_nlink", 0),
+                ("stx_uid", 0),
+                ("stx_gid", 0),
+                ("stx_mode", mode.into()),
+                ("stx_ino", 0),
+                ("stx_size", metadata.size.into()),
+                ("stx_blocks", 0),
+                ("stx_attributes_mask", 0),
+                ("stx_rdev_major", 0),
+                ("stx_rdev_minor", 0),
+                ("stx_dev_major", 0),
+                ("stx_dev_minor", 0),
+            ],
+            &statxbuf,
+        )?;
+        this.write_int_fields(
+            &[
+                access_sec.into(),  // stx_atime.tv_sec
+                access_nsec.into(), // stx_atime.tv_nsec
+            ],
+            &this.mplace_field_named(&statxbuf, "stx_atime")?,
+        )?;
+        this.write_int_fields(
+            &[
+                created_sec.into(),  // stx_btime.tv_sec
+                created_nsec.into(), // stx_btime.tv_nsec
+            ],
+            &this.mplace_field_named(&statxbuf, "stx_btime")?,
+        )?;
+        this.write_int_fields(
+            &[
+                0.into(), // stx_ctime.tv_sec
+                0.into(), // stx_ctime.tv_nsec
+            ],
+            &this.mplace_field_named(&statxbuf, "stx_ctime")?,
+        )?;
+        this.write_int_fields(
+            &[
+                modified_sec.into(),  // stx_mtime.tv_sec
+                modified_nsec.into(), // stx_mtime.tv_nsec
+            ],
+            &this.mplace_field_named(&statxbuf, "stx_mtime")?,
+        )?;
 
         Ok(0)
     }
@@ -1247,7 +1245,7 @@ fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, S
             Some(Ok(dir_entry)) => {
                 // Write the directory entry into a newly allocated buffer.
                 // The name is written with write_bytes, while the rest of the
-                // dirent64 struct is written using write_packed_immediates.
+                // dirent64 struct is written using write_int_fields.
 
                 // For reference:
                 // pub struct dirent64 {
@@ -1279,11 +1277,15 @@ fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, S
 
                 let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
 
-                let entry_place = MPlaceTy::from_aligned_ptr(entry, dirent64_layout);
-                this.write_uint(ino, &this.mplace_field(&entry_place, 0)?.into())?; // d_ino
-                this.write_uint(0u128, &this.mplace_field(&entry_place, 1)?.into())?; // d_off
-                this.write_uint(size, &this.mplace_field(&entry_place, 2)?.into())?; // d_reclen
-                this.write_int(file_type, &this.mplace_field(&entry_place, 3)?.into())?; // d_type
+                this.write_int_fields(
+                    &[
+                        ino.into(),       // d_ino
+                        0,                // d_off
+                        size.into(),      // d_reclen
+                        file_type.into(), // d_type
+                    ],
+                    &MPlaceTy::from_aligned_ptr(entry, dirent64_layout),
+                )?;
 
                 let name_ptr = entry.offset(Size::from_bytes(d_name_offset), this)?;
                 this.memory.write_bytes(name_ptr, name_bytes.iter().copied())?;
@@ -1333,7 +1335,7 @@ fn macos_readdir_r(
             Some(Ok(dir_entry)) => {
                 // Write into entry, write pointer to result, return 0 on success.
                 // The name is written with write_os_str_to_c_str, while the rest of the
-                // dirent struct is written using write_packed_Immediates.
+                // dirent struct is written using write_int_fields.
 
                 // For reference:
                 // pub struct dirent {
@@ -1361,10 +1363,6 @@ fn macos_readdir_r(
                 }
 
                 let entry_place = this.deref_operand(entry_op)?;
-                let ino_t_layout = this.libc_ty_layout("ino_t")?;
-                let off_t_layout = this.libc_ty_layout("off_t")?;
-                let c_ushort_layout = this.libc_ty_layout("c_ushort")?;
-                let c_uchar_layout = this.libc_ty_layout("c_uchar")?;
 
                 // If the host is a Unix system, fill in the inode number with its real value.
                 // If not, use 0 as a fallback value.
@@ -1375,14 +1373,16 @@ fn macos_readdir_r(
 
                 let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
 
-                let imms = [
-                    immty_from_uint_checked(ino, ino_t_layout)?,      // d_ino
-                    immty_from_uint_checked(0u128, off_t_layout)?,    // d_seekoff
-                    immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
-                    immty_from_uint_checked(file_name_len, c_ushort_layout)?, // d_namlen
-                    immty_from_int_checked(file_type, c_uchar_layout)?, // d_type
-                ];
-                this.write_packed_immediates(&entry_place, &imms)?;
+                this.write_int_fields(
+                    &[
+                        ino.into(),           // d_ino
+                        0,                    // d_seekoff
+                        0,                    // d_reclen
+                        file_name_len.into(), // d_namlen
+                        file_type.into(),     // d_type
+                    ],
+                    &entry_place,
+                )?;
 
                 let result_place = this.deref_operand(result_op)?;
                 this.write_scalar(this.read_scalar(entry_op)?, &result_place.into())?;
index 1db9d85debdc19eec9583800016cd988df2f2e56..0acd697fa4050fbb2c627240788eafafa1058bf4 100644 (file)
@@ -2,7 +2,6 @@
 use std::time::{Duration, Instant, SystemTime};
 
 use crate::*;
-use helpers::{immty_from_int_checked, immty_from_uint_checked};
 use thread::Time;
 
 /// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
@@ -24,7 +23,6 @@ fn clock_gettime(
         this.check_no_isolation("`clock_gettime`")?;
 
         let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
-        let tp = this.deref_operand(tp_op)?;
 
         let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
             system_time_to_duration(&SystemTime::now())?
@@ -41,12 +39,7 @@ fn clock_gettime(
         let tv_sec = duration.as_secs();
         let tv_nsec = duration.subsec_nanos();
 
-        let imms = [
-            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
-            immty_from_int_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
-        ];
-
-        this.write_packed_immediates(&tp, &imms)?;
+        this.write_int_fields(&[tv_sec.into(), tv_nsec.into()], &this.deref_operand(tp_op)?)?;
 
         Ok(0)
     }
@@ -69,18 +62,11 @@ fn gettimeofday(
             return Ok(-1);
         }
 
-        let tv = this.deref_operand(tv_op)?;
-
         let duration = system_time_to_duration(&SystemTime::now())?;
         let tv_sec = duration.as_secs();
         let tv_usec = duration.subsec_micros();
 
-        let imms = [
-            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
-            immty_from_int_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
-        ];
-
-        this.write_packed_immediates(&tv, &imms)?;
+        this.write_int_fields(&[tv_sec.into(), tv_usec.into()], &this.deref_operand(tv_op)?)?;
 
         Ok(0)
     }
@@ -105,12 +91,11 @@ fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: &OpTy<'tcx, Tag>) -> Interp
 
         let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap();
         let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap();
-        let DWORD_tylayout = this.machine.layouts.u32;
-        let imms = [
-            immty_from_uint_checked(dwLowDateTime, DWORD_tylayout)?,
-            immty_from_uint_checked(dwHighDateTime, DWORD_tylayout)?,
-        ];
-        this.write_packed_immediates(&this.deref_operand(LPFILETIME_op)?, &imms)?;
+        this.write_int_fields(
+            &[dwLowDateTime.into(), dwHighDateTime.into()],
+            &this.deref_operand(LPFILETIME_op)?,
+        )?;
+
         Ok(())
     }
 
@@ -185,12 +170,8 @@ fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx
         // Since our emulated ticks in `mach_absolute_time` *are* nanoseconds,
         // no scaling needs to happen.
         let (numer, denom) = (1, 1);
-        let imms = [
-            immty_from_int_checked(numer, this.machine.layouts.u32)?,
-            immty_from_int_checked(denom, this.machine.layouts.u32)?,
-        ];
+        this.write_int_fields(&[numer.into(), denom.into()], &info)?;
 
-        this.write_packed_immediates(&info, &imms)?;
         Ok(0) // KERN_SUCCESS
     }