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]
|
||||
cc = "1.0.28"
|
||||
|
||||
[dev-dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
recovery = []
|
||||
|
|
|
@ -534,19 +534,21 @@ extern "C" {
|
|||
#[no_mangle]
|
||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_create(flags: c_uint) -> *mut Context {
|
||||
use std::mem;
|
||||
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());
|
||||
assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>());
|
||||
use core::mem;
|
||||
use std::alloc;
|
||||
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>();
|
||||
let n_words = (secp256k1_context_preallocated_size(flags) + word_size - 1) / word_size;
|
||||
|
||||
let buf = vec![0usize; n_words + 1].into_boxed_slice();
|
||||
let ptr = Box::into_raw(buf) as *mut usize;
|
||||
::core::ptr::write(ptr, n_words);
|
||||
let ptr: *mut usize = ptr.offset(1);
|
||||
|
||||
secp256k1_context_preallocated_create(ptr as *mut c_void, flags)
|
||||
// We need to allocate `ALIGN_TO` more bytes in order to write the amount of bytes back.
|
||||
let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
|
||||
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
|
||||
let ptr = alloc::alloc(layout);
|
||||
(ptr as *mut usize).write(bytes);
|
||||
// We must offset a whole ALIGN_TO in order to preserve the same alignment
|
||||
// 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, flags)
|
||||
}
|
||||
|
||||
#[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]
|
||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_destroy(ctx: *mut Context) {
|
||||
use std::alloc;
|
||||
secp256k1_context_preallocated_destroy(ctx);
|
||||
let ctx: *mut usize = ctx as *mut usize;
|
||||
|
||||
let n_words_ptr: *mut usize = ctx.offset(-1);
|
||||
let n_words: usize = ::core::ptr::read(n_words_ptr);
|
||||
let slice: &mut [usize] = slice::from_raw_parts_mut(n_words_ptr , n_words+1);
|
||||
let _ = Box::from_raw(slice as *mut [usize]);
|
||||
let ptr = (ctx as *mut u8).sub(ALIGN_TO);
|
||||
let bytes = (ptr as *mut usize).read();
|
||||
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
|
||||
alloc::dealloc(ptr, layout);
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
use core::fmt;
|
||||
use core::{fmt, mem};
|
||||
|
||||
pub type c_int = i32;
|
||||
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)]
|
||||
mod tests {
|
||||
extern crate libc;
|
||||
use std::os::raw;
|
||||
use std::mem;
|
||||
use std::any::TypeId;
|
||||
use types;
|
||||
use {types, AlignedType};
|
||||
|
||||
#[test]
|
||||
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_uint>(), TypeId::of::<raw::c_uint>());
|
||||
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