]> git.lizzy.rs Git - rust.git/commitdiff
Support C ABI memcmp function.
authorScott Olson <scott@solson.me>
Tue, 10 May 2016 03:53:20 +0000 (21:53 -0600)
committerScott Olson <scott@solson.me>
Tue, 10 May 2016 03:53:20 +0000 (21:53 -0600)
src/interpreter.rs
tests/compile-fail/bugs/memcmp.rs [deleted file]
tests/run-pass/arrays.rs
tests/run-pass/c_enums.rs

index 3c91998b4a768e30841cd8796c50d87efe7d10a4..24f0e859bd824303ac77e60ae87d83adccdb7810 100644 (file)
@@ -346,14 +346,22 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
                                 match fn_ty.sig.0.output {
                                     ty::FnConverging(ty) => {
                                         let size = self.type_size(ty);
-                                        self.call_intrinsic(&name, substs, args,
-                                            return_ptr.unwrap(), size)?
+                                        let ret = return_ptr.unwrap();
+                                        self.call_intrinsic(&name, substs, args, ret, size)?
                                     }
                                     ty::FnDiverging => unimplemented!(),
                                 }
                             }
 
-                            Abi::C => self.call_c_abi(def_id, args, return_ptr.unwrap())?,
+                            Abi::C => {
+                                match fn_ty.sig.0.output {
+                                    ty::FnConverging(ty) => {
+                                        let size = self.type_size(ty);
+                                        self.call_c_abi(def_id, args, return_ptr.unwrap(), size)?
+                                    }
+                                    ty::FnDiverging => unimplemented!(),
+                                }
+                            }
 
                             Abi::Rust | Abi::RustCall => {
                                 // TODO(solson): Adjust the first argument when calling a Fn or
@@ -613,7 +621,8 @@ fn call_c_abi(
         &mut self,
         def_id: DefId,
         args: &[mir::Operand<'tcx>],
-        dest: Pointer
+        dest: Pointer,
+        dest_size: usize,
     ) -> EvalResult<TerminatorTarget> {
         let name = self.tcx.item_name(def_id);
         let attrs = self.tcx.get_attrs(def_id);
@@ -641,6 +650,26 @@ fn call_c_abi(
                 self.memory.write_ptr(dest, ptr)?;
             }
 
+            "memcmp" => {
+                let left = self.memory.read_ptr(args[0])?;
+                let right = self.memory.read_ptr(args[1])?;
+                let n = self.memory.read_usize(args[2])? as usize;
+
+                let result = {
+                    let left_bytes = self.memory.read_bytes(left, n)?;
+                    let right_bytes = self.memory.read_bytes(right, n)?;
+
+                    use std::cmp::Ordering::*;
+                    match left_bytes.cmp(right_bytes) {
+                        Less => -1,
+                        Equal => 0,
+                        Greater => 1,
+                    }
+                };
+
+                self.memory.write_int(dest, result, dest_size)?;
+            }
+
             _ => panic!("can't call C ABI function: {}", link_name),
         }
 
diff --git a/tests/compile-fail/bugs/memcmp.rs b/tests/compile-fail/bugs/memcmp.rs
deleted file mode 100644 (file)
index 3fd41e7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(custom_attribute)]
-#![allow(dead_code, unused_attributes)]
-
-// error-pattern:can't call C ABI function: memcmp
-
-#[miri_run]
-fn memcmp() {
-    assert_eq!("", "");
-}
-
-fn main() {}
index d433310a6a89d8cc8ed6cda870b7fc51bca642f8..db4f999a8b043f327712bdab597a398cc13d0eb6 100644 (file)
@@ -46,13 +46,11 @@ fn slice_index() -> u8 {
 
 #[miri_run]
 fn main() {
-    // assert_eq!(empty_array(), []);
+    assert_eq!(empty_array(), []);
     assert_eq!(index_unsafe(), 20);
     assert_eq!(index(), 20);
     assert_eq!(slice_index(), 106);
-    /*
     assert_eq!(big_array(), [5, 4, 3, 2, 1]);
     assert_eq!(array_array(), [[5, 4], [3, 2], [1, 0]]);
     assert_eq!(array_repeat(), [42; 8]);
-    */
 }
index fd537a37b043965a040b9884f631c2fc6fa2e28f..60790fef439fc47e762467e624bf01a06455d806 100644 (file)
@@ -33,7 +33,7 @@ fn unsafe_match() -> bool {
 
 #[miri_run]
 fn main() {
-    // assert_eq!(foo(), [42, 43, 100]);
-    // assert_eq!(signed(), [-42, -41, 100]);
+    assert_eq!(foo(), [42, 43, 100]);
+    assert_eq!(signed(), [-42, -41, 100]);
     assert!(unsafe_match());
 }