From 6bffe0e09738fc47eacf66f9d138dd434f5aebdf Mon Sep 17 00:00:00 2001 From: Rodrigo Rivas Costa Date: Fri, 12 Oct 2018 21:08:48 +0200 Subject: [PATCH] Add basic wasm32: C types and malloc/realloc/free. --- src/lib.rs | 8 ++++--- src/wasm32.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/wasm32.rs diff --git a/src/lib.rs b/src/lib.rs index c997960a4b29c..95604fe60d222 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,9 +102,8 @@ extern crate std as core; mod dox; /* - * `c_void` should be defined for all targets except wasm. + * `c_void` should be defined for all targets */ -#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] cfg_if! { if #[cfg(core_cvoid)] { pub use core::ffi::c_void; @@ -125,7 +124,10 @@ cfg_if! { cfg_if! { if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] { - // empty ... + // wasm32-unknown-unknown does not have a real C library. + // Some useful definitions are in the wasm32.rs file. + mod wasm32; + pub use wasm32::*; } else if #[cfg(target_os = "switch")] { // On the Switch, we only define some useful universal types for // convenience. Those can be found in the switch.rs file. diff --git a/src/wasm32.rs b/src/wasm32.rs new file mode 100644 index 0000000000000..340c550bf57ac --- /dev/null +++ b/src/wasm32.rs @@ -0,0 +1,66 @@ +pub type int8_t = i8; +pub type int16_t = i16; +pub type int32_t = i32; +pub type int64_t = i64; +pub type uint8_t = u8; +pub type uint16_t = u16; +pub type uint32_t = u32; +pub type uint64_t = u64; + +pub type c_char = u8; +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; +pub type off_t = u64; + +const MALLOC_HEADER : isize = 8; +const MALLOC_ALIGN : usize = 8; + +use super::c_void; +use std::alloc::{self, Layout}; +use std::ptr; + +pub unsafe fn malloc(size: size_t) -> *mut c_void { + let lay = Layout::from_size_align_unchecked(MALLOC_HEADER as usize + size, MALLOC_ALIGN); + let p = alloc::alloc(lay); + if p.is_null() { + return ptr::null_mut(); + } + *(p as *mut size_t) = size; + p.offset(MALLOC_HEADER) as *mut c_void +} +pub unsafe fn free(p: *mut c_void) { + let p = p.offset(-MALLOC_HEADER) as *mut u8; + let size = *(p as *mut size_t); + let lay = Layout::from_size_align_unchecked(MALLOC_HEADER as usize + size, MALLOC_ALIGN); + alloc::dealloc(p, lay); +} +pub unsafe fn realloc(p: *mut c_void, _size: size_t) -> *mut c_void { + let p = p.offset(-MALLOC_HEADER) as *mut u8; + let size = *(p as *mut size_t); + let lay = Layout::from_size_align_unchecked(MALLOC_HEADER as usize + size, MALLOC_ALIGN); + let p = alloc::realloc(p, lay, size); + if p.is_null() { + return ptr::null_mut(); + } + *(p as *mut size_t) = size; + p.offset(MALLOC_HEADER) as *mut c_void +} +