]> git.lizzy.rs Git - rust.git/commitdiff
Implement the size_of intrinsic.
authorScott Olson <scott@solson.me>
Tue, 15 Mar 2016 06:45:25 +0000 (00:45 -0600)
committerScott Olson <scott@solson.me>
Tue, 15 Mar 2016 06:45:25 +0000 (00:45 -0600)
src/interpreter.rs
test/calls.rs

index 17ab9a52bbac76a3aad158783ed6fcc13f7bd9b9..21be40f696a1747d823a634465092ce2f585731e 100644 (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,13 +223,38 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<
                 let func_ty = self.current_frame().mir.operand_ty(self.tcx, func);
 
                 match func_ty.sty {
-                    ty::TyFnDef(def_id, substs, _) => {
-                        let mir = self.load_mir(def_id);
-                        let substs = self.tcx.mk_substs(
-                            substs.subst(self.tcx, self.current_substs()));
-                        self.substs_stack.push(substs);
-                        try!(self.push_stack_frame(mir, args, return_ptr));
-                        TerminatorTarget::Call
+                    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()));
+                                self.substs_stack.push(substs);
+                                try!(self.push_stack_frame(mir, args, return_ptr));
+                                TerminatorTarget::Call
+                            }
+
+                            abi => panic!("can't handle function with ABI {:?}", abi),
+                        }
                     }
 
                     _ => panic!("can't handle callee of type {:?}", func_ty),
@@ -404,14 +429,19 @@ fn const_to_ptr(&mut self, const_val: &const_eval::ConstVal) -> EvalResult<Point
                 try!(self.memory.write_i64(ptr, n));
                 Ok(ptr)
             }
-            Uint(_u)          => unimplemented!(),
-            Str(ref _s)       => unimplemented!(),
-            ByteStr(ref _bs)  => 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!(),
index 56f5237113dbfcc476cdf2965fad762bb3147a5d..2cda1c3bddf1bd92a6c7255acc07d90fdeb95724 100644 (file)
@@ -32,3 +32,9 @@ fn id<T>(t: T) -> T { t }
 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>>()
+}