1
Fork 0

Implement the size_of intrinsic.

This commit is contained in:
Scott Olson 2016-03-15 00:45:25 -06:00
parent 7eddb4e92a
commit 40462d64ef
2 changed files with 48 additions and 12 deletions

View file

@ -1,6 +1,6 @@
use rustc::middle::const_eval;
use rustc::middle::def_id::DefId;
use rustc::middle::subst::{Subst, Substs};
use rustc::middle::subst::{self, Subst, Substs};
use rustc::middle::ty::{self, TyCtxt};
use rustc::mir::mir_map::MirMap;
use rustc::mir::repr as mir;
@ -223,7 +223,28 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
let func_ty = self.current_frame().mir.operand_ty(self.tcx, func);
match func_ty.sty {
ty::TyFnDef(def_id, substs, _) => {
ty::TyFnDef(def_id, substs, bare_fn_ty) => {
use syntax::abi::Abi;
match bare_fn_ty.abi {
Abi::RustIntrinsic => match &self.tcx.item_name(def_id).as_str()[..] {
"size_of" => {
let ty = *substs.types.get(subst::FnSpace, 0);
let (dest, dest_repr) =
try!(self.eval_lvalue(&mir::Lvalue::ReturnPointer));
let size = PrimVal::from_usize(self.ty_to_repr(ty).size(),
&dest_repr);
try!(self.memory.write_primval(dest, size));
// Since we pushed no stack frame, the main loop will act as if
// the call just completed and it's returning to the current
// frame.
TerminatorTarget::Call
},
name => panic!("can't handle intrinsic named {}", name),
},
Abi::Rust => {
let mir = self.load_mir(def_id);
let substs = self.tcx.mk_substs(
substs.subst(self.tcx, self.current_substs()));
@ -232,6 +253,10 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
TerminatorTarget::Call
}
abi => panic!("can't handle function with ABI {:?}", abi),
}
}
_ => panic!("can't handle callee of type {:?}", func_ty),
}
}
@ -404,14 +429,19 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
try!(self.memory.write_i64(ptr, n));
Ok(ptr)
}
Uint(_u) => unimplemented!(),
Uint(n) => {
// TODO(tsion): Check int constant type.
let ptr = self.memory.allocate(8);
try!(self.memory.write_u64(ptr, n));
Ok(ptr)
}
Str(ref _s) => unimplemented!(),
ByteStr(ref _bs) => unimplemented!(),
Bool(b) => {
let ptr = self.memory.allocate(Repr::Bool.size());
try!(self.memory.write_bool(ptr, b));
Ok(ptr)
},
}
Struct(_node_id) => unimplemented!(),
Tuple(_node_id) => unimplemented!(),
Function(_def_id) => unimplemented!(),

View file

@ -32,3 +32,9 @@ fn call_generic() -> (i16, bool) {
fn cross_crate_fn_call() -> i64 {
if 1i32.is_positive() { 1 } else { 0 }
}
// Test one of the simplest intrinsics.
#[miri_run]
fn test_size_of() -> usize {
::std::mem::size_of::<Option<i32>>()
}