diff --git a/Cargo.toml b/Cargo.toml index 9a3bf11..27ed677 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rusty_spine" -version = "0.7.1" +version = "0.7.2" edition = "2021" description = "Spine runtime for Rust (and wasm!) transpiled from the official C Runtime." homepage = "https://github.com/jabuwu/rusty_spine" diff --git a/changelog.md b/changelog.md index e37f853..73fcbe9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +# 0.7.2 +- Fix `memcpy` crash in Rust 1.78 (when not using `libc` feature) + # 0.7.1 - Fix dark color applying incorrectly with premultiplied alpha (using draw functions) diff --git a/src/c/wasm.rs b/src/c/wasm.rs index 644123b..579f2a9 100644 --- a/src/c/wasm.rs +++ b/src/c/wasm.rs @@ -853,19 +853,210 @@ unsafe extern "C" fn spine_free(ptr: *mut c_void) { } #[no_mangle] -unsafe extern "C" fn spine_memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void { - std::ptr::copy_nonoverlapping(src, dest, n as usize); - dest +unsafe extern "C" fn spine_memcpy( + dst0: *mut c_void, + src0: *const c_void, + mut length: size_t, +) -> *mut c_void { + type Word = size_t; + let mut dst: *mut c_char = dst0.cast::(); + let mut src: *const c_char = src0.cast::(); + let mut t: size_t; + if !(length == 0 as c_int as c_ulong || dst.cast_const() == src) { + if dst < src.cast_mut() && dst.offset(length as isize) > src.cast_mut() + || src < dst.cast_const() && src.offset(length as isize) > dst.cast_const() + { + panic!(); + } + t = src as c_long as size_t; + if (t | dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong) + != 0 + { + if (t ^ dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong) + != 0 + || length < ::core::mem::size_of::() as c_ulong + { + t = length; + } else { + t = (::core::mem::size_of::() as c_ulong).wrapping_sub( + t & (::core::mem::size_of::() as c_ulong) + .wrapping_sub(1 as c_int as c_ulong), + ); + } + length = (length as c_ulong).wrapping_sub(t) as size_t as size_t; + loop { + let fresh0 = src; + src = src.offset(1); + let fresh1 = dst; + dst = dst.offset(1); + *fresh1 = *fresh0; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length.wrapping_div(::core::mem::size_of::() as c_ulong); + if t != 0 { + loop { + *dst.cast::() = *(src as *mut Word); + src = src.offset(::core::mem::size_of::() as c_ulong as isize); + dst = dst.offset(::core::mem::size_of::() as c_ulong as isize); + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong); + if t != 0 { + loop { + let fresh2 = src; + src = src.offset(1); + let fresh3 = dst; + dst = dst.offset(1); + *fresh3 = *fresh2; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + } + dst0 } #[no_mangle] unsafe extern "C" fn spine_memmove( - dest: *mut c_void, - src: *const c_void, - n: size_t, + dst0: *mut c_void, + src0: *const c_void, + mut length: size_t, ) -> *mut c_void { - std::ptr::copy(src, dest, n as usize); - dest + type Word = size_t; + let mut dst: *mut c_char = dst0.cast::(); + let mut src: *const c_char = src0.cast::(); + let mut t: size_t; + if !(length == 0 as c_int as c_ulong || dst.cast_const() == src) { + if (dst as c_ulong) < src as c_ulong { + t = src as c_long as size_t; + if (t | dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong) + != 0 + { + if (t ^ dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong) + .wrapping_sub(1 as c_int as c_ulong) + != 0 + || length < ::core::mem::size_of::() as c_ulong + { + t = length; + } else { + t = (::core::mem::size_of::() as c_ulong).wrapping_sub( + t & (::core::mem::size_of::() as c_ulong) + .wrapping_sub(1 as c_int as c_ulong), + ); + } + length = (length as c_ulong).wrapping_sub(t) as size_t as size_t; + loop { + let fresh0 = src; + src = src.offset(1); + let fresh1 = dst; + dst = dst.offset(1); + *fresh1 = *fresh0; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length.wrapping_div(::core::mem::size_of::() as c_ulong); + if t != 0 { + loop { + *dst.cast::() = *(src as *mut Word); + src = src.offset(::core::mem::size_of::() as c_ulong as isize); + dst = dst.offset(::core::mem::size_of::() as c_ulong as isize); + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong); + if t != 0 { + loop { + let fresh2 = src; + src = src.offset(1); + let fresh3 = dst; + dst = dst.offset(1); + *fresh3 = *fresh2; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + } else { + src = src.offset(length as isize); + dst = dst.offset(length as isize); + t = src as c_long as size_t; + if (t | dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong) + != 0 + { + if (t ^ dst as c_long as c_ulong) + & (::core::mem::size_of::() as c_ulong) + .wrapping_sub(1 as c_int as c_ulong) + != 0 + || length <= ::core::mem::size_of::() as c_ulong + { + t = length; + } else { + t &= (::core::mem::size_of::() as c_ulong) + .wrapping_sub(1 as c_int as c_ulong); + } + length = (length as c_ulong).wrapping_sub(t) as size_t as size_t; + loop { + src = src.offset(-1); + dst = dst.offset(-1); + *dst = *src; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length.wrapping_div(::core::mem::size_of::() as c_ulong); + if t != 0 { + loop { + src = src.offset(-(::core::mem::size_of::() as c_ulong as isize)); + dst = dst.offset(-(::core::mem::size_of::() as c_ulong as isize)); + *dst.cast::() = *(src as *mut Word); + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + t = length + & (::core::mem::size_of::() as c_ulong).wrapping_sub(1 as c_int as c_ulong); + if t != 0 { + loop { + src = src.offset(-1); + dst = dst.offset(-1); + *dst = *src; + t = t.wrapping_sub(1); + if t == 0 { + break; + } + } + } + } + } + dst0 } #[no_mangle]