1
Fork 0

rustup (i128)

This commit is contained in:
Oliver Schneider 2017-01-12 08:28:42 +01:00
parent d6e35fe46f
commit 3a658e09e8
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
14 changed files with 193 additions and 148 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
tex/*/out tex/*/out
*.dot *.dot
*.mir *.mir
*.rs.bk

8
Cargo.lock generated
View file

@ -2,7 +2,7 @@
name = "miri" name = "miri"
version = "0.1.0" version = "0.1.0"
dependencies = [ 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)", "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)", "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)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -19,8 +19,8 @@ dependencies = [
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "0.4.2" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/quininer/byteorder.git?branch=i128#ef51df297aa833d0b6639aae328a95597fc07d75"
[[package]] [[package]]
name = "compiletest_rs" name = "compiletest_rs"
@ -136,7 +136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [metadata]
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "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 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 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" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"

View file

@ -15,7 +15,8 @@ test = false
test = false test = false
[dependencies] [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" env_logger = "0.3.3"
log = "0.3.6" log = "0.3.6"
log_settings = "0.1.1" log_settings = "0.1.1"

View file

@ -1,4 +1,4 @@
#![feature(rustc_private)] #![feature(rustc_private, i128_type)]
extern crate getopts; extern crate getopts;
extern crate miri; extern crate miri;
@ -51,7 +51,7 @@ fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits
let mut limits = miri::ResourceLimits::default(); let mut limits = miri::ResourceLimits::default();
let krate = state.hir_crate.as_ref().unwrap(); let krate = state.hir_crate.as_ref().unwrap();
let err_msg = "miri attributes need to be in the form `miri(key = value)`"; 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 { match lit.node {
syntax::ast::LitKind::Int(i, _) => i, syntax::ast::LitKind::Int(i, _) => i,
_ => state.session.span_fatal(lit.span, "expected an integer literal"), _ => 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 NestedMetaItemKind::MetaItem(ref inner) = item.node {
if let MetaItemKind::NameValue(ref value) = inner.node { if let MetaItemKind::NameValue(ref value) = inner.node {
match &inner.name().as_str()[..] { match &inner.name().as_str()[..] {
"memory_size" => limits.memory_size = extract_int(value), "memory_size" => limits.memory_size = extract_int(value) as u64,
"step_limit" => limits.step_limit = extract_int(value), "step_limit" => limits.step_limit = extract_int(value) as u64,
"stack_limit" => limits.stack_limit = extract_int(value) as usize, "stack_limit" => limits.stack_limit = extract_int(value) as usize,
_ => state.session.span_err(item.span, "unknown miri attribute"), _ => state.session.span_err(item.span, "unknown miri attribute"),
} }

View file

@ -20,34 +20,36 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
F32 => self.cast_float(val.to_f32()? as f64, dest_ty), F32 => self.cast_float(val.to_f32()? as f64, dest_ty),
F64 => self.cast_float(val.to_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), FnPtr | Ptr => self.cast_ptr(val.to_ptr()?, dest_ty),
} }
} }
fn cast_signed_int(&self, val: i64, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> { fn cast_signed_int(&self, val: i128, ty: ty::Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
self.cast_int(val as u64, ty, val < 0) 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::*; use rustc::ty::TypeVariants::*;
match ty.sty { match ty.sty {
TyBool if v == 0 => Ok(PrimVal::from_bool(false)), TyBool if v == 0 => Ok(PrimVal::from_bool(false)),
TyBool if v == 1 => Ok(PrimVal::from_bool(true)), TyBool if v == 1 => Ok(PrimVal::from_bool(true)),
TyBool => Err(EvalError::InvalidBool), TyBool => Err(EvalError::InvalidBool),
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i64 as i8 as u64)), TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i128 as i8 as u128)),
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i64 as i16 as u64)), TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i128 as i16 as u128)),
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i64 as i32 as u64)), TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i128 as i32 as u128)),
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i64 as i64 as u64)), 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::U8) => Ok(PrimVal::Bytes(v as u8 as u128)),
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u64)), TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u128)),
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u64)), TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u128)),
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v)), TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v as u64 as u128)),
TyUint(UintTy::U128) => Ok(PrimVal::Bytes(v)),
TyInt(IntTy::Is) => { TyInt(IntTy::Is) => {
let int_ty = self.tcx.sess.target.int_type; 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) 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::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)), 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)), 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))), _ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
} }
@ -80,9 +82,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
match ty.sty { match ty.sty {
// Casting negative floats to unsigned integers yields zero. // Casting negative floats to unsigned integers yields zero.
TyUint(_) if val < 0.0 => self.cast_int(0, ty, false), 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::F64) => Ok(PrimVal::from_f64(val)),
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)), TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(val as f32)),

View file

@ -31,7 +31,7 @@ pub enum EvalError<'tcx> {
ExecuteMemory, ExecuteMemory,
ArrayIndexOutOfBounds(Span, u64, u64), ArrayIndexOutOfBounds(Span, u64, u64),
Math(Span, ConstMathErr), Math(Span, ConstMathErr),
InvalidChar(u64), InvalidChar(u128),
OutOfMemory { OutOfMemory {
allocation_size: u64, allocation_size: u64,
memory_size: u64, memory_size: u64,

View file

@ -169,7 +169,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let ptr = self.memory.allocate(s.len() as u64, 1)?; let ptr = self.memory.allocate(s.len() as u64, 1)?;
self.memory.write_bytes(ptr, s.as_bytes())?; self.memory.write_bytes(ptr, s.as_bytes())?;
self.memory.freeze(ptr.alloc_id)?; 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> { 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; use rustc_const_math::ConstFloat;
let primval = match *const_val { 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::F32(f)) => PrimVal::from_f32(f),
Float(ConstFloat::F64(f)) => PrimVal::from_f64(f), Float(ConstFloat::F64(f)) => PrimVal::from_f64(f),
@ -429,7 +429,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
General { discr, ref variants, .. } => { General { discr, ref variants, .. } => {
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind { 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_size = discr.size().bytes();
let discr_offset = variants[variant].offsets[0].bytes(); let discr_offset = variants[variant].offsets[0].bytes();
@ -497,7 +497,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
CEnum { .. } => { CEnum { .. } => {
assert_eq!(operands.len(), 0); assert_eq!(operands.len(), 0);
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind { 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)?; self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
} else { } else {
bug!("tried to assign {:?} to Layout::CEnum", kind); 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 src = self.eval_lvalue(lvalue)?;
let ty = self.lvalue_ty(lvalue); let ty = self.lvalue_ty(lvalue);
let (_, len) = src.elem_ty_and_len(ty); 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) => { Ref(_, _, ref lvalue) => {
@ -566,7 +566,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let val = match extra { let val = match extra {
LvalueExtra::None => Value::ByVal(ptr), 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::Vtable(vtable) => Value::ByValPair(ptr, PrimVal::Ptr(vtable)),
LvalueExtra::DowncastVariant(..) => LvalueExtra::DowncastVariant(..) =>
bug!("attempted to take a reference to an enum downcast lvalue"), bug!("attempted to take a reference to an enum downcast lvalue"),
@ -1028,6 +1028,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
I16 => 2, I16 => 2,
I32 => 4, I32 => 4,
I64 => 8, I64 => 8,
I128 => 16,
Is => self.memory.pointer_size(), Is => self.memory.pointer_size(),
}; };
PrimValKind::from_int_size(size) PrimValKind::from_int_size(size)
@ -1040,6 +1041,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
U16 => 2, U16 => 2,
U32 => 4, U32 => 4,
U64 => 8, U64 => 8,
U128 => 16,
Us => self.memory.pointer_size(), Us => self.memory.pointer_size(),
}; };
PrimValKind::from_uint_size(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::TyBool if val.to_bytes()? > 1 => Err(EvalError::InvalidBool),
ty::TyChar if ::std::char::from_u32(val.to_bytes()? as u32).is_none() 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(()), _ => Ok(()),
} }
@ -1115,7 +1117,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let c = self.memory.read_uint(ptr, 4)? as u32; let c = self.memory.read_uint(ptr, 4)? as u32;
match ::std::char::from_u32(c) { match ::std::char::from_u32(c) {
Some(ch) => PrimVal::from_char(ch), 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, I16 => 2,
I32 => 4, I32 => 4,
I64 => 8, I64 => 8,
I128 => 16,
Is => self.memory.pointer_size(), 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) => { ty::TyUint(uint_ty) => {
@ -1138,9 +1141,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
U16 => 2, U16 => 2,
U32 => 4, U32 => 4,
U64 => 8, U64 => 8,
U128 => 16,
Us => self.memory.pointer_size(), 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)?), 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 { let extra = match self.tcx.struct_tail(ty).sty {
ty::TyDynamic(..) => PrimVal::Ptr(self.memory.read_ptr(extra)?), ty::TyDynamic(..) => PrimVal::Ptr(self.memory.read_ptr(extra)?),
ty::TySlice(..) | 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), _ => bug!("unsized primval ptr read from {:?}", ty),
}; };
return Ok(Some(Value::ByValPair(PrimVal::Ptr(p), extra))); 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)? { if let CEnum { discr, signed, .. } = *self.type_layout(ty)? {
let size = discr.size().bytes(); let size = discr.size().bytes();
if signed { if signed {
PrimVal::from_i64(self.memory.read_int(ptr, size)?) PrimVal::from_i128(self.memory.read_int(ptr, size)?)
} else { } else {
PrimVal::from_u64(self.memory.read_uint(ptr, size)?) PrimVal::from_u128(self.memory.read_uint(ptr, size)?)
} }
} else { } else {
return Ok(None); return Ok(None);
@ -1220,7 +1224,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) { match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
(&ty::TyArray(_, length), &ty::TySlice(_)) => { (&ty::TyArray(_, length), &ty::TySlice(_)) => {
let ptr = src.read_ptr(&self.memory)?; 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); let ptr = PrimVal::Ptr(ptr);
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?; self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?;
} }
@ -1454,6 +1458,7 @@ impl IntegerExt for layout::Integer {
I16 => Size::from_bits(16), I16 => Size::from_bits(16),
I32 => Size::from_bits(32), I32 => Size::from_bits(32),
I64 => Size::from_bits(64), I64 => Size::from_bits(64),
I128 => Size::from_bits(128),
} }
} }
} }

View file

@ -4,6 +4,7 @@
collections_bound, collections_bound,
pub_restricted, pub_restricted,
rustc_private, rustc_private,
i128_type,
)] )]
// From rustc. // From rustc.

View file

@ -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::Bound::{Included, Excluded};
use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque}; 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::hir::def_id::DefId;
use rustc::ty::{self, BareFnTy, ClosureTy, ClosureSubsts, TyCtxt}; use rustc::ty::{self, BareFnTy, ClosureTy, ClosureSubsts, TyCtxt};
@ -567,6 +567,8 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
let endianess = self.endianess(); let endianess = self.endianess();
let bytes = self.get_bytes_unchecked(ptr, size)?; let bytes = self.get_bytes_unchecked(ptr, size)?;
let offset = read_target_uint(endianess, bytes).unwrap(); 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)?; let alloc = self.get(ptr.alloc_id)?;
match alloc.relocations.get(&ptr.offset) { match alloc.relocations.get(&ptr.offset) {
Some(&alloc_id) => Ok(Pointer::new(alloc_id, 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 // 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. // than fits in an integer of the requested size.
let mask = match size { let mask = match size {
1 => 0xff, 1 => !0u8 as u128,
2 => 0xffff, 2 => !0u16 as u128,
4 => 0xffffffff, 4 => !0u32 as u128,
8 => 0xffffffffffffffff, 8 => !0u64 as u128,
16 => !0,
_ => bug!("unexpected PrimVal::Bytes size"), _ => bug!("unexpected PrimVal::Bytes size"),
}; };
self.write_uint(dest, bytes & mask, 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()), 2 => Ok(self.layout.i16_align.abi()),
4 => Ok(self.layout.i32_align.abi()), 4 => Ok(self.layout.i32_align.abi()),
8 => Ok(self.layout.i64_align.abi()), 8 => Ok(self.layout.i64_align.abi()),
16 => Ok(self.layout.i128_align.abi()),
_ => bug!("bad integer size: {}", size), _ => 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)?; let align = self.int_align(size)?;
self.get_bytes(ptr, size, align).map(|b| read_target_int(self.endianess(), b).unwrap()) 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 align = self.int_align(size)?;
let endianess = self.endianess(); let endianess = self.endianess();
let b = self.get_bytes_mut(ptr, size, align)?; let b = self.get_bytes_mut(ptr, size, align)?;
@ -647,12 +651,12 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
Ok(()) 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)?; let align = self.int_align(size)?;
self.get_bytes(ptr, size, align).map(|b| read_target_uint(self.endianess(), b).unwrap()) 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 align = self.int_align(size)?;
let endianess = self.endianess(); let endianess = self.endianess();
let b = self.get_bytes_mut(ptr, size, align)?; 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> { 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, ()> { pub fn write_isize(&mut self, ptr: Pointer, n: i64) -> EvalResult<'tcx, ()> {
let size = self.pointer_size(); 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> { 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, ()> { pub fn write_usize(&mut self, ptr: Pointer, n: u64) -> EvalResult<'tcx, ()> {
let size = self.pointer_size(); 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, ()> { 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 // 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(); let len = target.len();
match endianess { match endianess {
layout::Endian::Little => target.write_uint::<LittleEndian>(data, len), layout::Endian::Little => target.write_uint128::<LittleEndian>(data, len),
layout::Endian::Big => target.write_uint::<BigEndian>(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(); let len = target.len();
match endianess { match endianess {
layout::Endian::Little => target.write_int::<LittleEndian>(data, len), layout::Endian::Little => target.write_int128::<LittleEndian>(data, len),
layout::Endian::Big => target.write_int::<BigEndian>(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 { match endianess {
layout::Endian::Little => source.read_uint::<LittleEndian>(source.len()), layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
layout::Endian::Big => source.read_uint::<BigEndian>(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 { match endianess {
layout::Endian::Little => source.read_int::<LittleEndian>(source.len()), layout::Endian::Little => source.read_int128::<LittleEndian>(source.len()),
layout::Endian::Big => source.read_int::<BigEndian>(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 // 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 { match endianess {
layout::Endian::Little => target.write_f32::<LittleEndian>(data), layout::Endian::Little => target.write_f32::<LittleEndian>(data),
layout::Endian::Big => target.write_f32::<BigEndian>(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 { match endianess {
layout::Endian::Little => target.write_f64::<LittleEndian>(data), layout::Endian::Little => target.write_f64::<LittleEndian>(data),
layout::Endian::Big => target.write_f64::<BigEndian>(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 { match endianess {
layout::Endian::Little => source.read_f32::<LittleEndian>(), layout::Endian::Little => source.read_f32::<LittleEndian>(),
layout::Endian::Big => source.read_f32::<BigEndian>(), 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 { match endianess {
layout::Endian::Little => source.read_f64::<LittleEndian>(), layout::Endian::Little => source.read_f64::<LittleEndian>(),
layout::Endian::Big => source.read_f64::<BigEndian>(), layout::Endian::Big => source.read_f64::<BigEndian>(),

View file

@ -66,7 +66,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
macro_rules! overflow { macro_rules! overflow {
($op:ident, $l:expr, $r:expr) => ({ ($op:ident, $l:expr, $r:expr) => ({
let (val, overflowed) = $l.$op($r); let (val, overflowed) = $l.$op($r);
let primval = PrimVal::Bytes(val as u64); let primval = PrimVal::Bytes(val as u128);
Ok((primval, overflowed)) Ok((primval, overflowed))
}) })
} }
@ -144,7 +144,7 @@ pub fn binary_op<'tcx>(
fn normalize(val: PrimVal) -> PrimVal { fn normalize(val: PrimVal) -> PrimVal {
if let PrimVal::Ptr(ptr) = val { if let PrimVal::Ptr(ptr) = val {
if let Ok(bytes) = ptr.to_int() { if let Ok(bytes) = ptr.to_int() {
return PrimVal::Bytes(bytes); return PrimVal::Bytes(bytes as u128);
} }
} }
val val
@ -158,7 +158,7 @@ pub fn binary_op<'tcx>(
if left_ptr.alloc_id == right_ptr.alloc_id { if left_ptr.alloc_id == right_ptr.alloc_id {
// If the pointers are into the same allocation, fall through to the more general // If the pointers are into the same allocation, fall through to the more general
// match later, which will do comparisons on the pointer offsets. // 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 { } else {
return Ok((unrelated_ptr_ops(bin_op, left_ptr, right_ptr)?, false)); 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::Ptr(ptr), PrimVal::Bytes(bytes)) |
(PrimVal::Bytes(bytes), PrimVal::Ptr(ptr)) => { (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), (PrimVal::Undef, _) | (_, PrimVal::Undef) => return Err(EvalError::ReadUndefBytes),
@ -182,6 +182,7 @@ pub fn binary_op<'tcx>(
I16 | U16 => 16, I16 | U16 => 16,
I32 | U32 => 32, I32 | U32 => 32,
I64 | U64 => 64, I64 | U64 => 64,
I128 | U128 => 128,
_ => bug!("bad MIR: bitshift lhs is not integral"), _ => bug!("bad MIR: bitshift lhs is not integral"),
}; };
@ -278,22 +279,25 @@ pub fn unary_op<'tcx>(
let bytes = val.to_bytes()?; let bytes = val.to_bytes()?;
let result_bytes = match (un_op, val_kind) { 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, U8) => !(bytes as u8) as u128,
(Not, U16) => !(bytes as u16) as u64, (Not, U16) => !(bytes as u16) as u128,
(Not, U32) => !(bytes as u32) as u64, (Not, U32) => !(bytes as u32) as u128,
(Not, U64) => !bytes, (Not, U64) => !(bytes as u64) as u128,
(Not, U128) => !bytes,
(Not, I8) => !(bytes as i8) as u64, (Not, I8) => !(bytes as i8) as u128,
(Not, I16) => !(bytes as i16) as u64, (Not, I16) => !(bytes as i16) as u128,
(Not, I32) => !(bytes as i32) as u64, (Not, I32) => !(bytes as i32) as u128,
(Not, I64) => !(bytes as i64) as u64, (Not, I64) => !(bytes as i64) as u128,
(Not, I128) => !(bytes as i128) as u128,
(Neg, I8) => -(bytes as i8) as u64, (Neg, I8) => -(bytes as i8) as u128,
(Neg, I16) => -(bytes as i16) as u64, (Neg, I16) => -(bytes as i16) as u128,
(Neg, I32) => -(bytes as i32) as u64, (Neg, I32) => -(bytes as i32) as u128,
(Neg, I64) => -(bytes as i64) as u64, (Neg, I64) => -(bytes as i64) as u128,
(Neg, I128) => -(bytes as i128) as u128,
(Neg, F32) => f32_to_bytes(-bytes_to_f32(bytes)), (Neg, F32) => f32_to_bytes(-bytes_to_f32(bytes)),
(Neg, F64) => f64_to_bytes(-bytes_to_f64(bytes)), (Neg, F64) => f64_to_bytes(-bytes_to_f64(bytes)),

View file

@ -101,7 +101,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let dest = self.force_allocation(dest)?; let dest = self.force_allocation(dest)?;
let discr_dest = (dest.to_ptr()).offset(discr_offset); 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, .. } => { Layout::RawNullablePointer { nndiscr, .. } => {

View file

@ -45,8 +45,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"arith_offset" => { "arith_offset" => {
let ptr = arg_vals[0].read_ptr(&self.memory)?; let ptr = arg_vals[0].read_ptr(&self.memory)?;
let offset = self.value_to_primval(arg_vals[1], isize)?.to_i64()?; let offset = self.value_to_primval(arg_vals[1], isize)?.to_i128()?;
let new_ptr = ptr.signed_offset(offset); let new_ptr = ptr.signed_offset(offset as i64);
self.write_primval(dest, PrimVal::Ptr(new_ptr), dest_ty)?; self.write_primval(dest, PrimVal::Ptr(new_ptr), dest_ty)?;
} }
@ -260,7 +260,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"min_align_of" => { "min_align_of" => {
let elem_ty = substs.type_at(0); let elem_ty = substs.type_at(0);
let elem_align = self.type_align(elem_ty)?; 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)?; 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 ty = substs.type_at(0);
let layout = self.type_layout(ty)?; let layout = self.type_layout(ty)?;
let align = layout.align(&self.tcx.data_layout).pref(); 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)?; 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); let pointee_ty = substs.type_at(0);
// FIXME: assuming here that type size is < i64::max_value() // 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 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 ptr = arg_vals[0].read_ptr(&self.memory)?;
let result_ptr = ptr.signed_offset(offset * pointee_size); let result_ptr = ptr.signed_offset(offset * pointee_size);
@ -310,13 +310,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"powif32" => { "powif32" => {
let f = self.value_to_primval(arg_vals[0], f32)?.to_f32()?; 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)?; self.write_primval(dest, PrimVal::from_f32(f.powi(i as i32)), dest_ty)?;
} }
"powif64" => { "powif64" => {
let f = self.value_to_primval(arg_vals[0], f64)?.to_f64()?; 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)?; 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 // `size_of_val` intrinsic, then change this back to
// .expect("size_of intrinsic called on unsized value") // .expect("size_of intrinsic called on unsized value")
// see https://github.com/rust-lang/rust/pull/37708 // see https://github.com/rust-lang/rust/pull/37708
let size = self.type_size(ty)?.unwrap_or(!0) as u64; let size = self.type_size(ty)?.unwrap_or(!0) as u128;
self.write_primval(dest, PrimVal::from_u64(size), dest_ty)?; self.write_primval(dest, PrimVal::from_u128(size), dest_ty)?;
} }
"size_of_val" => { "size_of_val" => {
let ty = substs.type_at(0); let ty = substs.type_at(0);
let (size, _) = self.size_and_align_of_dst(ty, arg_vals[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" | "min_align_of_val" |
"align_of_val" => { "align_of_val" => {
let ty = substs.type_at(0); let ty = substs.type_at(0);
let (_, align) = self.size_and_align_of_dst(ty, arg_vals[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" => { "type_name" => {
@ -362,7 +362,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"type_id" => { "type_id" => {
let ty = substs.type_at(0); let ty = substs.type_at(0);
let n = self.tcx.type_id_hash(ty); 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" => { "transmute" => {
@ -514,14 +514,16 @@ fn numeric_intrinsic<'tcx>(
use value::PrimValKind::*; use value::PrimValKind::*;
let result_bytes = match $kind { let result_bytes = match $kind {
I8 => (bytes as i8).$method() as u64, I8 => (bytes as i8).$method() as u128,
U8 => (bytes as u8).$method() as u64, U8 => (bytes as u8).$method() as u128,
I16 => (bytes as i16).$method() as u64, I16 => (bytes as i16).$method() as u128,
U16 => (bytes as u16).$method() as u64, U16 => (bytes as u16).$method() as u128,
I32 => (bytes as i32).$method() as u64, I32 => (bytes as i32).$method() as u128,
U32 => (bytes as u32).$method() as u64, U32 => (bytes as u32).$method() as u128,
I64 => (bytes as i64).$method() as u64, I64 => (bytes as i64).$method() as u128,
U64 => bytes.$method() as u64, U64 => (bytes as u64).$method() as u128,
I128 => (bytes as i128).$method() as u128,
U128 => bytes.$method() as u128,
_ => bug!("invalid `{}` argument: {:?}", $name, val), _ => bug!("invalid `{}` argument: {:?}", $name, val),
}; };

View file

@ -71,7 +71,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let adt_ty = self.lvalue_ty(discr); let adt_ty = self.lvalue_ty(discr);
let discr_val = self.read_discriminant_value(adt_ptr, adt_ty)?; let discr_val = self.read_discriminant_value(adt_ptr, adt_ty)?;
let matching = adt_def.variants.iter() 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 { match matching {
Some(i) => self.goto_block(targets[i]), 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::*; use rustc::ty::layout::Layout::*;
let adt_layout = self.type_layout(adt_ty)?; let adt_layout = self.type_layout(adt_ty)?;
trace!("read_discriminant_value {:?}", adt_layout); trace!("read_discriminant_value {:?}", adt_layout);
@ -275,13 +275,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
CEnum { discr, signed: true, .. } => { CEnum { discr, signed: true, .. } => {
let discr_size = discr.size().bytes(); 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 } => { RawNullablePointer { nndiscr, value } => {
let discr_size = value.size(&self.tcx.data_layout).bytes(); let discr_size = value.size(&self.tcx.data_layout).bytes();
trace!("rawnullablepointer with size {}", discr_size); 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, .. } => { StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
@ -290,7 +290,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
trace!("struct wrapped nullable pointer type: {}", ty); trace!("struct wrapped nullable pointer type: {}", ty);
// only the pointer part of a fat pointer is used for this space optimization // 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"); 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. // The discriminant_value intrinsic returns 0 for non-sum types.
@ -301,7 +301,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Ok(discr_val) 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) { let not_null = match self.memory.read_uint(ptr, discr_size) {
Ok(0) => false, Ok(0) => false,
Ok(_) | Err(EvalError::ReadPointerAsBytes) => true, Ok(_) | Err(EvalError::ReadPointerAsBytes) => true,
@ -366,13 +366,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
use std::cmp::Ordering::*; use std::cmp::Ordering::*;
match left_bytes.cmp(right_bytes) { match left_bytes.cmp(right_bytes) {
Less => -1, Less => -1i8,
Equal => 0, Equal => 0,
Greater => 1, 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" => { "memchr" => {
@ -641,8 +641,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
adt_def.struct_variant().fields.iter().zip(&variant.offsets) adt_def.struct_variant().fields.iter().zip(&variant.offsets)
}, },
Layout::General { ref variants, .. } => { Layout::General { ref variants, .. } => {
let discr_val = self.read_discriminant_value(adt_ptr, ty)?; 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_u64_unchecked()) { match adt_def.variants.iter().position(|v| discr_val == v.disr_val.to_u128_unchecked()) {
// start at offset 1, to skip over the discriminant // start at offset 1, to skip over the discriminant
Some(i) => adt_def.variants[i].fields.iter().zip(&variants[i].offsets[1..]), Some(i) => adt_def.variants[i].fields.iter().zip(&variants[i].offsets[1..]),
None => return Err(EvalError::InvalidDiscriminant), None => return Err(EvalError::InvalidDiscriminant),
@ -650,8 +650,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}, },
Layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } => { Layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } => {
let discr = self.read_discriminant_value(adt_ptr, ty)?; let discr = self.read_discriminant_value(adt_ptr, ty)?;
if discr == nndiscr { if discr == nndiscr as u128 {
assert_eq!(discr as usize as u64, discr); assert_eq!(discr as usize as u128, discr);
adt_def.variants[discr as usize].fields.iter().zip(&nonnull.offsets) adt_def.variants[discr as usize].fields.iter().zip(&nonnull.offsets)
} else { } else {
// FIXME: the zst variant might contain zst types that impl Drop // FIXME: the zst variant might contain zst types that impl Drop
@ -660,8 +660,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}, },
Layout::RawNullablePointer { nndiscr, .. } => { Layout::RawNullablePointer { nndiscr, .. } => {
let discr = self.read_discriminant_value(adt_ptr, ty)?; let discr = self.read_discriminant_value(adt_ptr, ty)?;
if discr == nndiscr { if discr == nndiscr as u128 {
assert_eq!(discr as usize as u64, discr); assert_eq!(discr as usize as u128, discr);
assert_eq!(adt_def.variants[discr as usize].fields.len(), 1); 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 = &adt_def.variants[discr as usize].fields[0];
let field_ty = monomorphize_field_ty(self.tcx, field_ty, substs); let field_ty = monomorphize_field_ty(self.tcx, field_ty, substs);

View file

@ -6,23 +6,23 @@ use std::mem::transmute;
use error::{EvalError, EvalResult}; use error::{EvalError, EvalResult};
use memory::{Memory, Pointer}; 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) } unsafe { transmute::<u32, f32>(bytes as u32) }
} }
pub(super) fn bytes_to_f64(bytes: u64) -> f64 { pub(super) fn bytes_to_f64(bytes: u128) -> f64 {
unsafe { transmute::<u64, f64>(bytes) } unsafe { transmute::<u64, f64>(bytes as u64) }
} }
pub(super) fn f32_to_bytes(f: f32) -> u64 { pub(super) fn f32_to_bytes(f: f32) -> u128 {
unsafe { transmute::<f32, u32>(f) as u64 } unsafe { transmute::<f32, u32>(f) as u128 }
} }
pub(super) fn f64_to_bytes(f: f64) -> u64 { pub(super) fn f64_to_bytes(f: f64) -> u128 {
unsafe { transmute::<f64, u64>(f) } 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? // FIXME(solson): Can we reach here due to user error?
debug_assert!(n == 0 || n == 1, "bytes interpreted as bool were {}", n); debug_assert!(n == 0 || n == 1, "bytes interpreted as bool were {}", n);
n & 1 == 1 n & 1 == 1
@ -50,7 +50,7 @@ pub enum Value {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum PrimVal { pub enum PrimVal {
/// The raw bytes of a simple value. /// 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 /// 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 /// 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)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum PrimValKind { pub enum PrimValKind {
I8, I16, I32, I64, I8, I16, I32, I64, I128,
U8, U16, U32, U64, U8, U16, U32, U64, U128,
F32, F64, F32, F64,
Bool, Bool,
Char, Char,
@ -109,7 +109,9 @@ impl<'a, 'tcx: 'a> Value {
Ok((ptr, len)) Ok((ptr, len))
}, },
ByValPair(ptr, val) => { 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!(), _ => unimplemented!(),
} }
@ -117,12 +119,12 @@ impl<'a, 'tcx: 'a> Value {
} }
impl<'tcx> PrimVal { impl<'tcx> PrimVal {
pub fn from_u64(n: u64) -> Self { pub fn from_u128(n: u128) -> Self {
PrimVal::Bytes(n) PrimVal::Bytes(n)
} }
pub fn from_i64(n: i64) -> Self { pub fn from_i128(n: i128) -> Self {
PrimVal::Bytes(n as u64) PrimVal::Bytes(n as u128)
} }
pub fn from_f32(f: f32) -> Self { pub fn from_f32(f: f32) -> Self {
@ -134,35 +136,56 @@ impl<'tcx> PrimVal {
} }
pub fn from_bool(b: bool) -> Self { pub fn from_bool(b: bool) -> Self {
PrimVal::Bytes(b as u64) PrimVal::Bytes(b as u128)
} }
pub fn from_char(c: char) -> Self { 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 { match self {
PrimVal::Bytes(b) => Ok(b), 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), PrimVal::Undef => Err(EvalError::ReadUndefBytes),
} }
} }
pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> { pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> {
match self { 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::Ptr(p) => Ok(p),
PrimVal::Undef => Err(EvalError::ReadUndefBytes), PrimVal::Undef => Err(EvalError::ReadUndefBytes),
} }
} }
pub fn to_u64(self) -> EvalResult<'tcx, u64> { pub fn to_u128(self) -> EvalResult<'tcx, u128> {
self.to_bytes() 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> { 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> { pub fn to_f32(self) -> EvalResult<'tcx, f32> {
@ -186,7 +209,7 @@ impl PrimValKind {
pub fn is_int(self) -> bool { pub fn is_int(self) -> bool {
use self::PrimValKind::*; use self::PrimValKind::*;
match self { match self {
I8 | I16 | I32 | I64 | U8 | U16 | U32 | U64 => true, I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
_ => false, _ => false,
} }
} }
@ -197,6 +220,7 @@ impl PrimValKind {
2 => PrimValKind::U16, 2 => PrimValKind::U16,
4 => PrimValKind::U32, 4 => PrimValKind::U32,
8 => PrimValKind::U64, 8 => PrimValKind::U64,
16 => PrimValKind::U128,
_ => bug!("can't make uint with size {}", size), _ => bug!("can't make uint with size {}", size),
} }
} }
@ -207,6 +231,7 @@ impl PrimValKind {
2 => PrimValKind::I16, 2 => PrimValKind::I16,
4 => PrimValKind::I32, 4 => PrimValKind::I32,
8 => PrimValKind::I64, 8 => PrimValKind::I64,
16 => PrimValKind::I128,
_ => bug!("can't make int with size {}", size), _ => bug!("can't make int with size {}", size),
} }
} }