2018-10-19 02:51:04 -05:00
|
|
|
use std::mem;
|
2018-05-01 11:13:22 -05:00
|
|
|
|
2018-10-19 02:51:04 -05:00
|
|
|
use rustc::ty;
|
|
|
|
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
|
|
|
|
2018-11-01 02:56:41 -05:00
|
|
|
use crate::*;
|
2018-10-19 02:51:04 -05:00
|
|
|
|
|
|
|
pub trait ScalarExt {
|
2018-08-15 14:01:40 -05:00
|
|
|
/// HACK: this function just extracts all bits if `defined != 0`
|
|
|
|
/// Mainly used for args of C-functions and we should totally correctly fetch the size
|
|
|
|
/// of their arguments
|
|
|
|
fn to_bytes(self) -> EvalResult<'static, u128>;
|
|
|
|
}
|
|
|
|
|
2018-10-22 01:39:39 -05:00
|
|
|
impl<Tag> ScalarExt for Scalar<Tag> {
|
2018-08-15 14:01:40 -05:00
|
|
|
fn to_bytes(self) -> EvalResult<'static, u128> {
|
|
|
|
match self {
|
|
|
|
Scalar::Bits { bits, size } => {
|
|
|
|
assert_ne!(size, 0);
|
|
|
|
Ok(bits)
|
|
|
|
},
|
|
|
|
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
|
2018-07-10 10:32:38 -05:00
|
|
|
}
|
2017-07-28 06:08:27 -05:00
|
|
|
}
|
2018-08-15 14:01:40 -05:00
|
|
|
}
|
|
|
|
|
2018-10-22 01:39:39 -05:00
|
|
|
impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
|
2018-08-15 14:01:40 -05:00
|
|
|
fn to_bytes(self) -> EvalResult<'static, u128> {
|
|
|
|
self.not_undef()?.to_bytes()
|
2018-05-09 04:52:41 -05:00
|
|
|
}
|
2017-07-28 06:08:27 -05:00
|
|
|
}
|
2018-10-19 02:51:04 -05:00
|
|
|
|
|
|
|
pub trait EvalContextExt<'tcx> {
|
|
|
|
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>>;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
|
|
|
|
/// Get an instance for a path.
|
|
|
|
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
|
|
|
|
self.tcx
|
|
|
|
.crates()
|
|
|
|
.iter()
|
|
|
|
.find(|&&krate| self.tcx.original_crate_name(krate) == path[0])
|
|
|
|
.and_then(|krate| {
|
|
|
|
let krate = DefId {
|
|
|
|
krate: *krate,
|
|
|
|
index: CRATE_DEF_INDEX,
|
|
|
|
};
|
|
|
|
let mut items = self.tcx.item_children(krate);
|
|
|
|
let mut path_it = path.iter().skip(1).peekable();
|
|
|
|
|
|
|
|
while let Some(segment) = path_it.next() {
|
|
|
|
for item in mem::replace(&mut items, Default::default()).iter() {
|
|
|
|
if item.ident.name == *segment {
|
|
|
|
if path_it.peek().is_none() {
|
|
|
|
return Some(ty::Instance::mono(self.tcx.tcx, item.def.def_id()));
|
|
|
|
}
|
|
|
|
|
|
|
|
items = self.tcx.item_children(item.def.def_id());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
})
|
|
|
|
.ok_or_else(|| {
|
|
|
|
let path = path.iter().map(|&s| s.to_owned()).collect();
|
|
|
|
EvalErrorKind::PathNotFound(path).into()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|