]> git.lizzy.rs Git - rust.git/commitdiff
Simplify intrinsic/c_abi call argument evaluation.
authorScott Olson <scott@solson.me>
Thu, 7 Apr 2016 08:02:30 +0000 (02:02 -0600)
committerScott Olson <scott@solson.me>
Thu, 7 Apr 2016 08:02:30 +0000 (02:02 -0600)
src/interpreter.rs

index 24e65b5b678ec17795bd3b36ffa59676b6f089f6..5ea2a117b8c58374a8debc36fa2d7b4975c4a4ba 100644 (file)
@@ -371,25 +371,28 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
         Ok(target)
     }
 
-    fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
-        args: &[mir::Operand<'tcx>], dest: Pointer, dest_size: usize)
-        -> EvalResult<TerminatorTarget>
-    {
+    fn call_intrinsic(
+        &mut self,
+        name: &str,
+        substs: &'tcx Substs<'tcx>,
+        args: &[mir::Operand<'tcx>],
+        dest: Pointer,
+        dest_size: usize
+    ) -> EvalResult<TerminatorTarget> {
+        let args_res: EvalResult<Vec<Pointer>> = args.iter()
+            .map(|arg| self.eval_operand(arg))
+            .collect();
+        let args = try!(args_res);
+
         match name {
             "assume" => {}
 
             "copy_nonoverlapping" => {
                 let elem_ty = *substs.types.get(subst::FnSpace, 0);
                 let elem_size = self.type_size(elem_ty);
-
-                let src_arg   = try!(self.eval_operand(&args[0]));
-                let dest_arg  = try!(self.eval_operand(&args[1]));
-                let count_arg = try!(self.eval_operand(&args[2]));
-
-                let src   = try!(self.memory.read_ptr(src_arg));
-                let dest  = try!(self.memory.read_ptr(dest_arg));
-                let count = try!(self.memory.read_isize(count_arg));
-
+                let src = try!(self.memory.read_ptr(args[0]));
+                let dest = try!(self.memory.read_ptr(args[1]));
+                let count = try!(self.memory.read_isize(args[2]));
                 try!(self.memory.copy(src, dest, count as usize * elem_size));
             }
 
@@ -403,29 +406,19 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
             "move_val_init" => {
                 let ty = *substs.types.get(subst::FnSpace, 0);
                 let size = self.type_size(ty);
-
-                let ptr_arg = try!(self.eval_operand(&args[0]));
-                let ptr = try!(self.memory.read_ptr(ptr_arg));
-
-                let val = try!(self.eval_operand(&args[1]));
-                try!(self.memory.copy(val, ptr, size));
+                let ptr = try!(self.memory.read_ptr(args[0]));
+                try!(self.memory.copy(args[1], ptr, size));
             }
 
             // FIXME(tsion): Handle different integer types correctly.
             "add_with_overflow" => {
                 let ty = *substs.types.get(subst::FnSpace, 0);
                 let size = self.type_size(ty);
-
-                let left_arg  = try!(self.eval_operand(&args[0]));
-                let right_arg = try!(self.eval_operand(&args[1]));
-
-                let left = try!(self.memory.read_int(left_arg, size));
-                let right = try!(self.memory.read_int(right_arg, size));
-
+                let left = try!(self.memory.read_int(args[0], size));
+                let right = try!(self.memory.read_int(args[1], size));
                 let (n, overflowed) = unsafe {
                     ::std::intrinsics::add_with_overflow::<i64>(left, right)
                 };
-
                 try!(self.memory.write_int(dest, n, size));
                 try!(self.memory.write_bool(dest.offset(size as isize), overflowed));
             }
@@ -434,17 +427,11 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
             "mul_with_overflow" => {
                 let ty = *substs.types.get(subst::FnSpace, 0);
                 let size = self.type_size(ty);
-
-                let left_arg  = try!(self.eval_operand(&args[0]));
-                let right_arg = try!(self.eval_operand(&args[1]));
-
-                let left = try!(self.memory.read_int(left_arg, size));
-                let right = try!(self.memory.read_int(right_arg, size));
-
+                let left = try!(self.memory.read_int(args[0], size));
+                let right = try!(self.memory.read_int(args[1], size));
                 let (n, overflowed) = unsafe {
                     ::std::intrinsics::mul_with_overflow::<i64>(left, right)
                 };
-
                 try!(self.memory.write_int(dest, n, size));
                 try!(self.memory.write_bool(dest.offset(size as isize), overflowed));
             }
@@ -452,11 +439,8 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
             "offset" => {
                 let pointee_ty = *substs.types.get(subst::FnSpace, 0);
                 let pointee_size = self.type_size(pointee_ty) as isize;
-
-                let ptr_arg    = try!(self.eval_operand(&args[0]));
-                let offset_arg = try!(self.eval_operand(&args[1]));
-
-                let offset = try!(self.memory.read_isize(offset_arg));
+                let ptr_arg = args[0];
+                let offset = try!(self.memory.read_isize(args[1]));
 
                 match self.memory.read_ptr(ptr_arg) {
                     Ok(ptr) => {
@@ -476,13 +460,8 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
             "overflowing_sub" => {
                 let ty = *substs.types.get(subst::FnSpace, 0);
                 let size = self.type_size(ty);
-
-                let left_arg  = try!(self.eval_operand(&args[0]));
-                let right_arg = try!(self.eval_operand(&args[1]));
-
-                let left = try!(self.memory.read_int(left_arg, size));
-                let right = try!(self.memory.read_int(right_arg, size));
-
+                let left = try!(self.memory.read_int(args[0], size));
+                let right = try!(self.memory.read_int(args[1], size));
                 let n = left.wrapping_sub(right);
                 try!(self.memory.write_int(dest, n, size));
             }
@@ -493,14 +472,8 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
                 try!(self.memory.write_uint(dest, size, dest_size));
             }
 
-            "transmute" => {
-                let src = try!(self.eval_operand(&args[0]));
-                try!(self.memory.copy(src, dest, dest_size));
-            }
-
-            "uninit" => {
-                try!(self.memory.mark_definedness(dest, dest_size, false));
-            }
+            "transmute" => try!(self.memory.copy(args[0], dest, dest_size)),
+            "uninit" => try!(self.memory.mark_definedness(dest, dest_size, false)),
 
             name => panic!("can't handle intrinsic: {}", name),
         }
@@ -511,9 +484,12 @@ fn call_intrinsic(&mut self, name: &str, substs: &'tcx Substs<'tcx>,
         Ok(TerminatorTarget::Call)
     }
 
-    fn call_c_abi(&mut self, def_id: DefId, args: &[mir::Operand<'tcx>], dest: Pointer)
-        -> EvalResult<TerminatorTarget>
-    {
+    fn call_c_abi(
+        &mut self,
+        def_id: DefId,
+        args: &[mir::Operand<'tcx>],
+        dest: Pointer
+    ) -> EvalResult<TerminatorTarget> {
         let name = self.tcx.item_name(def_id);
         let attrs = self.tcx.get_attrs(def_id);
         let link_name = match attr::first_attr_value_str_by_name(&attrs, "link_name") {
@@ -521,22 +497,21 @@ fn call_c_abi(&mut self, def_id: DefId, args: &[mir::Operand<'tcx>], dest: Point
             None => name.as_str(),
         };
 
+        let args_res: EvalResult<Vec<Pointer>> = args.iter()
+            .map(|arg| self.eval_operand(arg))
+            .collect();
+        let args = try!(args_res);
+
         match &link_name[..] {
             "__rust_allocate" => {
-                let size_arg  = try!(self.eval_operand(&args[0]));
-                let _align_arg = try!(self.eval_operand(&args[1]));
-                let size = try!(self.memory.read_usize(size_arg));
+                let size = try!(self.memory.read_usize(args[0]));
                 let ptr = self.memory.allocate(size as usize);
                 try!(self.memory.write_ptr(dest, ptr));
             }
 
             "__rust_reallocate" => {
-                let ptr_arg = try!(self.eval_operand(&args[0]));
-                let _old_size_arg = try!(self.eval_operand(&args[1]));
-                let size_arg = try!(self.eval_operand(&args[2]));
-                let _align_arg = try!(self.eval_operand(&args[3]));
-                let ptr = try!(self.memory.read_ptr(ptr_arg));
-                let size = try!(self.memory.read_usize(size_arg));
+                let ptr = try!(self.memory.read_ptr(args[0]));
+                let size = try!(self.memory.read_usize(args[2]));
                 try!(self.memory.reallocate(ptr, size as usize));
                 try!(self.memory.write_ptr(dest, ptr));
             }