Skip to content

Commit

Permalink
impl wasm32-unknown-unknown support
Browse files Browse the repository at this point in the history
  • Loading branch information
quininer committed Jan 28, 2022
1 parent f5a7f38 commit ea28d3d
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 2 deletions.
3 changes: 2 additions & 1 deletion zstd-safe/zstd-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ features = ["parallel"]
libc = "0.2.45"

[features]
default = ["legacy"]
default = ["legacy", "dict_builder"]

debug = [] # Enable zstd debug logs
experimental = [] # Expose experimental ZSTD API
Expand All @@ -71,3 +71,4 @@ std = [] # Use std types instead of libc in bindgen
zstdmt = [] # Enable multi-thread support (with pthread)
thin = [] # Optimize binary by size
no_asm = [] # Disable ASM files (only on amd64 for decompression)
dict_builder = []
13 changes: 12 additions & 1 deletion zstd-safe/zstd-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ fn compile_zstd() {
"zstd/lib/common",
"zstd/lib/compress",
"zstd/lib/decompress",
#[cfg(feature = "dict_builder")]
"zstd/lib/dictBuilder",
#[cfg(feature = "legacy")]
"zstd/lib/legacy",
Expand Down Expand Up @@ -114,6 +115,14 @@ fn compile_zstd() {
config.file("zstd/lib/decompress/huf_decompress_amd64.S");
}

if env::var("CARGO_CFG_TARGET_ARCH").ok() == Some("wasm32".into()) {
println!("cargo:rerun-if-changed=wasm-shim/stdlib.h");
println!("cargo:rerun-if-changed=wasm-shim/string.h");

config.include("wasm-shim/");
config.define("XXH_STATIC_ASSERT", Some("0"));
}

// Some extra parameters
config.opt_level(3);
config.include("zstd/lib/");
Expand Down Expand Up @@ -152,7 +161,9 @@ fn compile_zstd() {
* 7+: events at every position (*very* verbose)
*/
#[cfg(feature = "debug")]
config.define("DEBUGLEVEL", Some("5"));
if env::var("CARGO_CFG_TARGET_ARCH").ok() != Some("wasm32".into()) {
config.define("DEBUGLEVEL", Some("5"));
}

set_pthread(&mut config);
set_legacy(&mut config);
Expand Down
50 changes: 50 additions & 0 deletions zstd-safe/zstd-sys/examples/it_work.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::convert::TryInto;

#[no_mangle]
pub extern "C" fn zstd_version() -> u32 {
unsafe {
zstd_sys::ZSTD_versionNumber()
}
}

macro_rules! zstd_check {
( $ret:expr ) => {{
let ret = $ret;
let error_code = unsafe {
zstd_sys::ZSTD_isError(ret)
};
assert_eq!(error_code, 0);
}}
}

#[no_mangle]
pub extern "C" fn test_compress() -> bool {
let fbuf = include_bytes!("../Cargo.toml");

let cbufsize = unsafe {
zstd_sys::ZSTD_compressBound(fbuf.len())
};
let mut cbuf = vec![0; cbufsize];

let csize = unsafe {
zstd_sys::ZSTD_compress(cbuf.as_mut_ptr().cast(), cbuf.len(), fbuf.as_ptr().cast(), fbuf.len(), 1)
};
zstd_check!(csize);
let cbuf = &cbuf[..csize];

let rsize = unsafe {
zstd_sys::ZSTD_getFrameContentSize(cbuf.as_ptr().cast(), cbuf.len())
};
let rsize = rsize.try_into().unwrap();
let mut rbuf = vec![0; rsize];

let dsize = unsafe {
zstd_sys::ZSTD_decompress(rbuf.as_mut_ptr().cast(), rbuf.len(), cbuf.as_ptr().cast(), cbuf.len())
};
zstd_check!(dsize);
assert_eq!(dsize, rsize);

&fbuf[..] == &rbuf[..]
}

fn main() {}
3 changes: 3 additions & 0 deletions zstd-safe/zstd-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#[cfg(feature = "std")]
extern crate std;

#[cfg(target_arch = "wasm32")]
mod wasm_shim;

// If running bindgen, we'll end up with the correct bindings anyway.
#[cfg(feature = "bindgen")]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
Expand Down
44 changes: 44 additions & 0 deletions zstd-safe/zstd-sys/src/wasm_shim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::os::raw::{c_void, c_int};
use std::alloc::{alloc, dealloc, Layout};


#[no_mangle]
pub extern "C" fn rust_zstd_wasm_shim_malloc(size: usize) -> *mut c_void {
unsafe {
let layout = Layout::from_size_align_unchecked(size, 1);
alloc(layout).cast()
}
}

#[no_mangle]
pub extern "C" fn rust_zstd_wasm_shim_calloc(nmemb: usize, size: usize) -> *mut c_void {
unsafe {
let layout = Layout::from_size_align_unchecked(size * nmemb, 1);
alloc(layout).cast()
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_zstd_wasm_shim_free(ptr: *mut c_void) {
// layout is not actually used
let layout = Layout::from_size_align_unchecked(1, 1);
dealloc(ptr.cast(), layout);
}

#[no_mangle]
pub unsafe extern "C" fn rust_zstd_wasm_shim_memcpy(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void {
std::ptr::copy_nonoverlapping(src as *const u8, dest as *mut u8, n);
dest
}

#[no_mangle]
pub unsafe extern "C" fn rust_zstd_wasm_shim_memmove(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void {
std::ptr::copy(src as *const u8, dest as *mut u8, n);
dest
}

#[no_mangle]
pub unsafe extern "C" fn rust_zstd_wasm_shim_memset(dest: *mut c_void, c: c_int, n: usize) -> *mut c_void {
std::ptr::write_bytes(dest as *mut u8, c as u8, n);
dest
}
22 changes: 22 additions & 0 deletions zstd-safe/zstd-sys/wasm-shim/stdlib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <stddef.h>

#ifndef _STDLIB_H
#define _STDLIB_H 1

void *rust_zstd_wasm_shim_malloc(size_t size);
void *rust_zstd_wasm_shim_calloc(size_t nmemb, size_t size);
void rust_zstd_wasm_shim_free(void *ptr);

inline void *malloc(size_t size) {
return rust_zstd_wasm_shim_malloc(size);
}

inline void *calloc(size_t nmemb, size_t size) {
return rust_zstd_wasm_shim_calloc(nmemb, size);
}

inline void free(void *ptr) {
rust_zstd_wasm_shim_free(ptr);
}

#endif // _STDLIB_H
22 changes: 22 additions & 0 deletions zstd-safe/zstd-sys/wasm-shim/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <stdlib.h>

#ifndef _STRING_H
#define _STRING_H 1

void *rust_zstd_wasm_shim_memcpy(void *restrict dest, const void *restrict src, size_t n);
void *rust_zstd_wasm_shim_memmove(void *dest, const void *src, size_t n);
void *rust_zstd_wasm_shim_memset(void *dest, int c, size_t n);

inline void *memcpy(void *restrict dest, const void *restrict src, size_t n) {
return rust_zstd_wasm_shim_memcpy(dest, src, n);
}

inline void *memmove(void *dest, const void *src, size_t n) {
return rust_zstd_wasm_shim_memmove(dest, src, n);
}

inline void *memset(void *dest, int c, size_t n) {
return rust_zstd_wasm_shim_memset(dest, c, n);
}

#endif // _STRING_H

0 comments on commit ea28d3d

Please sign in to comment.