commit
57b983862e
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
tex/*/out
|
||||
*.dot
|
||||
*.mir
|
||||
*.rs.bk
|
||||
|
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -2,7 +2,7 @@
|
||||
name = "miri"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (git+https://github.com/quininer/byteorder.git?branch=i128)",
|
||||
"compiletest_rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -19,8 +19,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
version = "1.0.0"
|
||||
source = "git+https://github.com/quininer/byteorder.git?branch=i128#ef51df297aa833d0b6639aae328a95597fc07d75"
|
||||
|
||||
[[package]]
|
||||
name = "compiletest_rs"
|
||||
@ -136,7 +136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||
"checksum byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96c8b41881888cc08af32d47ac4edd52bc7fa27fef774be47a92443756451304"
|
||||
"checksum byteorder 1.0.0 (git+https://github.com/quininer/byteorder.git?branch=i128)" = "<none>"
|
||||
"checksum compiletest_rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f344389765ad7bec166f64c1b39ed6dd2b54d81c4c5dd8af789169351d380c"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
|
@ -15,7 +15,8 @@ test = false
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
byteorder = "0.4.2"
|
||||
#byteorder = "0.4.2"
|
||||
byteorder = { git = "https://github.com/quininer/byteorder.git", branch = "i128", features = ["i128"]}
|
||||
env_logger = "0.3.3"
|
||||
log = "0.3.6"
|
||||
log_settings = "0.1.1"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(rustc_private)]
|
||||
#![feature(rustc_private, i128_type)]
|
||||
|
||||
extern crate getopts;
|
||||
extern crate miri;
|
||||
@ -51,7 +51,7 @@ fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits
|
||||
let mut limits = miri::ResourceLimits::default();
|
||||
let krate = state.hir_crate.as_ref().unwrap();
|
||||
let err_msg = "miri attributes need to be in the form `miri(key = value)`";
|
||||
let extract_int = |lit: &syntax::ast::Lit| -> u64 {
|
||||
let extract_int = |lit: &syntax::ast::Lit| -> u128 {
|
||||
match lit.node {
|
||||
syntax::ast::LitKind::Int(i, _) => i,
|
||||
_ => state.session.span_fatal(lit.span, "expected an integer literal"),
|
||||
@ -64,8 +64,8 @@ fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits
|
||||
if let NestedMetaItemKind::MetaItem(ref inner) = item.node {
|
||||
if let MetaItemKind::NameValue(ref value) = inner.node {
|
||||
match &inner.name().as_str()[..] {
|
||||
"memory_size" => limits.memory_size = extract_int(value),
|
||||
"step_limit" => limits.step_limit = extract_int(value),
|
||||
"memory_size" => limits.memory_size = extract_int(value) as u64,
|
||||
"step_limit" => limits.step_limit = extract_int(value) as u64,
|
||||
"stack_limit" => limits.stack_limit = extract_int(value) as usize,
|
||||
_ => state.session.span_err(item.span, "unknown miri attribute"),
|
||||
}
|
||||
|
40
src/cast.rs
40
src/cast.rs
@ -20,34 +20,36 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
F32 => self.cast_float(val.to_f32()? as f64, dest_ty),
|
||||
F64 => self.cast_float(val.to_f64()?, dest_ty),
|
||||
|
||||
I8 | I16 | I32 | I64 => self.cast_signed_int(val.to_i64()?, dest_ty),
|
||||
I8 | I16 | I32 | I64 | I128 => self.cast_signed_int(val.to_i128()?, dest_ty),
|
||||
|
||||
Bool | Char | U8 | U16 | U32 | U64 => self.cast_int(val.to_u64()?, dest_ty, false),
|
||||
Bool | Char | U8 | U16 | U32 | U64 | U128 => self.cast_int(val.to_u128()?, dest_ty, false),
|
||||
|
||||
FnPtr | Ptr => self.cast_ptr(val.to_ptr()?, dest_ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_signed_int(&self, val: i64, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
|
||||
self.cast_int(val as u64, ty, val < 0)
|
||||
fn cast_signed_int(&self, val: i128, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
|
||||
self.cast_int(val as u128, ty, val < 0)
|
||||
}
|
||||
|
||||
fn cast_int(&self, v: u64, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
|
||||
fn cast_int(&self, v: u128, ty: ty::Ty<'tcx>, negative: bool) -> EvalResult<'tcx, PrimVal> {
|
||||
use rustc::ty::TypeVariants::*;
|
||||
match ty.sty {
|
||||
TyBool if v == 0 => Ok(PrimVal::from_bool(false)),
|
||||
TyBool if v == 1 => Ok(PrimVal::from_bool(true)),
|
||||
TyBool => Err(EvalError::InvalidBool),
|
||||
|
||||
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i64 as i8 as u64)),
|
||||
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i64 as i16 as u64)),
|
||||
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i64 as i32 as u64)),
|
||||
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i64 as i64 as u64)),
|
||||
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i128 as i8 as u128)),
|
||||
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
|
||||
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
|
||||
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i128 as i64 as u128)),
|
||||
TyInt(IntTy::I128) => Ok(PrimVal::Bytes(v as u128)),
|
||||
|
||||
TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u64)),
|
||||
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u64)),
|
||||
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u64)),
|
||||
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v)),
|
||||
TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u128)),
|
||||
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
|
||||
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
|
||||
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
|
||||
TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),
|
||||
|
||||
TyInt(IntTy::Is) => {
|
||||
let int_ty = self.tcx.sess.target.int_type;
|
||||
@ -61,15 +63,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
self.cast_int(v, ty, negative)
|
||||
}
|
||||
|
||||
TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i64 as f64)),
|
||||
TyFloat(FloatTy::F64) if negative => Ok(PrimVal::from_f64(v as i128 as f64)),
|
||||
TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(v as f64)),
|
||||
TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i64 as f32)),
|
||||
TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i128 as f32)),
|
||||
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(v as f32)),
|
||||
|
||||
TyChar if v as u8 as u64 == v => Ok(PrimVal::Bytes(v)),
|
||||
TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
|
||||
TyChar => Err(EvalError::InvalidChar(v)),
|
||||
|
||||
TyRawPtr(_) => Ok(PrimVal::Ptr(Pointer::from_int(v))),
|
||||
TyRawPtr(_) => Ok(PrimVal::Ptr(Pointer::from_int(v as u64))),
|
||||
|
||||
_ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
|
||||
}
|
||||
@ -80,9 +82,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
match ty.sty {
|
||||
// Casting negative floats to unsigned integers yields zero.
|
||||
TyUint(_) if val < 0.0 => self.cast_int(0, ty, false),
|
||||
TyInt(_) if val < 0.0 => self.cast_int(val as i64 as u64, ty, true),
|
||||
TyInt(_) if val < 0.0 => self.cast_int(val as i128 as u128, ty, true),
|
||||
|
||||
TyInt(_) | ty::TyUint(_) => self.cast_int(val as u64, ty, false),
|
||||
TyInt(_) | ty::TyUint(_) => self.cast_int(val as u128, ty, false),
|
||||
|
||||
TyFloat(FloatTy::F64) => Ok(PrimVal::from_f64(val)),
|
||||
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)),
|
||||
|
@ -31,7 +31,7 @@ pub enum EvalError<'tcx> {
|
||||
ExecuteMemory,
|
||||
ArrayIndexOutOfBounds(Span, u64, u64),
|
||||
Math(Span, ConstMathErr),
|
||||
InvalidChar(u64),
|
||||
InvalidChar(u128),
|
||||
OutOfMemory {
|
||||
allocation_size: u64,
|
||||
memory_size: u64,
|
||||
|
@ -169,7 +169,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let ptr = self.memory.allocate(s.len() as u64, 1)?;
|
||||
self.memory.write_bytes(ptr, s.as_bytes())?;
|
||||
self.memory.freeze(ptr.alloc_id)?;
|
||||
Ok(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::from_u64(s.len() as u64)))
|
||||
Ok(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::from_u128(s.len() as u128)))
|
||||
}
|
||||
|
||||
pub(super) fn const_to_value(&mut self, const_val: &ConstVal) -> EvalResult<'tcx, Value> {
|
||||
@ -177,7 +177,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
use rustc_const_math::ConstFloat;
|
||||
|
||||
let primval = match *const_val {
|
||||
Integral(const_int) => PrimVal::Bytes(const_int.to_u64_unchecked()),
|
||||
Integral(const_int) => PrimVal::Bytes(const_int.to_u128_unchecked()),
|
||||
|
||||
Float(ConstFloat::F32(f)) => PrimVal::from_f32(f),
|
||||
Float(ConstFloat::F64(f)) => PrimVal::from_f64(f),
|
||||
@ -429,7 +429,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
General { discr, ref variants, .. } => {
|
||||
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
|
||||
let discr_val = adt_def.variants[variant].disr_val.to_u64_unchecked();
|
||||
let discr_val = adt_def.variants[variant].disr_val.to_u128_unchecked();
|
||||
let discr_size = discr.size().bytes();
|
||||
let discr_offset = variants[variant].offsets[0].bytes();
|
||||
|
||||
@ -497,7 +497,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
CEnum { .. } => {
|
||||
assert_eq!(operands.len(), 0);
|
||||
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
|
||||
let n = adt_def.variants[variant].disr_val.to_u64_unchecked();
|
||||
let n = adt_def.variants[variant].disr_val.to_u128_unchecked();
|
||||
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
|
||||
} else {
|
||||
bug!("tried to assign {:?} to Layout::CEnum", kind);
|
||||
@ -556,7 +556,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let src = self.eval_lvalue(lvalue)?;
|
||||
let ty = self.lvalue_ty(lvalue);
|
||||
let (_, len) = src.elem_ty_and_len(ty);
|
||||
self.write_primval(dest, PrimVal::from_u64(len), dest_ty)?;
|
||||
self.write_primval(dest, PrimVal::from_u128(len as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
Ref(_, _, ref lvalue) => {
|
||||
@ -566,7 +566,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
let val = match extra {
|
||||
LvalueExtra::None => Value::ByVal(ptr),
|
||||
LvalueExtra::Length(len) => Value::ByValPair(ptr, PrimVal::from_u64(len)),
|
||||
LvalueExtra::Length(len) => Value::ByValPair(ptr, PrimVal::from_u128(len as u128)),
|
||||
LvalueExtra::Vtable(vtable) => Value::ByValPair(ptr, PrimVal::Ptr(vtable)),
|
||||
LvalueExtra::DowncastVariant(..) =>
|
||||
bug!("attempted to take a reference to an enum downcast lvalue"),
|
||||
@ -1028,6 +1028,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
I16 => 2,
|
||||
I32 => 4,
|
||||
I64 => 8,
|
||||
I128 => 16,
|
||||
Is => self.memory.pointer_size(),
|
||||
};
|
||||
PrimValKind::from_int_size(size)
|
||||
@ -1040,6 +1041,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
U16 => 2,
|
||||
U32 => 4,
|
||||
U64 => 8,
|
||||
U128 => 16,
|
||||
Us => self.memory.pointer_size(),
|
||||
};
|
||||
PrimValKind::from_uint_size(size)
|
||||
@ -1092,7 +1094,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
ty::TyBool if val.to_bytes()? > 1 => Err(EvalError::InvalidBool),
|
||||
|
||||
ty::TyChar if ::std::char::from_u32(val.to_bytes()? as u32).is_none()
|
||||
=> Err(EvalError::InvalidChar(val.to_bytes()? as u32 as u64)),
|
||||
=> Err(EvalError::InvalidChar(val.to_bytes()? as u32 as u128)),
|
||||
|
||||
_ => Ok(()),
|
||||
}
|
||||
@ -1115,7 +1117,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let c = self.memory.read_uint(ptr, 4)? as u32;
|
||||
match ::std::char::from_u32(c) {
|
||||
Some(ch) => PrimVal::from_char(ch),
|
||||
None => return Err(EvalError::InvalidChar(c as u64)),
|
||||
None => return Err(EvalError::InvalidChar(c as u128)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1126,9 +1128,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
I16 => 2,
|
||||
I32 => 4,
|
||||
I64 => 8,
|
||||
I128 => 16,
|
||||
Is => self.memory.pointer_size(),
|
||||
};
|
||||
PrimVal::from_i64(self.memory.read_int(ptr, size)?)
|
||||
PrimVal::from_i128(self.memory.read_int(ptr, size)?)
|
||||
}
|
||||
|
||||
ty::TyUint(uint_ty) => {
|
||||
@ -1138,9 +1141,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
U16 => 2,
|
||||
U32 => 4,
|
||||
U64 => 8,
|
||||
U128 => 16,
|
||||
Us => self.memory.pointer_size(),
|
||||
};
|
||||
PrimVal::from_u64(self.memory.read_uint(ptr, size)?)
|
||||
PrimVal::from_u128(self.memory.read_uint(ptr, size)?)
|
||||
}
|
||||
|
||||
ty::TyFloat(FloatTy::F32) => PrimVal::from_f32(self.memory.read_f32(ptr)?),
|
||||
@ -1159,7 +1163,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let extra = match self.tcx.struct_tail(ty).sty {
|
||||
ty::TyDynamic(..) => PrimVal::Ptr(self.memory.read_ptr(extra)?),
|
||||
ty::TySlice(..) |
|
||||
ty::TyStr => PrimVal::from_u64(self.memory.read_usize(extra)?),
|
||||
ty::TyStr => PrimVal::from_u128(self.memory.read_usize(extra)? as u128),
|
||||
_ => bug!("unsized primval ptr read from {:?}", ty),
|
||||
};
|
||||
return Ok(Some(Value::ByValPair(PrimVal::Ptr(p), extra)));
|
||||
@ -1171,9 +1175,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
if let CEnum { discr, signed, .. } = *self.type_layout(ty)? {
|
||||
let size = discr.size().bytes();
|
||||
if signed {
|
||||
PrimVal::from_i64(self.memory.read_int(ptr, size)?)
|
||||
PrimVal::from_i128(self.memory.read_int(ptr, size)?)
|
||||
} else {
|
||||
PrimVal::from_u64(self.memory.read_uint(ptr, size)?)
|
||||
PrimVal::from_u128(self.memory.read_uint(ptr, size)?)
|
||||
}
|
||||
} else {
|
||||
return Ok(None);
|
||||
@ -1220,7 +1224,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
|
||||
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
|
||||
let ptr = src.read_ptr(&self.memory)?;
|
||||
let len = PrimVal::from_u64(length as u64);
|
||||
let len = PrimVal::from_u128(length as u128);
|
||||
let ptr = PrimVal::Ptr(ptr);
|
||||
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?;
|
||||
}
|
||||
@ -1454,6 +1458,7 @@ impl IntegerExt for layout::Integer {
|
||||
I16 => Size::from_bits(16),
|
||||
I32 => Size::from_bits(32),
|
||||
I64 => Size::from_bits(64),
|
||||
I128 => Size::from_bits(128),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
collections_bound,
|
||||
pub_restricted,
|
||||
rustc_private,
|
||||
i128_type,
|
||||
)]
|
||||
|
||||
// From rustc.
|
||||
|
@ -1,7 +1,7 @@
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian, BigEndian, self};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian, BigEndian};
|
||||
use std::collections::Bound::{Included, Excluded};
|
||||
use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use std::{fmt, iter, ptr, mem};
|
||||
use std::{fmt, iter, ptr, mem, io};
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, BareFnTy, ClosureTy, ClosureSubsts, TyCtxt};
|
||||
@ -567,6 +567,8 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
let endianess = self.endianess();
|
||||
let bytes = self.get_bytes_unchecked(ptr, size)?;
|
||||
let offset = read_target_uint(endianess, bytes).unwrap();
|
||||
assert_eq!(offset as u64 as u128, offset);
|
||||
let offset = offset as u64;
|
||||
let alloc = self.get(ptr.alloc_id)?;
|
||||
match alloc.relocations.get(&ptr.offset) {
|
||||
Some(&alloc_id) => Ok(Pointer::new(alloc_id, offset)),
|
||||
@ -596,10 +598,11 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
// We need to mask here, or the byteorder crate can die when given a u64 larger
|
||||
// than fits in an integer of the requested size.
|
||||
let mask = match size {
|
||||
1 => 0xff,
|
||||
2 => 0xffff,
|
||||
4 => 0xffffffff,
|
||||
8 => 0xffffffffffffffff,
|
||||
1 => !0u8 as u128,
|
||||
2 => !0u16 as u128,
|
||||
4 => !0u32 as u128,
|
||||
8 => !0u64 as u128,
|
||||
16 => !0,
|
||||
_ => bug!("unexpected PrimVal::Bytes size"),
|
||||
};
|
||||
self.write_uint(dest, bytes & mask, size)
|
||||
@ -630,16 +633,17 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
2 => Ok(self.layout.i16_align.abi()),
|
||||
4 => Ok(self.layout.i32_align.abi()),
|
||||
8 => Ok(self.layout.i64_align.abi()),
|
||||
16 => Ok(self.layout.i128_align.abi()),
|
||||
_ => bug!("bad integer size: {}", size),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_int(&self, ptr: Pointer, size: u64) -> EvalResult<'tcx, i64> {
|
||||
pub fn read_int(&self, ptr: Pointer, size: u64) -> EvalResult<'tcx, i128> {
|
||||
let align = self.int_align(size)?;
|
||||
self.get_bytes(ptr, size, align).map(|b| read_target_int(self.endianess(), b).unwrap())
|
||||
}
|
||||
|
||||
pub fn write_int(&mut self, ptr: Pointer, n: i64, size: u64) -> EvalResult<'tcx, ()> {
|
||||
pub fn write_int(&mut self, ptr: Pointer, n: i128, size: u64) -> EvalResult<'tcx, ()> {
|
||||
let align = self.int_align(size)?;
|
||||
let endianess = self.endianess();
|
||||
let b = self.get_bytes_mut(ptr, size, align)?;
|
||||
@ -647,12 +651,12 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_uint(&self, ptr: Pointer, size: u64) -> EvalResult<'tcx, u64> {
|
||||
pub fn read_uint(&self, ptr: Pointer, size: u64) -> EvalResult<'tcx, u128> {
|
||||
let align = self.int_align(size)?;
|
||||
self.get_bytes(ptr, size, align).map(|b| read_target_uint(self.endianess(), b).unwrap())
|
||||
}
|
||||
|
||||
pub fn write_uint(&mut self, ptr: Pointer, n: u64, size: u64) -> EvalResult<'tcx, ()> {
|
||||
pub fn write_uint(&mut self, ptr: Pointer, n: u128, size: u64) -> EvalResult<'tcx, ()> {
|
||||
let align = self.int_align(size)?;
|
||||
let endianess = self.endianess();
|
||||
let b = self.get_bytes_mut(ptr, size, align)?;
|
||||
@ -661,21 +665,21 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn read_isize(&self, ptr: Pointer) -> EvalResult<'tcx, i64> {
|
||||
self.read_int(ptr, self.pointer_size())
|
||||
self.read_int(ptr, self.pointer_size()).map(|i| i as i64)
|
||||
}
|
||||
|
||||
pub fn write_isize(&mut self, ptr: Pointer, n: i64) -> EvalResult<'tcx, ()> {
|
||||
let size = self.pointer_size();
|
||||
self.write_int(ptr, n, size)
|
||||
self.write_int(ptr, n as i128, size)
|
||||
}
|
||||
|
||||
pub fn read_usize(&self, ptr: Pointer) -> EvalResult<'tcx, u64> {
|
||||
self.read_uint(ptr, self.pointer_size())
|
||||
self.read_uint(ptr, self.pointer_size()).map(|i| i as u64)
|
||||
}
|
||||
|
||||
pub fn write_usize(&mut self, ptr: Pointer, n: u64) -> EvalResult<'tcx, ()> {
|
||||
let size = self.pointer_size();
|
||||
self.write_uint(ptr, n, size)
|
||||
self.write_uint(ptr, n as u128, size)
|
||||
}
|
||||
|
||||
pub fn write_f32(&mut self, ptr: Pointer, f: f32) -> EvalResult<'tcx, ()> {
|
||||
@ -801,31 +805,31 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
// Methods to access integers in the target endianess
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn write_target_uint(endianess: layout::Endian, mut target: &mut [u8], data: u64) -> Result<(), byteorder::Error> {
|
||||
fn write_target_uint(endianess: layout::Endian, mut target: &mut [u8], data: u128) -> Result<(), io::Error> {
|
||||
let len = target.len();
|
||||
match endianess {
|
||||
layout::Endian::Little => target.write_uint::<LittleEndian>(data, len),
|
||||
layout::Endian::Big => target.write_uint::<BigEndian>(data, len),
|
||||
layout::Endian::Little => target.write_uint128::<LittleEndian>(data, len),
|
||||
layout::Endian::Big => target.write_uint128::<BigEndian>(data, len),
|
||||
}
|
||||
}
|
||||
fn write_target_int(endianess: layout::Endian, mut target: &mut [u8], data: i64) -> Result<(), byteorder::Error> {
|
||||
fn write_target_int(endianess: layout::Endian, mut target: &mut [u8], data: i128) -> Result<(), io::Error> {
|
||||
let len = target.len();
|
||||
match endianess {
|
||||
layout::Endian::Little => target.write_int::<LittleEndian>(data, len),
|
||||
layout::Endian::Big => target.write_int::<BigEndian>(data, len),
|
||||
layout::Endian::Little => target.write_int128::<LittleEndian>(data, len),
|
||||
layout::Endian::Big => target.write_int128::<BigEndian>(data, len),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_target_uint(endianess: layout::Endian, mut source: &[u8]) -> Result<u64, byteorder::Error> {
|
||||
fn read_target_uint(endianess: layout::Endian, mut source: &[u8]) -> Result<u128, io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => source.read_uint::<LittleEndian>(source.len()),
|
||||
layout::Endian::Big => source.read_uint::<BigEndian>(source.len()),
|
||||
layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
|
||||
layout::Endian::Big => source.read_uint128::<BigEndian>(source.len()),
|
||||
}
|
||||
}
|
||||
fn read_target_int(endianess: layout::Endian, mut source: &[u8]) -> Result<i64, byteorder::Error> {
|
||||
fn read_target_int(endianess: layout::Endian, mut source: &[u8]) -> Result<i128, io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => source.read_int::<LittleEndian>(source.len()),
|
||||
layout::Endian::Big => source.read_int::<BigEndian>(source.len()),
|
||||
layout::Endian::Little => source.read_int128::<LittleEndian>(source.len()),
|
||||
layout::Endian::Big => source.read_int128::<BigEndian>(source.len()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -833,26 +837,26 @@ fn read_target_int(endianess: layout::Endian, mut source: &[u8]) -> Result<i64,
|
||||
// Methods to access floats in the target endianess
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn write_target_f32(endianess: layout::Endian, mut target: &mut [u8], data: f32) -> Result<(), byteorder::Error> {
|
||||
fn write_target_f32(endianess: layout::Endian, mut target: &mut [u8], data: f32) -> Result<(), io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => target.write_f32::<LittleEndian>(data),
|
||||
layout::Endian::Big => target.write_f32::<BigEndian>(data),
|
||||
}
|
||||
}
|
||||
fn write_target_f64(endianess: layout::Endian, mut target: &mut [u8], data: f64) -> Result<(), byteorder::Error> {
|
||||
fn write_target_f64(endianess: layout::Endian, mut target: &mut [u8], data: f64) -> Result<(), io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => target.write_f64::<LittleEndian>(data),
|
||||
layout::Endian::Big => target.write_f64::<BigEndian>(data),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_target_f32(endianess: layout::Endian, mut source: &[u8]) -> Result<f32, byteorder::Error> {
|
||||
fn read_target_f32(endianess: layout::Endian, mut source: &[u8]) -> Result<f32, io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => source.read_f32::<LittleEndian>(),
|
||||
layout::Endian::Big => source.read_f32::<BigEndian>(),
|
||||
}
|
||||
}
|
||||
fn read_target_f64(endianess: layout::Endian, mut source: &[u8]) -> Result<f64, byteorder::Error> {
|
||||
fn read_target_f64(endianess: layout::Endian, mut source: &[u8]) -> Result<f64, io::Error> {
|
||||
match endianess {
|
||||
layout::Endian::Little => source.read_f64::<LittleEndian>(),
|
||||
layout::Endian::Big => source.read_f64::<BigEndian>(),
|
||||
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
macro_rules! overflow {
|
||||
($op:ident, $l:expr, $r:expr) => ({
|
||||
let (val, overflowed) = $l.$op($r);
|
||||
let primval = PrimVal::Bytes(val as u64);
|
||||
let primval = PrimVal::Bytes(val as u128);
|
||||
Ok((primval, overflowed))
|
||||
})
|
||||
}
|
||||
@ -144,7 +144,7 @@ pub fn binary_op<'tcx>(
|
||||
fn normalize(val: PrimVal) -> PrimVal {
|
||||
if let PrimVal::Ptr(ptr) = val {
|
||||
if let Ok(bytes) = ptr.to_int() {
|
||||
return PrimVal::Bytes(bytes);
|
||||
return PrimVal::Bytes(bytes as u128);
|
||||
}
|
||||
}
|
||||
val
|
||||
@ -158,7 +158,7 @@ pub fn binary_op<'tcx>(
|
||||
if left_ptr.alloc_id == right_ptr.alloc_id {
|
||||
// If the pointers are into the same allocation, fall through to the more general
|
||||
// match later, which will do comparisons on the pointer offsets.
|
||||
(left_ptr.offset, right_ptr.offset)
|
||||
(left_ptr.offset as u128, right_ptr.offset as u128)
|
||||
} else {
|
||||
return Ok((unrelated_ptr_ops(bin_op, left_ptr, right_ptr)?, false));
|
||||
}
|
||||
@ -166,7 +166,7 @@ pub fn binary_op<'tcx>(
|
||||
|
||||
(PrimVal::Ptr(ptr), PrimVal::Bytes(bytes)) |
|
||||
(PrimVal::Bytes(bytes), PrimVal::Ptr(ptr)) => {
|
||||
return Ok((unrelated_ptr_ops(bin_op, ptr, Pointer::from_int(bytes))?, false));
|
||||
return Ok((unrelated_ptr_ops(bin_op, ptr, Pointer::from_int(bytes as u64))?, false));
|
||||
}
|
||||
|
||||
(PrimVal::Undef, _) | (_, PrimVal::Undef) => return Err(EvalError::ReadUndefBytes),
|
||||
@ -182,6 +182,7 @@ pub fn binary_op<'tcx>(
|
||||
I16 | U16 => 16,
|
||||
I32 | U32 => 32,
|
||||
I64 | U64 => 64,
|
||||
I128 | U128 => 128,
|
||||
_ => bug!("bad MIR: bitshift lhs is not integral"),
|
||||
};
|
||||
|
||||
@ -278,22 +279,25 @@ pub fn unary_op<'tcx>(
|
||||
let bytes = val.to_bytes()?;
|
||||
|
||||
let result_bytes = match (un_op, val_kind) {
|
||||
(Not, Bool) => !bytes_to_bool(bytes) as u64,
|
||||
(Not, Bool) => !bytes_to_bool(bytes) as u128,
|
||||
|
||||
(Not, U8) => !(bytes as u8) as u64,
|
||||
(Not, U16) => !(bytes as u16) as u64,
|
||||
(Not, U32) => !(bytes as u32) as u64,
|
||||
(Not, U64) => !bytes,
|
||||
(Not, U8) => !(bytes as u8) as u128,
|
||||
(Not, U16) => !(bytes as u16) as u128,
|
||||
(Not, U32) => !(bytes as u32) as u128,
|
||||
(Not, U64) => !(bytes as u64) as u128,
|
||||
(Not, U128) => !bytes,
|
||||
|
||||
(Not, I8) => !(bytes as i8) as u64,
|
||||
(Not, I16) => !(bytes as i16) as u64,
|
||||
(Not, I32) => !(bytes as i32) as u64,
|
||||
(Not, I64) => !(bytes as i64) as u64,
|
||||
(Not, I8) => !(bytes as i8) as u128,
|
||||
(Not, I16) => !(bytes as i16) as u128,
|
||||
(Not, I32) => !(bytes as i32) as u128,
|
||||
(Not, I64) => !(bytes as i64) as u128,
|
||||
(Not, I128) => !(bytes as i128) as u128,
|
||||
|
||||
(Neg, I8) => -(bytes as i8) as u64,
|
||||
(Neg, I16) => -(bytes as i16) as u64,
|
||||
(Neg, I32) => -(bytes as i32) as u64,
|
||||
(Neg, I64) => -(bytes as i64) as u64,
|
||||
(Neg, I8) => -(bytes as i8) as u128,
|
||||
(Neg, I16) => -(bytes as i16) as u128,
|
||||
(Neg, I32) => -(bytes as i32) as u128,
|
||||
(Neg, I64) => -(bytes as i64) as u128,
|
||||
(Neg, I128) => -(bytes as i128) as u128,
|
||||
|
||||
(Neg, F32) => f32_to_bytes(-bytes_to_f32(bytes)),
|
||||
(Neg, F64) => f64_to_bytes(-bytes_to_f64(bytes)),
|
||||
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let dest = self.force_allocation(dest)?;
|
||||
let discr_dest = (dest.to_ptr()).offset(discr_offset);
|
||||
|
||||
self.memory.write_uint(discr_dest, variant_index as u64, discr_size)?;
|
||||
self.memory.write_uint(discr_dest, variant_index as u128, discr_size)?;
|
||||
}
|
||||
|
||||
Layout::RawNullablePointer { nndiscr, .. } => {
|
||||
|
@ -45,8 +45,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
"arith_offset" => {
|
||||
let ptr = arg_vals[0].read_ptr(&self.memory)?;
|
||||
let offset = self.value_to_primval(arg_vals[1], isize)?.to_i64()?;
|
||||
let new_ptr = ptr.signed_offset(offset);
|
||||
let offset = self.value_to_primval(arg_vals[1], isize)?.to_i128()?;
|
||||
let new_ptr = ptr.signed_offset(offset as i64);
|
||||
self.write_primval(dest, PrimVal::Ptr(new_ptr), dest_ty)?;
|
||||
}
|
||||
|
||||
@ -260,7 +260,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
"min_align_of" => {
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_align = self.type_align(elem_ty)?;
|
||||
let align_val = PrimVal::from_u64(elem_align as u64);
|
||||
let align_val = PrimVal::from_u128(elem_align as u128);
|
||||
self.write_primval(dest, align_val, dest_ty)?;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let ty = substs.type_at(0);
|
||||
let layout = self.type_layout(ty)?;
|
||||
let align = layout.align(&self.tcx.data_layout).pref();
|
||||
let align_val = PrimVal::from_u64(align);
|
||||
let align_val = PrimVal::from_u128(align as u128);
|
||||
self.write_primval(dest, align_val, dest_ty)?;
|
||||
}
|
||||
|
||||
@ -289,7 +289,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let pointee_ty = substs.type_at(0);
|
||||
// FIXME: assuming here that type size is < i64::max_value()
|
||||
let pointee_size = self.type_size(pointee_ty)?.expect("cannot offset a pointer to an unsized type") as i64;
|
||||
let offset = self.value_to_primval(arg_vals[1], isize)?.to_i64()?;
|
||||
let offset = self.value_to_primval(arg_vals[1], isize)?.to_i128()? as i64;
|
||||
|
||||
let ptr = arg_vals[0].read_ptr(&self.memory)?;
|
||||
let result_ptr = ptr.signed_offset(offset * pointee_size);
|
||||
@ -310,13 +310,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
"powif32" => {
|
||||
let f = self.value_to_primval(arg_vals[0], f32)?.to_f32()?;
|
||||
let i = self.value_to_primval(arg_vals[1], i32)?.to_i64()?;
|
||||
let i = self.value_to_primval(arg_vals[1], i32)?.to_i128()?;
|
||||
self.write_primval(dest, PrimVal::from_f32(f.powi(i as i32)), dest_ty)?;
|
||||
}
|
||||
|
||||
"powif64" => {
|
||||
let f = self.value_to_primval(arg_vals[0], f64)?.to_f64()?;
|
||||
let i = self.value_to_primval(arg_vals[1], i32)?.to_i64()?;
|
||||
let i = self.value_to_primval(arg_vals[1], i32)?.to_i128()?;
|
||||
self.write_primval(dest, PrimVal::from_f64(f.powi(i as i32)), dest_ty)?;
|
||||
}
|
||||
|
||||
@ -336,21 +336,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
// `size_of_val` intrinsic, then change this back to
|
||||
// .expect("size_of intrinsic called on unsized value")
|
||||
// see https://github.com/rust-lang/rust/pull/37708
|
||||
let size = self.type_size(ty)?.unwrap_or(!0) as u64;
|
||||
self.write_primval(dest, PrimVal::from_u64(size), dest_ty)?;
|
||||
let size = self.type_size(ty)?.unwrap_or(!0) as u128;
|
||||
self.write_primval(dest, PrimVal::from_u128(size), dest_ty)?;
|
||||
}
|
||||
|
||||
"size_of_val" => {
|
||||
let ty = substs.type_at(0);
|
||||
let (size, _) = self.size_and_align_of_dst(ty, arg_vals[0])?;
|
||||
self.write_primval(dest, PrimVal::from_u64(size), dest_ty)?;
|
||||
self.write_primval(dest, PrimVal::from_u128(size as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
"min_align_of_val" |
|
||||
"align_of_val" => {
|
||||
let ty = substs.type_at(0);
|
||||
let (_, align) = self.size_and_align_of_dst(ty, arg_vals[0])?;
|
||||
self.write_primval(dest, PrimVal::from_u64(align), dest_ty)?;
|
||||
self.write_primval(dest, PrimVal::from_u128(align as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
"type_name" => {
|
||||
@ -362,7 +362,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
"type_id" => {
|
||||
let ty = substs.type_at(0);
|
||||
let n = self.tcx.type_id_hash(ty);
|
||||
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
|
||||
self.write_primval(dest, PrimVal::Bytes(n as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
"transmute" => {
|
||||
@ -514,14 +514,16 @@ fn numeric_intrinsic<'tcx>(
|
||||
|
||||
use value::PrimValKind::*;
|
||||
let result_bytes = match $kind {
|
||||
I8 => (bytes as i8).$method() as u64,
|
||||
U8 => (bytes as u8).$method() as u64,
|
||||
I16 => (bytes as i16).$method() as u64,
|
||||
U16 => (bytes as u16).$method() as u64,
|
||||
I32 => (bytes as i32).$method() as u64,
|
||||
U32 => (bytes as u32).$method() as u64,
|
||||
I64 => (bytes as i64).$method() as u64,
|
||||
U64 => bytes.$method() as u64,
|
||||
I8 => (bytes as i8).$method() as u128,
|
||||
U8 => (bytes as u8).$method() as u128,
|
||||
I16 => (bytes as i16).$method() as u128,
|
||||
U16 => (bytes as u16).$method() as u128,
|
||||
I32 => (bytes as i32).$method() as u128,
|
||||
U32 => (bytes as u32).$method() as u128,
|
||||
I64 => (bytes as i64).$method() as u128,
|
||||
U64 => (bytes as u64).$method() as u128,
|
||||
I128 => (bytes as i128).$method() as u128,
|
||||
U128 => bytes.$method() as u128,
|
||||
_ => bug!("invalid `{}` argument: {:?}", $name, val),
|
||||
};
|
||||
|
||||
|
@ -71,7 +71,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let adt_ty = self.lvalue_ty(discr);
|
||||
let discr_val = self.read_discriminant_value(adt_ptr, adt_ty)?;
|
||||
let matching = adt_def.variants.iter()
|
||||
.position(|v| discr_val == v.disr_val.to_u64_unchecked());
|
||||
.position(|v| discr_val == v.disr_val.to_u128_unchecked());
|
||||
|
||||
match matching {
|
||||
Some(i) => self.goto_block(targets[i]),
|
||||
@ -262,7 +262,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u64> {
|
||||
fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
|
||||
use rustc::ty::layout::Layout::*;
|
||||
let adt_layout = self.type_layout(adt_ty)?;
|
||||
trace!("read_discriminant_value {:?}", adt_layout);
|
||||
@ -275,13 +275,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
CEnum { discr, signed: true, .. } => {
|
||||
let discr_size = discr.size().bytes();
|
||||
self.memory.read_int(adt_ptr, discr_size)? as u64
|
||||
self.memory.read_int(adt_ptr, discr_size)? as u128
|
||||
}
|
||||
|
||||
RawNullablePointer { nndiscr, value } => {
|
||||
let discr_size = value.size(&self.tcx.data_layout).bytes();
|
||||
trace!("rawnullablepointer with size {}", discr_size);
|
||||
self.read_nonnull_discriminant_value(adt_ptr, nndiscr, discr_size)?
|
||||
self.read_nonnull_discriminant_value(adt_ptr, nndiscr as u128, discr_size)?
|
||||
}
|
||||
|
||||
StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
|
||||
@ -290,7 +290,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
trace!("struct wrapped nullable pointer type: {}", ty);
|
||||
// only the pointer part of a fat pointer is used for this space optimization
|
||||
let discr_size = self.type_size(ty)?.expect("bad StructWrappedNullablePointer discrfield");
|
||||
self.read_nonnull_discriminant_value(nonnull, nndiscr, discr_size)?
|
||||
self.read_nonnull_discriminant_value(nonnull, nndiscr as u128, discr_size)?
|
||||
}
|
||||
|
||||
// The discriminant_value intrinsic returns 0 for non-sum types.
|
||||
@ -301,7 +301,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Ok(discr_val)
|
||||
}
|
||||
|
||||
fn read_nonnull_discriminant_value(&self, ptr: Pointer, nndiscr: u64, discr_size: u64) -> EvalResult<'tcx, u64> {
|
||||
fn read_nonnull_discriminant_value(&self, ptr: Pointer, nndiscr: u128, discr_size: u64) -> EvalResult<'tcx, u128> {
|
||||
let not_null = match self.memory.read_uint(ptr, discr_size) {
|
||||
Ok(0) => false,
|
||||
Ok(_) | Err(EvalError::ReadPointerAsBytes) => true,
|
||||
@ -366,13 +366,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
use std::cmp::Ordering::*;
|
||||
match left_bytes.cmp(right_bytes) {
|
||||
Less => -1,
|
||||
Less => -1i8,
|
||||
Equal => 0,
|
||||
Greater => 1,
|
||||
}
|
||||
};
|
||||
|
||||
self.write_primval(dest, PrimVal::Bytes(result as u64), dest_ty)?;
|
||||
self.write_primval(dest, PrimVal::Bytes(result as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
"memchr" => {
|
||||
@ -641,8 +641,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
adt_def.struct_variant().fields.iter().zip(&variant.offsets)
|
||||
},
|
||||
Layout::General { ref variants, .. } => {
|
||||
let discr_val = self.read_discriminant_value(adt_ptr, ty)?;
|
||||
match adt_def.variants.iter().position(|v| discr_val == v.disr_val.to_u64_unchecked()) {
|
||||
let discr_val = self.read_discriminant_value(adt_ptr, ty)? as u128;
|
||||
match adt_def.variants.iter().position(|v| discr_val == v.disr_val.to_u128_unchecked()) {
|
||||
// start at offset 1, to skip over the discriminant
|
||||
Some(i) => adt_def.variants[i].fields.iter().zip(&variants[i].offsets[1..]),
|
||||
None => return Err(EvalError::InvalidDiscriminant),
|
||||
@ -650,8 +650,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
},
|
||||
Layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } => {
|
||||
let discr = self.read_discriminant_value(adt_ptr, ty)?;
|
||||
if discr == nndiscr {
|
||||
assert_eq!(discr as usize as u64, discr);
|
||||
if discr == nndiscr as u128 {
|
||||
assert_eq!(discr as usize as u128, discr);
|
||||
adt_def.variants[discr as usize].fields.iter().zip(&nonnull.offsets)
|
||||
} else {
|
||||
// FIXME: the zst variant might contain zst types that impl Drop
|
||||
@ -660,8 +660,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
},
|
||||
Layout::RawNullablePointer { nndiscr, .. } => {
|
||||
let discr = self.read_discriminant_value(adt_ptr, ty)?;
|
||||
if discr == nndiscr {
|
||||
assert_eq!(discr as usize as u64, discr);
|
||||
if discr == nndiscr as u128 {
|
||||
assert_eq!(discr as usize as u128, discr);
|
||||
assert_eq!(adt_def.variants[discr as usize].fields.len(), 1);
|
||||
let field_ty = &adt_def.variants[discr as usize].fields[0];
|
||||
let field_ty = monomorphize_field_ty(self.tcx, field_ty, substs);
|
||||
|
71
src/value.rs
71
src/value.rs
@ -6,23 +6,23 @@ use std::mem::transmute;
|
||||
use error::{EvalError, EvalResult};
|
||||
use memory::{Memory, Pointer};
|
||||
|
||||
pub(super) fn bytes_to_f32(bytes: u64) -> f32 {
|
||||
pub(super) fn bytes_to_f32(bytes: u128) -> f32 {
|
||||
unsafe { transmute::<u32, f32>(bytes as u32) }
|
||||
}
|
||||
|
||||
pub(super) fn bytes_to_f64(bytes: u64) -> f64 {
|
||||
unsafe { transmute::<u64, f64>(bytes) }
|
||||
pub(super) fn bytes_to_f64(bytes: u128) -> f64 {
|
||||
unsafe { transmute::<u64, f64>(bytes as u64) }
|
||||
}
|
||||
|
||||
pub(super) fn f32_to_bytes(f: f32) -> u64 {
|
||||
unsafe { transmute::<f32, u32>(f) as u64 }
|
||||
pub(super) fn f32_to_bytes(f: f32) -> u128 {
|
||||
unsafe { transmute::<f32, u32>(f) as u128 }
|
||||
}
|
||||
|
||||
pub(super) fn f64_to_bytes(f: f64) -> u64 {
|
||||
unsafe { transmute::<f64, u64>(f) }
|
||||
pub(super) fn f64_to_bytes(f: f64) -> u128 {
|
||||
unsafe { transmute::<f64, u64>(f) as u128 }
|
||||
}
|
||||
|
||||
pub(super) fn bytes_to_bool(n: u64) -> bool {
|
||||
pub(super) fn bytes_to_bool(n: u128) -> bool {
|
||||
// FIXME(solson): Can we reach here due to user error?
|
||||
debug_assert!(n == 0 || n == 1, "bytes interpreted as bool were {}", n);
|
||||
n & 1 == 1
|
||||
@ -50,7 +50,7 @@ pub enum Value {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum PrimVal {
|
||||
/// The raw bytes of a simple value.
|
||||
Bytes(u64),
|
||||
Bytes(u128),
|
||||
|
||||
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
|
||||
/// relocations, but a `PrimVal` is only large enough to contain one, so we just represent the
|
||||
@ -64,8 +64,8 @@ pub enum PrimVal {
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PrimValKind {
|
||||
I8, I16, I32, I64,
|
||||
U8, U16, U32, U64,
|
||||
I8, I16, I32, I64, I128,
|
||||
U8, U16, U32, U64, U128,
|
||||
F32, F64,
|
||||
Bool,
|
||||
Char,
|
||||
@ -109,7 +109,9 @@ impl<'a, 'tcx: 'a> Value {
|
||||
Ok((ptr, len))
|
||||
},
|
||||
ByValPair(ptr, val) => {
|
||||
Ok((ptr.to_ptr()?, val.to_u64()?))
|
||||
let len = val.to_u128()?;
|
||||
assert_eq!(len as u64 as u128, len);
|
||||
Ok((ptr.to_ptr()?, len as u64))
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
@ -117,12 +119,12 @@ impl<'a, 'tcx: 'a> Value {
|
||||
}
|
||||
|
||||
impl<'tcx> PrimVal {
|
||||
pub fn from_u64(n: u64) -> Self {
|
||||
pub fn from_u128(n: u128) -> Self {
|
||||
PrimVal::Bytes(n)
|
||||
}
|
||||
|
||||
pub fn from_i64(n: i64) -> Self {
|
||||
PrimVal::Bytes(n as u64)
|
||||
pub fn from_i128(n: i128) -> Self {
|
||||
PrimVal::Bytes(n as u128)
|
||||
}
|
||||
|
||||
pub fn from_f32(f: f32) -> Self {
|
||||
@ -134,35 +136,56 @@ impl<'tcx> PrimVal {
|
||||
}
|
||||
|
||||
pub fn from_bool(b: bool) -> Self {
|
||||
PrimVal::Bytes(b as u64)
|
||||
PrimVal::Bytes(b as u128)
|
||||
}
|
||||
|
||||
pub fn from_char(c: char) -> Self {
|
||||
PrimVal::Bytes(c as u64)
|
||||
PrimVal::Bytes(c as u128)
|
||||
}
|
||||
|
||||
pub fn to_bytes(self) -> EvalResult<'tcx, u64> {
|
||||
pub fn to_bytes(self) -> EvalResult<'tcx, u128> {
|
||||
match self {
|
||||
PrimVal::Bytes(b) => Ok(b),
|
||||
PrimVal::Ptr(p) => p.to_int(),
|
||||
PrimVal::Ptr(p) => p.to_int().map(|b| b as u128),
|
||||
PrimVal::Undef => Err(EvalError::ReadUndefBytes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> {
|
||||
match self {
|
||||
PrimVal::Bytes(b) => Ok(Pointer::from_int(b)),
|
||||
PrimVal::Bytes(b) => Ok(Pointer::from_int(b as u64)),
|
||||
PrimVal::Ptr(p) => Ok(p),
|
||||
PrimVal::Undef => Err(EvalError::ReadUndefBytes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u64(self) -> EvalResult<'tcx, u64> {
|
||||
pub fn to_u128(self) -> EvalResult<'tcx, u128> {
|
||||
self.to_bytes()
|
||||
}
|
||||
|
||||
pub fn to_u64(self) -> EvalResult<'tcx, u64> {
|
||||
self.to_bytes().map(|b| {
|
||||
assert_eq!(b as u64 as u128, b);
|
||||
b as u64
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_i32(self) -> EvalResult<'tcx, i32> {
|
||||
self.to_bytes().map(|b| {
|
||||
assert_eq!(b as i32 as u128, b);
|
||||
b as i32
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_i128(self) -> EvalResult<'tcx, i128> {
|
||||
self.to_bytes().map(|b| b as i128)
|
||||
}
|
||||
|
||||
pub fn to_i64(self) -> EvalResult<'tcx, i64> {
|
||||
self.to_bytes().map(|b| b as i64)
|
||||
self.to_bytes().map(|b| {
|
||||
assert_eq!(b as i64 as u128, b);
|
||||
b as i64
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_f32(self) -> EvalResult<'tcx, f32> {
|
||||
@ -186,7 +209,7 @@ impl PrimValKind {
|
||||
pub fn is_int(self) -> bool {
|
||||
use self::PrimValKind::*;
|
||||
match self {
|
||||
I8 | I16 | I32 | I64 | U8 | U16 | U32 | U64 => true,
|
||||
I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -197,6 +220,7 @@ impl PrimValKind {
|
||||
2 => PrimValKind::U16,
|
||||
4 => PrimValKind::U32,
|
||||
8 => PrimValKind::U64,
|
||||
16 => PrimValKind::U128,
|
||||
_ => bug!("can't make uint with size {}", size),
|
||||
}
|
||||
}
|
||||
@ -207,6 +231,7 @@ impl PrimValKind {
|
||||
2 => PrimValKind::I16,
|
||||
4 => PrimValKind::I32,
|
||||
8 => PrimValKind::I64,
|
||||
16 => PrimValKind::I128,
|
||||
_ => bug!("can't make int with size {}", size),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user