rust/src/helpers.rs

73 lines
2.3 KiB
Rust
Raw Normal View History

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 {
/// HACK: this function just extracts all bits if `defined != 0`
/// Mainly used for args of C-functions and we should totally correctly fetch the size
/// of their arguments
fn to_bytes(self) -> EvalResult<'static, u128>;
}
impl<Tag> ScalarExt for Scalar<Tag> {
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
}
}
}
impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
fn to_bytes(self) -> EvalResult<'static, u128> {
self.not_undef()?.to_bytes()
}
}
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()
})
}
}