Add sanity checks for wasm32 for size and alignment of types

This commit is contained in:
Elichai Turkel 2020-04-29 22:15:40 +03:00 committed by Matt Corallo
parent 931253d41e
commit affc6b4027
3 changed files with 63 additions and 1 deletions

View File

@ -12,7 +12,7 @@ pub type c_char = i8;
/// This is an exact copy of https://doc.rust-lang.org/core/ffi/enum.c_void.html
/// It should be Equivalent to C's void type when used as a pointer.
///
///
/// We can replace this with `core::ffi::c_void` once we update the rustc version to >=1.30.0.
#[repr(u8)]
pub enum c_void {
@ -40,3 +40,42 @@ mod tests {
assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
}
}
#[doc(hidden)]
#[cfg(target_arch = "wasm32")]
pub fn sanity_checks_for_wasm() {
use std::mem::{size_of, align_of};
extern "C" {
pub static WASM32_INT_SIZE: c_uchar;
pub static WASM32_INT_ALIGN: c_uchar;
pub static WASM32_UNSIGNED_INT_SIZE: c_uchar;
pub static WASM32_UNSIGNED_INT_ALIGN: c_uchar;
pub static WASM32_SIZE_T_SIZE: c_uchar;
pub static WASM32_SIZE_T_ALIGN: c_uchar;
pub static WASM32_UNSIGNED_CHAR_SIZE: c_uchar;
pub static WASM32_UNSIGNED_CHAR_ALIGN: c_uchar;
pub static WASM32_PTR_SIZE: c_uchar;
pub static WASM32_PTR_ALIGN: c_uchar;
}
unsafe {
assert_eq!(size_of::<c_int>(), WASM32_INT_SIZE as usize);
assert_eq!(align_of::<c_int>(), WASM32_INT_ALIGN as usize);
assert_eq!(size_of::<c_uint>(), WASM32_UNSIGNED_INT_SIZE as usize);
assert_eq!(align_of::<c_uint>(), WASM32_UNSIGNED_INT_ALIGN as usize);
assert_eq!(size_of::<size_t>(), WASM32_SIZE_T_SIZE as usize);
assert_eq!(align_of::<size_t>(), WASM32_SIZE_T_ALIGN as usize);
assert_eq!(size_of::<c_uchar>(), WASM32_UNSIGNED_CHAR_SIZE as usize);
assert_eq!(align_of::<c_uchar>(), WASM32_UNSIGNED_CHAR_ALIGN as usize);
assert_eq!(size_of::<*const ()>(), WASM32_PTR_SIZE as usize);
assert_eq!(align_of::<*const ()>(), WASM32_PTR_ALIGN as usize);
}
}

View File

@ -0,0 +1,17 @@
#include <stddef.h>
#define alignof(type) offsetof (struct { char c; type member; }, member)
extern const unsigned char WASM32_INT_SIZE = sizeof(int);
extern const unsigned char WASM32_INT_ALIGN = alignof(int);
extern const unsigned char WASM32_UNSIGNED_INT_SIZE = sizeof(unsigned int);
extern const unsigned char WASM32_UNSIGNED_INT_ALIGN = alignof(unsigned int);
extern const unsigned char WASM32_SIZE_T_SIZE = sizeof(size_t);
extern const unsigned char WASM32_SIZE_T_ALIGN = alignof(size_t);
extern const unsigned char WASM32_UNSIGNED_CHAR_SIZE = sizeof(unsigned char);
extern const unsigned char WASM32_UNSIGNED_CHAR_ALIGN = alignof(unsigned char);
extern const unsigned char WASM32_PTR_SIZE = sizeof(void*);
extern const unsigned char WASM32_PTR_ALIGN = alignof(void*);

View File

@ -106,6 +106,9 @@ mod std_only {
impl<C: Context> Secp256k1<C> {
/// Lets you create a context in a generic manner(sign/verify/all)
pub fn gen_new() -> Secp256k1<C> {
#[cfg(target_arch = "wasm32")]
ffi::types::sanity_checks_for_wasm();
let buf = vec![0u8; Self::preallocate_size_gen()].into_boxed_slice();
let ptr = Box::into_raw(buf);
Secp256k1 {
@ -192,6 +195,9 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> {
impl<'buf, C: Context + 'buf> Secp256k1<C> {
/// Lets you create a context with preallocated buffer in a generic manner(sign/verify/all)
pub fn preallocated_gen_new(buf: &'buf mut [u8]) -> Result<Secp256k1<C>, Error> {
#[cfg(target_arch = "wasm32")]
ffi::types::sanity_checks_for_wasm();
if buf.len() < Self::preallocate_size_gen() {
return Err(Error::NotEnoughMemory);
}