Reuse the const_eval method for syscall name resolution

This commit is contained in:
Oliver Schneider 2017-07-13 16:49:55 +02:00
parent f78d6a0d97
commit f8757aa092
2 changed files with 22 additions and 34 deletions

View file

@ -1,22 +1,20 @@
use rustc::hir::def_id::DefId;
use rustc::traits::Reveal;
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt};
use rustc::ty::{self, TyCtxt, Ty, Instance};
use error::{EvalError, EvalResult};
use lvalue::{Global, GlobalId, Lvalue};
use value::PrimVal;
use rustc_const_math::ConstInt;
use eval_context::{EvalContext, StackPopCleanup};
pub fn eval_body_as_integer<'a, 'tcx>(
pub fn eval_body_as_primval<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
(def_id, substs): (DefId, &'tcx Substs<'tcx>),
) -> EvalResult<'tcx, ConstInt> {
instance: Instance<'tcx>,
) -> EvalResult<'tcx, (PrimVal, Ty<'tcx>)> {
let limits = ::ResourceLimits::default();
let mut ecx = EvalContext::new(tcx, limits);
let instance = ecx.resolve_associated_const(def_id, substs);
let cid = GlobalId { instance, promoted: None };
if ecx.tcx.has_attr(def_id, "linkage") {
if ecx.tcx.has_attr(instance.def_id(), "linkage") {
return Err(EvalError::NotConst("extern global".to_string()));
}
@ -28,7 +26,7 @@ pub fn eval_body_as_integer<'a, 'tcx>(
ty::ParamEnv::empty(Reveal::All),
mir.span);
let cleanup = StackPopCleanup::MarkStatic(mutable);
let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
let name = ty::tls::with(|tcx| tcx.item_path_str(instance.def_id()));
trace!("pushing stack frame for global: {}", name);
ecx.push_stack_frame(
instance,
@ -41,11 +39,19 @@ pub fn eval_body_as_integer<'a, 'tcx>(
while ecx.step()? {}
}
let value = ecx.globals.get(&cid).expect("global not cached").value;
let prim = ecx.value_to_primval(value, mir.return_ty)?.to_bytes()?;
Ok((ecx.value_to_primval(value, mir.return_ty)?, mir.return_ty))
}
pub fn eval_body_as_integer<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
instance: Instance<'tcx>,
) -> EvalResult<'tcx, ConstInt> {
let (prim, ty) = eval_body_as_primval(tcx, instance)?;
let prim = prim.to_bytes()?;
use syntax::ast::{IntTy, UintTy};
use rustc::ty::TypeVariants::*;
use rustc_const_math::{ConstIsize, ConstUsize};
Ok(match mir.return_ty.sty {
Ok(match ty.sty {
TyInt(IntTy::I8) => ConstInt::I8(prim as i128 as i8),
TyInt(IntTy::I16) => ConstInt::I16(prim as i128 as i16),
TyInt(IntTy::I32) => ConstInt::I32(prim as i128 as i32),

View file

@ -855,7 +855,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"sysconf" => {
let name = self.value_to_primval(args[0], usize)?.to_u64()?;
trace!("sysconf() called with name {}", name);
// cache the sysconf integers
// cache the sysconf integers via miri's global cache
let paths = &[
(&["libc", "_SC_PAGESIZE"], PrimVal::Bytes(4096)),
(&["libc", "_SC_GETPW_R_SIZE_MAX"], PrimVal::from_i128(-1)),
@ -863,31 +863,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let mut result = None;
for &(path, path_value) in paths {
if let Ok(instance) = self.resolve_path(path) {
use lvalue::{Global, GlobalId};
use lvalue::GlobalId;
let cid = GlobalId { instance, promoted: None };
// compute global if not cached
let val = match self.globals.get(&cid).map(|glob| glob.value) {
Some(value) => value,
None => {
let mir = self.load_mir(instance.def)?;
self.globals.insert(cid, Global::uninitialized(mir.return_ty));
let cleanup = StackPopCleanup::MarkStatic(false);
let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
trace!("pushing stack frame for global: {}", name);
let frame = self.stack.len();
self.push_stack_frame(
instance,
mir.span,
mir,
Lvalue::Global(cid),
cleanup,
)?;
while self.stack.len() != frame {
self.step()?;
}
self.globals.get(&cid).expect("we just computed the global").value
}
Some(value) => self.value_to_primval(value, usize)?.to_u64()?,
None => ::const_eval::eval_body_as_primval(self.tcx, instance)?.0.to_u64()?,
};
let val = self.value_to_primval(val, usize)?.to_u64()?;
if val == name {
result = Some(path_value);
break;