Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2018-08-30
nightly-2018-09-01
8 changes: 4 additions & 4 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
};

self.write_scalar(
Scalar::from_i32(result),
Scalar::from_int(result, Size::from_bits(32)),
dest,
)?;
}
Expand Down Expand Up @@ -346,7 +346,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
let name = self.memory.read_c_str(name_ptr)?;
match self.machine.env_vars.get(name) {
Some(&var) => Scalar::Ptr(var),
None => Scalar::null(self.memory.pointer_size()),
None => Scalar::ptr_null(*self.tcx),
}
};
self.write_scalar(result, dest)?;
Expand Down Expand Up @@ -446,7 +446,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '

// Some things needed for sys::thread initialization to go through
"signal" | "sigaction" | "sigaltstack" => {
self.write_scalar(Scalar::null(dest.layout.size), dest)?;
self.write_scalar(Scalar::from_int(0, dest.layout.size), dest)?;
}

"sysconf" => {
Expand Down Expand Up @@ -729,6 +729,6 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
}

fn write_null(&mut self, dest: PlaceTy<'tcx>) -> EvalResult<'tcx> {
self.write_scalar(Scalar::null(dest.layout.size), dest)
self.write_scalar(Scalar::from_int(0, dest.layout.size), dest)
}
}
45 changes: 0 additions & 45 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,12 @@
use rustc::ty::layout::Size;

use super::{Scalar, ScalarMaybeUndef, EvalResult};

pub trait ScalarExt {
fn null(size: Size) -> Self;
fn from_i32(i: i32) -> Self;
fn from_uint(i: impl Into<u128>, ptr_size: Size) -> Self;
fn from_int(i: impl Into<i128>, ptr_size: Size) -> Self;
fn from_f32(f: f32) -> Self;
fn from_f64(f: f64) -> Self;
fn is_null(self) -> bool;
}

pub trait FalibleScalarExt {
/// HACK: this function just extracts all bits if `defined != 0`
/// Mainly used for args of C-functions and we should totally correctly fetch the size
/// of their arguments
fn to_bytes(self) -> EvalResult<'static, u128>;
}

impl ScalarExt for Scalar {
fn null(size: Size) -> Self {
Scalar::Bits { bits: 0, size: size.bytes() as u8 }
}

fn from_i32(i: i32) -> Self {
Scalar::Bits { bits: i as u32 as u128, size: 4 }
}

fn from_uint(i: impl Into<u128>, size: Size) -> Self {
Scalar::Bits { bits: i.into(), size: size.bytes() as u8 }
}

fn from_int(i: impl Into<i128>, size: Size) -> Self {
Scalar::Bits { bits: i.into() as u128, size: size.bytes() as u8 }
}

fn from_f32(f: f32) -> Self {
Scalar::Bits { bits: f.to_bits() as u128, size: 4 }
}

fn from_f64(f: f64) -> Self {
Scalar::Bits { bits: f.to_bits() as u128, size: 8 }
}

fn is_null(self) -> bool {
match self {
Scalar::Bits { bits, .. } => bits == 0,
Scalar::Ptr(_) => false
}
}
}

impl FalibleScalarExt for Scalar {
fn to_bytes(self) -> EvalResult<'static, u128> {
match self {
Expand Down
77 changes: 30 additions & 47 deletions src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use rustc::mir;
use rustc::ty::layout::{self, LayoutOf, Size};
use rustc::ty;

use rustc::mir::interpret::{EvalResult, Scalar, ScalarMaybeUndef};
use rustc::mir::interpret::{EvalResult, Scalar, ScalarMaybeUndef, PointerArithmetic};
use rustc_mir::interpret::{
PlaceTy, EvalContext, OpTy, Value
};

use super::{ScalarExt, FalibleScalarExt, OperatorEvalContextExt};
use super::{FalibleScalarExt, OperatorEvalContextExt};

pub trait EvalContextExt<'tcx> {
fn call_intrinsic(
Expand Down Expand Up @@ -116,11 +116,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:

_ if intrinsic_name.starts_with("atomic_cxchg") => {
let ptr = self.ref_to_mplace(self.read_value(args[0])?)?;
let expect_old = self.read_value(args[1])?; // read as value for the sake of `binary_op()`
let expect_old = self.read_value(args[1])?; // read as value for the sake of `binary_op_val()`
let new = self.read_scalar(args[2])?;
let old = self.read_value(ptr.into())?; // read as value for the sake of `binary_op()`
// binary_op will bail if either of them is not a scalar
let (eq, _) = self.binary_op(mir::BinOp::Eq, old, expect_old)?;
let old = self.read_value(ptr.into())?; // read as value for the sake of `binary_op_val()`
// binary_op_val will bail if either of them is not a scalar
let (eq, _) = self.binary_op_val(mir::BinOp::Eq, old, expect_old)?;
let res = Value::ScalarPair(old.to_scalar_or_undef(), eq.into());
self.write_value(res, dest)?; // old value is returned
// update ptr depending on comparison
Expand Down Expand Up @@ -167,8 +167,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
_ => bug!(),
};
// FIXME: what do atomics do on overflow?
let (val, _) = self.binary_op(op, old, rhs)?;
self.write_scalar(val, ptr.into())?;
self.binop_ignore_overflow(op, old, rhs, ptr.into())?;
}

"breakpoint" => unimplemented!(), // halt miri
Expand Down Expand Up @@ -204,8 +203,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:

"sinf32" | "fabsf32" | "cosf32" | "sqrtf32" | "expf32" | "exp2f32" | "logf32" |
"log10f32" | "log2f32" | "floorf32" | "ceilf32" | "truncf32" => {
let f = self.read_scalar(args[0])?.to_bytes()?;
let f = f32::from_bits(f as u32);
let f = self.read_scalar(args[0])?.to_f32()?;
let f = match intrinsic_name {
"sinf32" => f.sin(),
"fabsf32" => f.abs(),
Expand All @@ -226,8 +224,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:

"sinf64" | "fabsf64" | "cosf64" | "sqrtf64" | "expf64" | "exp2f64" | "logf64" |
"log10f64" | "log2f64" | "floorf64" | "ceilf64" | "truncf64" => {
let f = self.read_scalar(args[0])?.to_bytes()?;
let f = f64::from_bits(f as u64);
let f = self.read_scalar(args[0])?.to_f64()?;
let f = match intrinsic_name {
"sinf64" => f.sin(),
"fabsf64" => f.abs(),
Expand Down Expand Up @@ -257,8 +254,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
"frem_fast" => mir::BinOp::Rem,
_ => bug!(),
};
let result = self.binary_op(op, a, b)?;
self.write_scalar(result.0, dest)?;
self.binop_ignore_overflow(op, a, b, dest)?;
}

"exact_div" => {
Expand All @@ -267,11 +263,10 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
let a = self.read_value(args[0])?;
let b = self.read_value(args[1])?;
// check x % y != 0
if !self.binary_op(mir::BinOp::Rem, a, b)?.0.is_null() {
if !self.binary_op_val(mir::BinOp::Rem, a, b)?.0.is_null() {
return err!(ValidationFailure(format!("exact_div: {:?} cannot be divided by {:?}", a, b)));
}
let result = self.binary_op(mir::BinOp::Div, a, b)?;
self.write_scalar(result.0, dest)?;
self.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?;
},

"likely" | "unlikely" | "forget" => {}
Expand All @@ -282,12 +277,12 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
if !dest.layout.is_zst() { // notzhing to do for ZST
match dest.layout.abi {
layout::Abi::Scalar(ref s) => {
let x = Scalar::null(s.value.size(&self));
let x = Scalar::from_int(0, s.value.size(&self));
self.write_value(Value::Scalar(x.into()), dest)?;
}
layout::Abi::ScalarPair(ref s1, ref s2) => {
let x = Scalar::null(s1.value.size(&self));
let y = Scalar::null(s2.value.size(&self));
let x = Scalar::from_int(0, s1.value.size(&self));
let y = Scalar::from_int(0, s2.value.size(&self));
self.write_value(Value::ScalarPair(x.into(), y.into()), dest)?;
}
_ => {
Expand All @@ -304,7 +299,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
let ty = substs.type_at(0);
let layout = self.layout_of(ty)?;
let align = layout.align.pref();
let ptr_size = self.memory.pointer_size();
let ptr_size = self.pointer_size();
let align_val = Scalar::from_uint(align as u128, ptr_size);
self.write_scalar(align_val, dest)?;
}
Expand Down Expand Up @@ -365,56 +360,45 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
}

"powf32" => {
let f = self.read_scalar(args[0])?.to_bits(Size::from_bits(32))?;
let f = f32::from_bits(f as u32);
let f2 = self.read_scalar(args[1])?.to_bits(Size::from_bits(32))?;
let f2 = f32::from_bits(f2 as u32);
let f = self.read_scalar(args[0])?.to_f32()?;
let f2 = self.read_scalar(args[1])?.to_f32()?;
self.write_scalar(
Scalar::from_f32(f.powf(f2)),
dest,
)?;
}

"powf64" => {
let f = self.read_scalar(args[0])?.to_bits(Size::from_bits(64))?;
let f = f64::from_bits(f as u64);
let f2 = self.read_scalar(args[1])?.to_bits(Size::from_bits(64))?;
let f2 = f64::from_bits(f2 as u64);
let f = self.read_scalar(args[0])?.to_f64()?;
let f2 = self.read_scalar(args[1])?.to_f64()?;
self.write_scalar(
Scalar::from_f64(f.powf(f2)),
dest,
)?;
}

"fmaf32" => {
let a = self.read_scalar(args[0])?.to_bits(Size::from_bits(32))?;
let a = f32::from_bits(a as u32);
let b = self.read_scalar(args[1])?.to_bits(Size::from_bits(32))?;
let b = f32::from_bits(b as u32);
let c = self.read_scalar(args[2])?.to_bits(Size::from_bits(32))?;
let c = f32::from_bits(c as u32);
let a = self.read_scalar(args[0])?.to_f32()?;
let b = self.read_scalar(args[1])?.to_f32()?;
let c = self.read_scalar(args[2])?.to_f32()?;
self.write_scalar(
Scalar::from_f32(a * b + c),
dest,
)?;
}

"fmaf64" => {
let a = self.read_scalar(args[0])?.to_bits(Size::from_bits(64))?;
let a = f64::from_bits(a as u64);
let b = self.read_scalar(args[1])?.to_bits(Size::from_bits(64))?;
let b = f64::from_bits(b as u64);
let c = self.read_scalar(args[2])?.to_bits(Size::from_bits(64))?;
let c = f64::from_bits(c as u64);
let a = self.read_scalar(args[0])?.to_f64()?;
let b = self.read_scalar(args[1])?.to_f64()?;
let c = self.read_scalar(args[2])?.to_f64()?;
self.write_scalar(
Scalar::from_f64(a * b + c),
dest,
)?;
}

"powif32" => {
let f = self.read_scalar(args[0])?.to_bits(Size::from_bits(32))?;
let f = f32::from_bits(f as u32);
let f = self.read_scalar(args[0])?.to_f32()?;
let i = self.read_scalar(args[1])?.to_i32()?;
self.write_scalar(
Scalar::from_f32(f.powi(i)),
Expand All @@ -423,8 +407,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
}

"powif64" => {
let f = self.read_scalar(args[0])?.to_bits(Size::from_bits(64))?;
let f = f64::from_bits(f as u64);
let f = self.read_scalar(args[0])?.to_f64()?;
let i = self.read_scalar(args[1])?.to_i32()?;
self.write_scalar(
Scalar::from_f64(f.powi(i)),
Expand All @@ -435,7 +418,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
"size_of_val" => {
let mplace = self.ref_to_mplace(self.read_value(args[0])?)?;
let (size, _) = self.size_and_align_of_mplace(mplace)?;
let ptr_size = self.memory.pointer_size();
let ptr_size = self.pointer_size();
self.write_scalar(
Scalar::from_uint(size.bytes() as u128, ptr_size),
dest,
Expand All @@ -446,7 +429,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
"align_of_val" => {
let mplace = self.ref_to_mplace(self.read_value(args[0])?)?;
let (_, align) = self.size_and_align_of_mplace(mplace)?;
let ptr_size = self.memory.pointer_size();
let ptr_size = self.pointer_size();
self.write_scalar(
Scalar::from_uint(align.abi(), ptr_size),
dest,
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use tls::EvalContextExt as TlsEvalContextExt;
use memory::MemoryKind as MiriMemoryKind;
use locks::LockInfo;
use range_map::RangeMap;
use helpers::{ScalarExt, FalibleScalarExt};
use helpers::FalibleScalarExt;

pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand Down Expand Up @@ -304,14 +304,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
ecx.call_intrinsic(instance, args, dest)
}

fn try_ptr_op<'a>(
fn ptr_op<'a>(
ecx: &rustc_mir::interpret::EvalContext<'a, 'mir, 'tcx, Self>,
bin_op: mir::BinOp,
left: Scalar,
left_layout: TyLayout<'tcx>,
right: Scalar,
right_layout: TyLayout<'tcx>,
) -> EvalResult<'tcx, Option<(Scalar, bool)>> {
) -> EvalResult<'tcx, (Scalar, bool)> {
ecx.ptr_op(bin_op, left, left_layout, right, right_layout)
}

Expand Down
Loading