Add AligneType and redo secp256k1_context_create with alloc
This commit is contained in:
parent
11e9641d21
commit
7b99784837
|
@ -21,6 +21,9 @@ features = [ "recovery", "endomorphism", "lowmemory" ]
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0.28"
|
cc = "1.0.28"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
recovery = []
|
recovery = []
|
||||||
|
|
|
@ -534,19 +534,21 @@ extern "C" {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||||
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_create(flags: c_uint) -> *mut Context {
|
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_create(flags: c_uint) -> *mut Context {
|
||||||
use std::mem;
|
use core::mem;
|
||||||
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());
|
use std::alloc;
|
||||||
assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>());
|
assert!(ALIGN_TO >= mem::align_of::<usize>());
|
||||||
|
assert!(ALIGN_TO >= mem::align_of::<&usize>());
|
||||||
|
assert!(ALIGN_TO >= mem::size_of::<usize>());
|
||||||
|
|
||||||
let word_size = mem::size_of::<usize>();
|
// We need to allocate `ALIGN_TO` more bytes in order to write the amount of bytes back.
|
||||||
let n_words = (secp256k1_context_preallocated_size(flags) + word_size - 1) / word_size;
|
let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
|
||||||
|
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
|
||||||
let buf = vec![0usize; n_words + 1].into_boxed_slice();
|
let ptr = alloc::alloc(layout);
|
||||||
let ptr = Box::into_raw(buf) as *mut usize;
|
(ptr as *mut usize).write(bytes);
|
||||||
::core::ptr::write(ptr, n_words);
|
// We must offset a whole ALIGN_TO in order to preserve the same alignment
|
||||||
let ptr: *mut usize = ptr.offset(1);
|
// this means we "lose" ALIGN_TO-size_of(usize) for padding.
|
||||||
|
let ptr = ptr.add(ALIGN_TO) as *mut c_void;
|
||||||
secp256k1_context_preallocated_create(ptr as *mut c_void, flags)
|
secp256k1_context_preallocated_create(ptr, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||||
|
@ -563,13 +565,12 @@ pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||||
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_destroy(ctx: *mut Context) {
|
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_destroy(ctx: *mut Context) {
|
||||||
|
use std::alloc;
|
||||||
secp256k1_context_preallocated_destroy(ctx);
|
secp256k1_context_preallocated_destroy(ctx);
|
||||||
let ctx: *mut usize = ctx as *mut usize;
|
let ptr = (ctx as *mut u8).sub(ALIGN_TO);
|
||||||
|
let bytes = (ptr as *mut usize).read();
|
||||||
let n_words_ptr: *mut usize = ctx.offset(-1);
|
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
|
||||||
let n_words: usize = ::core::ptr::read(n_words_ptr);
|
alloc::dealloc(ptr, layout);
|
||||||
let slice: &mut [usize] = slice::from_raw_parts_mut(n_words_ptr , n_words+1);
|
|
||||||
let _ = Box::from_raw(slice as *mut [usize]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
use core::fmt;
|
use core::{fmt, mem};
|
||||||
|
|
||||||
pub type c_int = i32;
|
pub type c_int = i32;
|
||||||
pub type c_uchar = u8;
|
pub type c_uchar = u8;
|
||||||
|
@ -26,11 +26,30 @@ impl fmt::Debug for c_void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type that is as aligned as the biggest alignment for fundamental types in C
|
||||||
|
/// since C11 that means as aligned as `max_align_t` is.
|
||||||
|
/// the exact size/alignment is unspecified.
|
||||||
|
// 16 matches is as big as the biggest alignment in any arch that rust currently supports https://github.com/rust-lang/rust/blob/2c31b45ae878b821975c4ebd94cc1e49f6073fd0/library/std/src/sys_common/alloc.rs
|
||||||
|
#[repr(align(16))]
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct AlignedType([u8; 16]);
|
||||||
|
|
||||||
|
impl AlignedType {
|
||||||
|
pub fn zeroed() -> Self {
|
||||||
|
AlignedType([0u8; 16])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) const ALIGN_TO: usize = mem::align_of::<AlignedType>();
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
extern crate libc;
|
||||||
use std::os::raw;
|
use std::os::raw;
|
||||||
|
use std::mem;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use types;
|
use {types, AlignedType};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_types() {
|
fn verify_types() {
|
||||||
|
@ -38,6 +57,8 @@ mod tests {
|
||||||
assert_eq!(TypeId::of::<types::c_uchar>(), TypeId::of::<raw::c_uchar>());
|
assert_eq!(TypeId::of::<types::c_uchar>(), TypeId::of::<raw::c_uchar>());
|
||||||
assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>());
|
assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>());
|
||||||
assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
|
assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
|
||||||
|
|
||||||
|
assert!(mem::align_of::<AlignedType>() >= mem::align_of::<self::libc::max_align_t>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue