avoid Scalar::from_(u)int in favor of giving the size explicitly

This commit is contained in:
Ralf Jung 2020-03-28 17:35:40 +01:00
parent 3d3e2b65b9
commit fbbca59de7
11 changed files with 61 additions and 64 deletions

View file

@ -6,7 +6,7 @@ use std::convert::TryFrom;
use rand::rngs::StdRng;
use rand::SeedableRng;
use rustc::ty::layout::{LayoutOf, Size};
use rustc::ty::layout::LayoutOf;
use rustc::ty::{self, TyCtxt};
use rustc_hir::def_id::DefId;
@ -96,7 +96,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
// First argument: pointer to `main()`.
let main_ptr = ecx.memory.create_fn_alloc(FnVal::Instance(main_instance));
// Second argument (argc): length of `config.args`.
let argc = Scalar::from_uint(u64::try_from(config.args.len()).unwrap(), ecx.pointer_size());
let argc = Scalar::from_machine_usize(u64::try_from(config.args.len()).unwrap(), &ecx);
// Third argument (`argv`): created from `config.args`.
let argv = {
// Put each argument in memory, collect pointers.
@ -152,10 +152,9 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
let cmd_place = ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into());
ecx.machine.cmd_line = Some(cmd_place.ptr);
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
let char_size = Size::from_bytes(2);
for (idx, &c) in cmd_utf16.iter().enumerate() {
let place = ecx.mplace_field(cmd_place, idx)?;
ecx.write_scalar(Scalar::from_uint(c, char_size), place.into())?;
ecx.write_scalar(Scalar::from_u16(c), place.into())?;
}
}
argv

View file

@ -100,7 +100,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
/// Test if this immediate equals 0.
fn is_null(&self, val: Scalar<Tag>) -> InterpResult<'tcx, bool> {
let this = self.eval_context_ref();
let null = Scalar::from_int(0, this.memory.pointer_size());
let null = Scalar::ptr_null(this);
this.ptr_eq(val, null)
}

View file

@ -316,10 +316,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
let layout = ecx.layout_of(dest.layout.ty.builtin_deref(false).unwrap().ty)?;
// First argument: `size`.
// (`0` is allowed here -- this is expected to be handled by the lang item).
let size = Scalar::from_uint(layout.size.bytes(), ecx.pointer_size());
let size = Scalar::from_machine_usize(layout.size.bytes(), ecx);
// Second argument: `align`.
let align = Scalar::from_uint(layout.align.abi.bytes(), ecx.pointer_size());
let align = Scalar::from_machine_usize(layout.align.abi.bytes(), ecx);
// Call the `exchange_malloc` lang item.
let malloc = ecx.tcx.lang_items().exchange_malloc_fn().unwrap();

View file

@ -108,7 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
name_op: OpTy<'tcx, Tag>, // LPCWSTR
buf_op: OpTy<'tcx, Tag>, // LPWSTR
size_op: OpTy<'tcx, Tag>, // DWORD
) -> InterpResult<'tcx, u64> {
) -> InterpResult<'tcx, u32> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetEnvironmentVariableW");
@ -124,17 +124,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let buf_ptr = this.read_scalar(buf_op)?.not_undef()?;
// `buf_size` represents the size in characters.
let buf_size = u64::try_from(this.read_scalar(size_op)?.to_u32()?).unwrap();
let buf_size = u64::from(this.read_scalar(size_op)?.to_u32()?);
let (success, len) = this.write_os_str_to_wide_str(&var, buf_ptr, buf_size)?;
if success {
// If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer,
// not including the terminating null character.
len
u32::try_from(len).unwrap()
} else {
// If lpBuffer is not large enough to hold the data, the return value is the buffer size, in characters,
// required to hold the string and its terminating null character and the contents of lpBuffer are undefined.
len + 1
u32::try_from(len).unwrap().checked_add(1).unwrap()
}
}
None => {
@ -344,7 +344,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Collect all the pointers to each variable in a vector.
let mut vars: Vec<Scalar<Tag>> = this.machine.env_vars.map.values().map(|&ptr| ptr.into()).collect();
// Add the trailing null pointer.
vars.push(Scalar::from_int(0, this.pointer_size()));
vars.push(Scalar::from_machine_usize(0, this));
// Make an array with all these pointers inside Miri.
let tcx = this.tcx;
let vars_layout =

View file

@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn malloc(&mut self, size: u64, zero_init: bool, kind: MiriMemoryKind) -> Scalar<Tag> {
let this = self.eval_context_mut();
if size == 0 {
Scalar::from_int(0, this.pointer_size())
Scalar::ptr_null(this)
} else {
let align = this.min_align(size, kind);
let ptr = this.memory.allocate(Size::from_bytes(size), align, kind.into());
@ -78,7 +78,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let new_align = this.min_align(new_size, kind);
if this.is_null(old_ptr)? {
if new_size == 0 {
Ok(Scalar::from_int(0, this.pointer_size()))
Ok(Scalar::ptr_null(this))
} else {
let new_ptr =
this.memory.allocate(Size::from_bytes(new_size), new_align, kind.into());
@ -88,7 +88,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let old_ptr = this.force_ptr(old_ptr)?;
if new_size == 0 {
this.memory.deallocate(old_ptr, None, kind.into())?;
Ok(Scalar::from_int(0, this.pointer_size()))
Ok(Scalar::ptr_null(this))
} else {
let new_ptr = this.memory.reallocate(
old_ptr,
@ -296,7 +296,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
};
this.write_scalar(Scalar::from_int(result, Size::from_bits(32)), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"memrchr" => {
let ptr = this.read_scalar(args[0])?.not_undef()?;
@ -334,7 +334,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"strlen" => {
let ptr = this.read_scalar(args[0])?.not_undef()?;
let n = this.memory.read_c_str(ptr)?.len();
this.write_scalar(Scalar::from_uint(u64::try_from(n).unwrap(), dest.layout.size), dest)?;
this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
}
// math functions

View file

@ -26,11 +26,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"unsetenv" => {
let result = this.unsetenv(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"setenv" => {
let result = this.setenv(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"getcwd" => {
let result = this.getcwd(args[0], args[1])?;
@ -38,21 +38,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"chdir" => {
let result = this.chdir(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// File related shims
"open" | "open64" => {
let result = this.open(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"fcntl" => {
let result = this.fcntl(args[0], args[1], args.get(2).cloned())?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"read" => {
let result = this.read(args[0], args[1], args[2])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
}
"write" => {
let fd = this.read_scalar(args[0])?.to_i32()?;
@ -85,35 +85,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write(args[0], args[1], args[2])?
};
// Now, `result` is the value we return back to the program.
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
}
"unlink" => {
let result = this.unlink(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"symlink" => {
let result = this.symlink(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"rename" => {
let result = this.rename(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"mkdir" => {
let result = this.mkdir(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"rmdir" => {
let result = this.rmdir(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"closedir" => {
let result = this.closedir(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"lseek" | "lseek64" => {
let result = this.lseek64(args[0], args[1], args[2])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
// "lseek" is only used on macOS which is 64bit-only, so `i64` always works.
this.write_scalar(Scalar::from_i64(result), dest)?;
}
// Allocation
@ -165,8 +166,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let name = this.read_scalar(args[0])?.to_i32()?;
let sysconfs = &[
("_SC_PAGESIZE", Scalar::from_int(PAGE_SIZE, dest.layout.size)),
("_SC_NPROCESSORS_ONLN", Scalar::from_int(NUM_CPUS, dest.layout.size)),
("_SC_PAGESIZE", Scalar::from_int(PAGE_SIZE, this.pointer_size())),
("_SC_NPROCESSORS_ONLN", Scalar::from_int(NUM_CPUS, this.pointer_size())),
];
let mut result = None;
for &(sysconf_name, value) in sysconfs {

View file

@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// in the `posix` module.
"close" => {
let result = this.close(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"opendir" => {
let result = this.opendir(args[0])?;
@ -32,7 +32,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"readdir64_r" => {
let result = this.linux_readdir64_r(args[0], args[1], args[2])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// Linux-only
"posix_fadvise" => {
@ -48,7 +48,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"clock_gettime" => {
// This is a POSIX function but it has only been tested on linux.
let result = this.clock_gettime(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// Querying system information
@ -59,11 +59,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size_place = this.deref_operand(args[2])?;
this.write_scalar(
Scalar::from_uint(STACK_ADDR, addr_place.layout.size),
Scalar::from_uint(STACK_ADDR, this.pointer_size()),
addr_place.into(),
)?;
this.write_scalar(
Scalar::from_uint(STACK_SIZE, size_place.layout.size),
Scalar::from_uint(STACK_SIZE, this.pointer_size()),
size_place.into(),
)?;
@ -93,7 +93,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
id if id == sys_statx => {
// The first argument is the syscall id, so skip over it.
let result = this.linux_statx(args[1], args[2], args[3], args[4], args[5])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_machine_isize(result.into(), this), dest)?;
}
id => throw_unsup_format!("miri does not support syscall ID {}", id),
}
@ -110,7 +110,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(-1), dest)?;
}
// Incomplete shims that we "stub out" just to get pre-main initialziation code to work.

View file

@ -22,19 +22,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// File related shims
"close$NOCANCEL" => {
let result = this.close(args[0])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"stat$INODE64" => {
let result = this.macos_stat(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"lstat$INODE64" => {
let result = this.macos_lstat(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"fstat$INODE64" => {
let result = this.macos_fstat(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"opendir$INODE64" => {
let result = this.opendir(args[0])?;
@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"readdir_r$INODE64" => {
let result = this.macos_readdir_r(args[0], args[1], args[2])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// Environment related shims
@ -53,11 +53,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Time related shims
"gettimeofday" => {
let result = this.gettimeofday(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"mach_absolute_time" => {
let result = this.mach_absolute_time()?;
this.write_scalar(Scalar::from_uint(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_u64(result), dest)?;
}
// Access to command-line arguments
@ -79,12 +79,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Querying system information
"pthread_get_stackaddr_np" => {
let _thread = this.read_scalar(args[0])?.not_undef()?;
let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
let stack_addr = Scalar::from_uint(STACK_ADDR, this.pointer_size());
this.write_scalar(stack_addr, dest)?;
}
"pthread_get_stacksize_np" => {
let _thread = this.read_scalar(args[0])?.not_undef()?;
let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
let stack_size = Scalar::from_uint(STACK_SIZE, this.pointer_size());
this.write_scalar(stack_size, dest)?;
}

View file

@ -22,12 +22,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Environment related shims
"GetEnvironmentVariableW" => {
let result = this.GetEnvironmentVariableW(args[0], args[1], args[2])?;
this.write_scalar(Scalar::from_uint(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_u32(result), dest)?;
}
"SetEnvironmentVariableW" => {
let result = this.SetEnvironmentVariableW(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"GetEnvironmentStringsW" => {
@ -45,7 +45,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let which = this.read_scalar(args[0])?.to_i32()?;
// We just make this the identity function, so we know later in `WriteFile`
// which one it is.
this.write_scalar(Scalar::from_int(which, this.pointer_size()), dest)?;
this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
}
"WriteFile" => {
let handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
@ -74,7 +74,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
// Return whether this was a success.
this.write_scalar(
Scalar::from_int(if written.is_some() { 1 } else { 0 }, dest.layout.size),
Scalar::from_i32(if written.is_some() { 1 } else { 0 }),
dest,
)?;
}
@ -93,7 +93,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let _flags = this.read_scalar(args[1])?.to_u32()?;
let ptr = this.read_scalar(args[2])?.not_undef()?;
this.free(ptr, MiriMemoryKind::WinHeap)?;
this.write_scalar(Scalar::from_int(1, Size::from_bytes(4)), dest)?;
this.write_scalar(Scalar::from_i32(1), dest)?;
}
"HeapReAlloc" => {
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
@ -146,7 +146,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
// Return success (`1`).
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_i32(1), dest)?;
}
// Access to command-line arguments
@ -191,7 +191,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// These shims are enabled only when the caller is in the standard library.
"GetProcessHeap" if this.frame().instance.to_string().starts_with("std::sys::windows::") => {
// Just fake a HANDLE
this.write_scalar(Scalar::from_int(1, this.pointer_size()), dest)?;
this.write_scalar(Scalar::from_machine_isize(1, this), dest)?;
}
| "GetModuleHandleW"
| "GetProcAddress"
@ -202,7 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"AddVectoredExceptionHandler" if this.frame().instance.to_string().starts_with("std::sys::windows::") => {
// Any non zero value works for the stdlib. This is just used for stack overflows anyway.
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_machine_usize(1, this), dest)?;
}
| "InitializeCriticalSection"
| "EnterCriticalSection"

View file

@ -388,8 +388,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let ty = substs.type_at(0);
let layout = this.layout_of(ty)?;
let align = layout.align.pref.bytes();
let ptr_size = this.pointer_size();
let align_val = Scalar::from_uint(align, ptr_size);
let align_val = Scalar::from_machine_usize(align, this);
this.write_scalar(align_val, dest)?;
}
@ -471,8 +470,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let (size, _) = this
.size_and_align_of_mplace(mplace)?
.expect("size_of_val called on extern type");
let ptr_size = this.pointer_size();
this.write_scalar(Scalar::from_uint(size.bytes(), ptr_size), dest)?;
this.write_scalar(Scalar::from_machine_usize(size.bytes(), this), dest)?;
}
#[rustfmt::skip]
@ -483,8 +481,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let (_, align) = this
.size_and_align_of_mplace(mplace)?
.expect("size_of_val called on extern type");
let ptr_size = this.pointer_size();
this.write_scalar(Scalar::from_uint(align.bytes(), ptr_size), dest)?;
this.write_scalar(Scalar::from_machine_usize(align.bytes(), this), dest)?;
}
"write_bytes" => {

View file

@ -92,7 +92,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
// Return result, and jump to caller.
this.write_scalar(Scalar::from_uint(result, dest.layout.size), dest)?;
this.write_scalar(Scalar::from_uint(result, this.pointer_size()), dest)?;
this.go_to_block(ret);
Ok(())
}