Skip to content

Commit aa85faf

Browse files
sam-kirbyLicenser
authored andcommitted
feat(arch): add support for wasm32 with simd128 feature
closes #217
1 parent 45ba86b commit aa85faf

File tree

16 files changed

+459
-28
lines changed

16 files changed

+459
-28
lines changed

.cargo/config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
[build]
22
rustflags = ["-C", "target-cpu=native"]
3+
4+
[target.wasm32-unknown-unknown]
5+
rustflags = ["-C", "target-feature=+simd128"]
6+
7+
[target.wasm32-wasi]
8+
rustflags = ["-C", "target-feature=+simd128"]

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ rust-version = "1.49"
1414
[dependencies]
1515
beef = { version = "0.5", optional = true }
1616
halfbrown = "0.1"
17-
value-trait = { version = "0.2.1" }
18-
simdutf8 = { version = "0.1.3", features = ["public_imp", "aarch64_neon"] }
17+
value-trait = "0.2.10"
18+
simdutf8 = { version = "0.1.4", features = ["public_imp", "aarch64_neon"] }
1919

2020
# serde compatibilty
2121
serde = { version = "1", features = ["derive"], optional = true}
@@ -35,6 +35,8 @@ criterion = { version = "0.3", optional = true }
3535
[dev-dependencies]
3636
float-cmp = "0.9"
3737
getopts = "0.2"
38+
39+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
3840
proptest = "1.0"
3941

4042
[lib]

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ perf:
55
cargo +nightly run --example perf --features perf --release
66
clippy:
77
touch src/lib.rs
8-
cargo clippy
8+
cargo clippy
9+
wasmtest:
10+
cargo clean --target-dir target
11+
cargo build --tests --target wasm32-wasi --target-dir target
12+
wasmtime run --wasm-features=simd target/wasm32-wasi/debug/deps/simd_json*.wasm
13+
wasmtime run --dir=. --wasm-features=simd target/wasm32-wasi/debug/deps/jsonchecker*.wasm

src/lib.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,34 +171,42 @@ use crate::neon::stage1::{SimdInput, SIMDINPUT_LENGTH, SIMDJSON_PADDING};
171171
#[cfg(target_feature = "neon")]
172172
use simdutf8::basic::imp::aarch64::neon::ChunkedUtf8ValidatorImp;
173173

174+
#[cfg(target_feature = "simd128")]
175+
mod simd128;
176+
#[cfg(target_feature = "simd128")]
177+
pub use crate::simd128::deser::*;
178+
#[cfg(target_feature = "simd128")]
179+
use crate::simd128::stage1::{SimdInput, SIMDINPUT_LENGTH, SIMDJSON_PADDING};
180+
#[cfg(target_feature = "simd128")]
181+
use simdutf8::basic::imp::wasm32::simd128::ChunkedUtf8ValidatorImp;
182+
174183
// We import this as generics
175184
#[cfg(all(not(any(
176185
target_feature = "sse4.2",
177186
target_feature = "avx2",
178-
target_feature = "neon"
187+
target_feature = "neon",
188+
target_feature = "simd128"
179189
))))]
180190
mod sse42;
181191
#[cfg(all(not(any(
182192
target_feature = "sse4.2",
183193
target_feature = "avx2",
184-
target_feature = "neon"
185-
))))]
186-
#[cfg(all(not(any(
187-
target_feature = "sse4.2",
188-
target_feature = "avx2",
189-
target_feature = "neon"
194+
target_feature = "neon",
195+
target_feature = "simd128"
190196
))))]
191197
pub use crate::sse42::deser::*;
192198
#[cfg(all(not(any(
193199
target_feature = "sse4.2",
194200
target_feature = "avx2",
195-
target_feature = "neon"
201+
target_feature = "neon",
202+
target_feature = "simd128"
196203
))))]
197204
use crate::sse42::stage1::{SimdInput, SIMDINPUT_LENGTH, SIMDJSON_PADDING};
198205
#[cfg(all(not(any(
199206
target_feature = "sse4.2",
200207
target_feature = "avx2",
201-
target_feature = "neon"
208+
target_feature = "neon",
209+
target_feature = "simd128"
202210
))))]
203211
use simdutf8::basic::imp::x86::sse42::ChunkedUtf8ValidatorImp;
204212

@@ -207,7 +215,8 @@ use simdutf8::basic::imp::x86::sse42::ChunkedUtf8ValidatorImp;
207215
not(any(
208216
target_feature = "sse4.2",
209217
target_feature = "avx2",
210-
target_feature = "neon"
218+
target_feature = "neon",
219+
target_feature = "simd128"
211220
))
212221
))]
213222
fn please_compile_with_a_simd_compatible_cpu_setting_read_the_simdjsonrs_readme() -> ! {}
@@ -750,10 +759,15 @@ impl DerefMut for AlignedBuf {
750759
mod tests {
751760

752761
#![allow(clippy::unnecessary_operation, clippy::non_ascii_literal)]
753-
use super::{owned::Value, to_borrowed_value, to_owned_value, Deserializer};
762+
#[cfg(not(target_arch = "wasm32"))]
763+
use super::to_borrowed_value;
764+
use super::{owned::Value, to_owned_value, Deserializer};
754765
use crate::tape::Node;
766+
#[cfg(not(target_arch = "wasm32"))]
755767
use proptest::prelude::*;
756-
use value_trait::{StaticNode, Writable};
768+
#[cfg(not(target_arch = "wasm32"))]
769+
use value_trait::StaticNode;
770+
use value_trait::Writable;
757771

758772
#[test]
759773
fn test_send_sync() {
@@ -865,6 +879,7 @@ mod tests {
865879
assert_eq!(v, parsed);
866880
}
867881
#[cfg(not(feature = "128bit"))]
882+
#[cfg(not(target_arch = "wasm32"))]
868883
fn arb_json_value() -> BoxedStrategy<Value> {
869884
let leaf = prop_oneof![
870885
Just(Value::Static(StaticNode::Null)),
@@ -890,6 +905,7 @@ mod tests {
890905
}
891906

892907
#[cfg(feature = "128bit")]
908+
#[cfg(not(target_arch = "wasm32"))]
893909
fn arb_json_value() -> BoxedStrategy<Value> {
894910
let leaf = prop_oneof![
895911
Just(Value::Static(StaticNode::Null)),
@@ -916,6 +932,7 @@ mod tests {
916932
.boxed()
917933
}
918934

935+
#[cfg(not(target_arch = "wasm32"))]
919936
proptest! {
920937
#![proptest_config(ProptestConfig {
921938
// Setting both fork and timeout is redundant since timeout implies
@@ -958,6 +975,7 @@ mod tests_serde {
958975
use super::serde::from_slice;
959976
use super::{owned::to_value, owned::Object, owned::Value, to_borrowed_value, to_owned_value};
960977
use halfbrown::HashMap;
978+
#[cfg(not(target_arch = "wasm32"))]
961979
use proptest::prelude::*;
962980
use serde::Deserialize;
963981

@@ -1721,6 +1739,7 @@ mod tests_serde {
17211739
}
17221740

17231741
//6.576692109929364e305
1742+
#[cfg(not(target_arch = "wasm32"))]
17241743
fn arb_json() -> BoxedStrategy<String> {
17251744
let leaf = prop_oneof![
17261745
Just(Value::Static(StaticNode::Null)),
@@ -1747,6 +1766,7 @@ mod tests_serde {
17471766
.boxed()
17481767
}
17491768

1769+
#[cfg(not(target_arch = "wasm32"))]
17501770
proptest! {
17511771
#![proptest_config(ProptestConfig {
17521772
// Setting both fork and timeout is redundant since timeout implies
@@ -1782,9 +1802,11 @@ mod tests_serde {
17821802

17831803
}
17841804

1805+
#[cfg(not(target_arch = "wasm32"))]
17851806
fn arb_junk() -> BoxedStrategy<Vec<u8>> {
17861807
prop::collection::vec(any::<u8>(), 0..(1024 * 8)).boxed()
17871808
}
1809+
#[cfg(not(target_arch = "wasm32"))]
17881810
proptest! {
17891811
#![proptest_config(ProptestConfig {
17901812
// Setting both fork and timeout is redundant since timeout implies
@@ -1807,6 +1829,7 @@ mod tests_serde {
18071829
}
18081830
}
18091831

1832+
#[cfg(not(target_arch = "wasm32"))]
18101833
proptest! {
18111834
#![proptest_config(ProptestConfig {
18121835
// Setting both fork and timeout is redundant since timeout implies

src/neon/stage1.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ pub(crate) unsafe fn bit_mask() -> uint8x16_t {
1111
])
1212
}
1313

14-
// FIXME this needs to be upstream
15-
//
16-
// vtstq_u8
17-
// vmovq_n_s8
18-
19-
pub unsafe fn vtstq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
20-
vcgtq_u8(vandq_u8(a, b), vdupq_n_u8(0))
21-
}
22-
2314
#[cfg_attr(not(feature = "no-inline"), inline(always))]
2415
pub unsafe fn neon_movemask_bulk(
2516
p0: uint8x16_t,

src/numberparse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn parse_eight_digits_unrolled(chars: &[u8]) -> u32 {
160160
}
161161

162162
#[cfg_attr(not(feature = "no-inline"), inline)]
163-
#[cfg(target_feature = "neon")]
163+
#[cfg(any(target_feature = "neon", target_feature = "simd128"))]
164164
fn parse_eight_digits_unrolled(chars: &[u8]) -> u32 {
165165
let val: u64 = unsafe { *(chars.as_ptr() as *const u64) };
166166
// memcpy(&val, chars, sizeof(u64));

src/serde/se.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,9 @@ where
820820

821821
#[cfg(test)]
822822
mod test {
823+
#[cfg(not(target_arch = "wasm32"))]
823824
use crate::{OwnedValue as Value, StaticNode};
825+
#[cfg(not(target_arch = "wasm32"))]
824826
use proptest::prelude::*;
825827

826828
#[test]
@@ -871,6 +873,7 @@ mod test {
871873
}
872874

873875
#[cfg(not(feature = "128bit"))]
876+
#[cfg(not(target_arch = "wasm32"))]
874877
fn arb_json_value() -> BoxedStrategy<Value> {
875878
let leaf = prop_oneof![
876879
Just(Value::Static(StaticNode::Null)),
@@ -902,6 +905,7 @@ mod test {
902905
}
903906

904907
#[cfg(feature = "128bit")]
908+
#[cfg(not(target_arch = "wasm32"))]
905909
fn arb_json_value() -> BoxedStrategy<Value> {
906910
let leaf = prop_oneof![
907911
Just(Value::Static(StaticNode::Null)),
@@ -934,6 +938,7 @@ mod test {
934938
.boxed()
935939
}
936940

941+
#[cfg(not(target_arch = "wasm32"))]
937942
proptest! {
938943
#![proptest_config(ProptestConfig {
939944
// Setting both fork and timeout is redundant since timeout implies

src/serde/se/pp.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,13 @@ where
651651

652652
#[cfg(test)]
653653
mod test {
654+
#[cfg(not(target_arch = "wasm32"))]
654655
use crate::{OwnedValue as Value, StaticNode};
656+
#[cfg(not(target_arch = "wasm32"))]
655657
use proptest::prelude::*;
656658

657659
#[cfg(not(feature = "128bit"))]
660+
#[cfg(not(target_arch = "wasm32"))]
658661
fn arb_json_value() -> BoxedStrategy<Value> {
659662
let leaf = prop_oneof![
660663
Just(Value::Static(StaticNode::Null)),
@@ -686,6 +689,7 @@ mod test {
686689
}
687690

688691
#[cfg(feature = "128bit")]
692+
#[cfg(not(target_arch = "wasm32"))]
689693
fn arb_json_value() -> BoxedStrategy<Value> {
690694
let leaf = prop_oneof![
691695
Just(Value::Static(StaticNode::Null)),
@@ -718,6 +722,7 @@ mod test {
718722
.boxed()
719723
}
720724

725+
#[cfg(not(target_arch = "wasm32"))]
721726
proptest! {
722727
#![proptest_config(ProptestConfig {
723728
// Setting both fork and timeout is redundant since timeout implies

src/serde/value/borrowed/se.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,9 @@ mod test {
793793
assert_eq!(vec, vec3);
794794
}
795795

796+
#[cfg(not(target_arch = "wasm32"))]
796797
use proptest::prelude::*;
798+
#[cfg(not(target_arch = "wasm32"))]
797799
prop_compose! {
798800
fn obj_case()(
799801
v_i128 in any::<i64>().prop_map(i128::from),
@@ -831,6 +833,7 @@ mod test {
831833
}
832834
}
833835

836+
#[cfg(not(target_arch = "wasm32"))]
834837
proptest! {
835838
#![proptest_config(ProptestConfig {
836839
.. ProptestConfig::default()

src/serde/value/owned/se.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,9 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant {
642642

643643
#[cfg(test)]
644644
mod test {
645-
use crate::serde::{from_slice, from_str, to_string};
645+
use crate::serde::from_slice;
646+
#[cfg(not(target_arch = "wasm32"))]
647+
use crate::serde::{from_str, to_string};
646648
/*
647649
use crate::{
648650
owned::to_value, owned::Object, owned::Value, to_borrowed_value, to_owned_value,
@@ -729,7 +731,9 @@ mod test {
729731
assert_eq!(vec, vec3);
730732
}
731733

734+
#[cfg(not(target_arch = "wasm32"))]
732735
use proptest::prelude::*;
736+
#[cfg(not(target_arch = "wasm32"))]
733737
prop_compose! {
734738
fn obj_case()(
735739
v_i128 in any::<i64>().prop_map(i128::from),
@@ -775,6 +779,7 @@ mod test {
775779
}
776780
}
777781

782+
#[cfg(not(target_arch = "wasm32"))]
778783
proptest! {
779784
#![proptest_config(ProptestConfig {
780785
.. ProptestConfig::default()

0 commit comments

Comments
 (0)