From: Scott Olson Date: Tue, 10 May 2016 03:53:20 +0000 (-0600) Subject: Support C ABI memcmp function. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=2d325034093a336df20f22f7edb3df9ef83cac47;p=rust.git Support C ABI memcmp function. --- diff --git a/src/interpreter.rs b/src/interpreter.rs index 3c91998b4a7..24f0e859bd8 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -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 { 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 index 3fd41e7b3dd..00000000000 --- a/tests/compile-fail/bugs/memcmp.rs +++ /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() {} diff --git a/tests/run-pass/arrays.rs b/tests/run-pass/arrays.rs index d433310a6a8..db4f999a8b0 100644 --- a/tests/run-pass/arrays.rs +++ b/tests/run-pass/arrays.rs @@ -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]); - */ } diff --git a/tests/run-pass/c_enums.rs b/tests/run-pass/c_enums.rs index fd537a37b04..60790fef439 100644 --- a/tests/run-pass/c_enums.rs +++ b/tests/run-pass/c_enums.rs @@ -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()); }