Skip to content

Commit a011ca3

Browse files
committed
Add memmove semantics to Ptr::memcpy
1 parent 0e84766 commit a011ca3

7 files changed

Lines changed: 111 additions & 39 deletions

File tree

libcc2rs/src/rc.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,16 @@ thread_local! {
952952
impl Ptr<u8> {
953953
#[allow(clippy::explicit_counter_loop)]
954954
pub fn memcpy(&self, src: &Self, len: usize) {
955+
if *self > *src {
956+
let mut dst = self.offset(len);
957+
let mut s = src.offset(len);
958+
for _ in 0..len {
959+
dst -= 1;
960+
s -= 1;
961+
dst.write(s.read());
962+
}
963+
return;
964+
}
955965
let mut dst = self.clone();
956966
let mut i: usize = 0;
957967
for value in src {

rules/cstring/tgt_refcount.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,7 @@ fn f3(a0: AnyPtr, a1: AnyPtr, a2: usize) -> i32 {
1818
}
1919

2020
fn f4(a0: AnyPtr, a1: AnyPtr, a2: usize) -> AnyPtr {
21-
let mut __src = a1.reinterpret_cast::<u8>();
22-
let mut __tmp: Vec<u8> = Vec::with_capacity(a2);
23-
for _ in 0..a2 {
24-
__tmp.push(__src.read());
25-
__src += 1;
26-
}
27-
let mut __dst = a0.reinterpret_cast::<u8>();
28-
for __i in 0..a2 {
29-
__dst.write(__tmp[__i]);
30-
__dst += 1;
31-
}
21+
a0.memcpy(&a1, a2 as usize);
3222
a0.clone()
3323
}
3424

tests/unit/memcpy_overlap.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
#include <string.h>
3+
4+
int main(void) {
5+
char buf[6] = {1, 2, 3, 4, 5, 6};
6+
7+
memmove(buf + 2, buf, 4);
8+
9+
assert(buf[0] == 1);
10+
assert(buf[1] == 2);
11+
assert(buf[2] == 1);
12+
assert(buf[3] == 2);
13+
assert(buf[4] == 3);
14+
assert(buf[5] == 4);
15+
16+
return 0;
17+
}

tests/unit/out/refcount/cstring.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,12 @@ pub fn test_memmove_3() {
101101
('\0' as u8),
102102
])));
103103
let r: Value<AnyPtr> = Rc::new(RefCell::new({
104-
let mut __src = ((buf.as_pointer() as Ptr<u8>) as Ptr<u8>)
105-
.to_any()
106-
.reinterpret_cast::<u8>();
107-
let mut __tmp: Vec<u8> = Vec::with_capacity(4_usize);
108-
for _ in 0..4_usize {
109-
__tmp.push(__src.read());
110-
__src += 1;
111-
}
112-
let mut __dst = ((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
104+
((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
113105
.to_any()
114-
.reinterpret_cast::<u8>();
115-
for __i in 0..4_usize {
116-
__dst.write(__tmp[__i]);
117-
__dst += 1;
118-
}
106+
.memcpy(
107+
&((buf.as_pointer() as Ptr<u8>) as Ptr<u8>).to_any(),
108+
4_usize as usize,
109+
);
119110
((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
120111
.to_any()
121112
.clone()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn main() {
10+
std::process::exit(main_0());
11+
}
12+
fn main_0() -> i32 {
13+
let buf: Value<Box<[u8]>> =
14+
Rc::new(RefCell::new(Box::new([1_u8, 2_u8, 3_u8, 4_u8, 5_u8, 6_u8])));
15+
{
16+
((buf.as_pointer() as Ptr<u8>).offset((2) as isize) as Ptr<u8>)
17+
.to_any()
18+
.memcpy(
19+
&((buf.as_pointer() as Ptr<u8>) as Ptr<u8>).to_any(),
20+
4_usize as usize,
21+
);
22+
((buf.as_pointer() as Ptr<u8>).offset((2) as isize) as Ptr<u8>)
23+
.to_any()
24+
.clone()
25+
};
26+
assert!((((*buf.borrow())[(0) as usize] as i32) == 1));
27+
assert!((((*buf.borrow())[(1) as usize] as i32) == 2));
28+
assert!((((*buf.borrow())[(2) as usize] as i32) == 1));
29+
assert!((((*buf.borrow())[(3) as usize] as i32) == 2));
30+
assert!((((*buf.borrow())[(4) as usize] as i32) == 3));
31+
assert!((((*buf.borrow())[(5) as usize] as i32) == 4));
32+
return 0;
33+
}

tests/unit/out/refcount/string_h.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,21 +124,12 @@ pub fn test_memmove_3() {
124124
(('\0' as i32) as u8),
125125
])));
126126
let r: Value<AnyPtr> = Rc::new(RefCell::new({
127-
let mut __src = ((buf.as_pointer() as Ptr<u8>) as Ptr<u8>)
128-
.to_any()
129-
.reinterpret_cast::<u8>();
130-
let mut __tmp: Vec<u8> = Vec::with_capacity(4_usize);
131-
for _ in 0..4_usize {
132-
__tmp.push(__src.read());
133-
__src += 1;
134-
}
135-
let mut __dst = ((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
127+
((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
136128
.to_any()
137-
.reinterpret_cast::<u8>();
138-
for __i in 0..4_usize {
139-
__dst.write(__tmp[__i]);
140-
__dst += 1;
141-
}
129+
.memcpy(
130+
&((buf.as_pointer() as Ptr<u8>) as Ptr<u8>).to_any(),
131+
4_usize as usize,
132+
);
142133
((buf.as_pointer() as Ptr<u8>).offset((1) as isize) as Ptr<u8>)
143134
.to_any()
144135
.clone()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub fn main() {
10+
unsafe {
11+
std::process::exit(main_0() as i32);
12+
}
13+
}
14+
unsafe fn main_0() -> i32 {
15+
let mut buf: [libc::c_char; 6] = [
16+
(1 as libc::c_char),
17+
(2 as libc::c_char),
18+
(3 as libc::c_char),
19+
(4 as libc::c_char),
20+
(5 as libc::c_char),
21+
(6 as libc::c_char),
22+
];
23+
{
24+
if 4_usize != 0 {
25+
::std::ptr::copy_nonoverlapping(
26+
(buf.as_mut_ptr() as *const libc::c_char as *const ::libc::c_void),
27+
(buf.as_mut_ptr().offset((2) as isize) as *mut libc::c_char as *mut ::libc::c_void),
28+
4_usize as usize,
29+
)
30+
}
31+
(buf.as_mut_ptr().offset((2) as isize) as *mut libc::c_char as *mut ::libc::c_void)
32+
};
33+
assert!(((buf[(0) as usize] as i32) == (1)));
34+
assert!(((buf[(1) as usize] as i32) == (2)));
35+
assert!(((buf[(2) as usize] as i32) == (1)));
36+
assert!(((buf[(3) as usize] as i32) == (2)));
37+
assert!(((buf[(4) as usize] as i32) == (3)));
38+
assert!(((buf[(5) as usize] as i32) == (4)));
39+
return 0;
40+
}

0 commit comments

Comments
 (0)