Reuse the const_eval method for syscall name resolution
This commit is contained in:
parent
f78d6a0d97
commit
f8757aa092
2 changed files with 22 additions and 34 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue