1
Fork 0

Support C ABI memcmp function.

This commit is contained in:
Scott Olson 2016-05-09 21:53:20 -06:00
parent 78caee20c7
commit 2d32503409
4 changed files with 36 additions and 20 deletions

View file

@ -346,14 +346,22 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
match fn_ty.sig.0.output { match fn_ty.sig.0.output {
ty::FnConverging(ty) => { ty::FnConverging(ty) => {
let size = self.type_size(ty); let size = self.type_size(ty);
self.call_intrinsic(&name, substs, args, let ret = return_ptr.unwrap();
return_ptr.unwrap(), size)? self.call_intrinsic(&name, substs, args, ret, size)?
} }
ty::FnDiverging => unimplemented!(), 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 => { Abi::Rust | Abi::RustCall => {
// TODO(solson): Adjust the first argument when calling a Fn or // TODO(solson): Adjust the first argument when calling a Fn or
@ -613,7 +621,8 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
&mut self, &mut self,
def_id: DefId, def_id: DefId,
args: &[mir::Operand<'tcx>], args: &[mir::Operand<'tcx>],
dest: Pointer dest: Pointer,
dest_size: usize,
) -> EvalResult<TerminatorTarget> { ) -> EvalResult<TerminatorTarget> {
let name = self.tcx.item_name(def_id); let name = self.tcx.item_name(def_id);
let attrs = self.tcx.get_attrs(def_id); let attrs = self.tcx.get_attrs(def_id);
@ -641,6 +650,26 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
self.memory.write_ptr(dest, ptr)?; 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), _ => panic!("can't call C ABI function: {}", link_name),
} }

View file

@ -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() {}

View file

@ -46,13 +46,11 @@ fn slice_index() -> u8 {
#[miri_run] #[miri_run]
fn main() { fn main() {
// assert_eq!(empty_array(), []); assert_eq!(empty_array(), []);
assert_eq!(index_unsafe(), 20); assert_eq!(index_unsafe(), 20);
assert_eq!(index(), 20); assert_eq!(index(), 20);
assert_eq!(slice_index(), 106); assert_eq!(slice_index(), 106);
/*
assert_eq!(big_array(), [5, 4, 3, 2, 1]); assert_eq!(big_array(), [5, 4, 3, 2, 1]);
assert_eq!(array_array(), [[5, 4], [3, 2], [1, 0]]); assert_eq!(array_array(), [[5, 4], [3, 2], [1, 0]]);
assert_eq!(array_repeat(), [42; 8]); assert_eq!(array_repeat(), [42; 8]);
*/
} }

View file

@ -33,7 +33,7 @@ fn unsafe_match() -> bool {
#[miri_run] #[miri_run]
fn main() { fn main() {
// assert_eq!(foo(), [42, 43, 100]); assert_eq!(foo(), [42, 43, 100]);
// assert_eq!(signed(), [-42, -41, 100]); assert_eq!(signed(), [-42, -41, 100]);
assert!(unsafe_match()); assert!(unsafe_match());
} }