Skip to content

Commit

Permalink
Add support for number slices of type MaybeUninit<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Dec 6, 2024
1 parent 94b2dc6 commit 2c6b2d0
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 88 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* Add support for multi-threading in Node.js.
[#4318](https://github.com/rustwasm/wasm-bindgen/pull/4318)

* Add support for number slices of type `MaybeUninit<T>`.
[#4316](https://github.com/rustwasm/wasm-bindgen/pull/4316)

### Changed

* Add clear error message to communicate new feature resolver version requirements.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ wasm-bindgen-test = { path = 'crates/test' }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
js-sys = { path = 'crates/js-sys' }
paste = "1"
serde_derive = "1.0"
wasm-bindgen-futures = { path = 'crates/futures' }
wasm-bindgen-test-crate-a = { path = 'tests/crates/a' }
Expand Down
2 changes: 1 addition & 1 deletion guide/src/reference/types/boxed-number-slices.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Boxed Number Slices: `Box<[u8]>`, `Box<[i8]>`, `Box<[u16]>`, `Box<[i16]>`, `Box<[u32]>`, `Box<[i32]>`, `Box<[u64]>`, `Box<[i64]>`, `Box<[f32]>`, and `Box<[f64]>`
# Boxed Number Slices: `Box<[u8]>`, `Box<[i8]>`, `Box<[u16]>`, `Box<[i16]>`, `Box<[u32]>`, `Box<[i32]>`, `Box<[u64]>`, `Box<[i64]>`, `Box<[f32]>`, `Box<[f64]>`, `Box<[MaybeUninit<u8>]>`, `Box<[MaybeUninit<i8>]>`, `Box<[MaybeUninit<u16>]>`, `Box<[MaybeUninit<i16>]>`, `Box<[MaybeUninit<u32>]>`, `Box<[MaybeUninit<i32>]>`, `Box<[MaybeUninit<u64>]>`, `Box<[MaybeUninit<i64>]>`, `Box<[MaybeUninit<f32>]>`, and `Box<[MaybeUninit<f64>]>`

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
Expand Down
2 changes: 1 addition & 1 deletion guide/src/reference/types/number-slices.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Number Slices: `[u8]`, `[i8]`, `[u16]`, `[i16]`, `[u32]`, `[i32]`, `[u64]`, `[i64]`, `[f32]`, and `[f64]`
# Number Slices: `[u8]`, `[i8]`, `[u16]`, `[i16]`, `[u32]`, `[i32]`, `[u64]`, `[i64]`, `[f32]`, `[f64]`, `[MaybeUninit<u8>]`, `[MaybeUninit<i8>]`, `[MaybeUninit<u16>]`, `[MaybeUninit<i16>]`, `[MaybeUninit<u32>]`, `[MaybeUninit<i32>]`, `[MaybeUninit<u64>]`, `[MaybeUninit<i64>]`, `[MaybeUninit<f32>]`, and `[MaybeUninit<f64>]`

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<&T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
Expand Down
23 changes: 17 additions & 6 deletions src/convert/slices.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::mem;
use core::mem::{self, MaybeUninit};
use core::ops::{Deref, DerefMut};
use core::str;

Expand Down Expand Up @@ -118,12 +118,19 @@ impl<T> DerefMut for MutSlice<T> {
}

macro_rules! vectors {
($($t:ident)*) => ($(
($($t:ty)*) => ($(
vectors_internal!($t);
vectors_internal!(MaybeUninit<$t>);
)*)
}

macro_rules! vectors_internal {
($t:ty) => {
impl WasmDescribeVector for $t {
#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
fn describe_vector() {
inform(VECTOR);
$t::describe();
<$t>::describe();
}
}

Expand Down Expand Up @@ -167,7 +174,9 @@ macro_rules! vectors {

impl<'a> OptionIntoWasmAbi for &'a [$t] {
#[inline]
fn none() -> WasmSlice { null_slice() }
fn none() -> WasmSlice {
null_slice()
}
}

impl<'a> IntoWasmAbi for &'a mut [$t] {
Expand All @@ -181,7 +190,9 @@ macro_rules! vectors {

impl<'a> OptionIntoWasmAbi for &'a mut [$t] {
#[inline]
fn none() -> WasmSlice { null_slice() }
fn none() -> WasmSlice {
null_slice()
}
}

impl RefFromWasmAbi for [$t] {
Expand Down Expand Up @@ -215,7 +226,7 @@ macro_rules! vectors {
Self::ref_from_abi(js)
}
}
)*)
};
}

vectors! {
Expand Down
9 changes: 8 additions & 1 deletion src/describe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::ptr::NonNull;
use core::{mem::MaybeUninit, ptr::NonNull};

use crate::{Clamped, JsError, JsObject, JsValue};
use cfg_if::cfg_if;
Expand Down Expand Up @@ -229,6 +229,13 @@ impl<T: WasmDescribe, E: Into<JsValue>> WasmDescribe for Result<T, E> {
}
}

impl<T: WasmDescribe> WasmDescribe for MaybeUninit<T> {
#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
fn describe() {
T::describe();
}
}

impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
fn describe() {
Expand Down
85 changes: 85 additions & 0 deletions tests/wasm/slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,30 @@ exports.js_export = () => {
i8[1] = 2;
assert.deepStrictEqual(wasm.export_i8(i8), i8);
assert.deepStrictEqual(wasm.export_optional_i8(i8), i8);
assert.deepStrictEqual(wasm.export_uninit_i8(i8), i8);
assert.deepStrictEqual(wasm.export_optional_uninit_i8(i8), i8);
const u8 = new Uint8Array(2);
u8[0] = 1;
u8[1] = 2;
assert.deepStrictEqual(wasm.export_u8(u8), u8);
assert.deepStrictEqual(wasm.export_optional_u8(u8), u8);
assert.deepStrictEqual(wasm.export_uninit_u8(u8), u8);
assert.deepStrictEqual(wasm.export_optional_uninit_u8(u8), u8);

const i16 = new Int16Array(2);
i16[0] = 1;
i16[1] = 2;
assert.deepStrictEqual(wasm.export_i16(i16), i16);
assert.deepStrictEqual(wasm.export_optional_i16(i16), i16);
assert.deepStrictEqual(wasm.export_uninit_i16(i16), i16);
assert.deepStrictEqual(wasm.export_optional_uninit_i16(i16), i16);
const u16 = new Uint16Array(2);
u16[0] = 1;
u16[1] = 2;
assert.deepStrictEqual(wasm.export_u16(u16), u16);
assert.deepStrictEqual(wasm.export_optional_u16(u16), u16);
assert.deepStrictEqual(wasm.export_uninit_u16(u16), u16);
assert.deepStrictEqual(wasm.export_optional_uninit_u16(u16), u16);

const i32 = new Int32Array(2);
i32[0] = 1;
Expand All @@ -31,24 +39,36 @@ exports.js_export = () => {
assert.deepStrictEqual(wasm.export_optional_i32(i32), i32);
assert.deepStrictEqual(wasm.export_isize(i32), i32);
assert.deepStrictEqual(wasm.export_optional_isize(i32), i32);
assert.deepStrictEqual(wasm.export_uninit_i32(i32), i32);
assert.deepStrictEqual(wasm.export_optional_uninit_i32(i32), i32);
assert.deepStrictEqual(wasm.export_uninit_isize(i32), i32);
assert.deepStrictEqual(wasm.export_optional_uninit_isize(i32), i32);
const u32 = new Uint32Array(2);
u32[0] = 1;
u32[1] = 2;
assert.deepStrictEqual(wasm.export_u32(u32), u32);
assert.deepStrictEqual(wasm.export_optional_u32(u32), u32);
assert.deepStrictEqual(wasm.export_usize(u32), u32);
assert.deepStrictEqual(wasm.export_optional_usize(u32), u32);
assert.deepStrictEqual(wasm.export_uninit_u32(u32), u32);
assert.deepStrictEqual(wasm.export_optional_uninit_u32(u32), u32);
assert.deepStrictEqual(wasm.export_uninit_usize(u32), u32);
assert.deepStrictEqual(wasm.export_optional_uninit_usize(u32), u32);

const f32 = new Float32Array(2);
f32[0] = 1;
f32[1] = 2;
assert.deepStrictEqual(wasm.export_f32(f32), f32);
assert.deepStrictEqual(wasm.export_optional_f32(f32), f32);
assert.deepStrictEqual(wasm.export_uninit_f32(f32), f32);
assert.deepStrictEqual(wasm.export_optional_uninit_f32(f32), f32);
const f64 = new Float64Array(2);
f64[0] = 1;
f64[1] = 2;
assert.deepStrictEqual(wasm.export_f64(f64), f64);
assert.deepStrictEqual(wasm.export_optional_f64(f64), f64);
assert.deepStrictEqual(wasm.export_uninit_f64(f64), f64);
assert.deepStrictEqual(wasm.export_optional_uninit_f64(f64), f64);

assert.strictEqual(wasm.export_optional_i8(undefined), undefined);
assert.strictEqual(wasm.export_optional_u8(undefined), undefined);
Expand All @@ -60,6 +80,17 @@ exports.js_export = () => {
assert.strictEqual(wasm.export_optional_usize(undefined), undefined);
assert.strictEqual(wasm.export_optional_f32(undefined), undefined);
assert.strictEqual(wasm.export_optional_f64(undefined), undefined);

assert.strictEqual(wasm.export_optional_uninit_i8(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_u8(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_i16(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_u16(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_i32(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_isize(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_u32(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_usize(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_f32(undefined), undefined);
assert.strictEqual(wasm.export_optional_uninit_f64(undefined), undefined);
};

const test_import = (a, b, c) => {
Expand All @@ -84,44 +115,65 @@ exports.import_js_usize = test_import;
exports.import_js_f32 = test_import;
exports.import_js_f64 = test_import;

exports.import_js_uninit_i8 = test_import;
exports.import_js_uninit_u8 = test_import;
exports.import_js_uninit_i16 = test_import;
exports.import_js_uninit_u16 = test_import;
exports.import_js_uninit_i32 = test_import;
exports.import_js_uninit_isize = test_import;
exports.import_js_uninit_u32 = test_import;
exports.import_js_uninit_usize = test_import;
exports.import_js_uninit_f32 = test_import;
exports.import_js_uninit_f64 = test_import;

exports.js_import = () => {
const i8 = new Int8Array(2);
i8[0] = 1;
i8[1] = 2;
assert.deepStrictEqual(wasm.import_rust_i8(i8), i8);
assert.deepStrictEqual(wasm.import_rust_uninit_i8(i8), i8);
const u8 = new Uint8Array(2);
u8[0] = 1;
u8[1] = 2;
assert.deepStrictEqual(wasm.import_rust_u8(u8), u8);
assert.deepStrictEqual(wasm.import_rust_uninit_u8(u8), u8);

const i16 = new Int16Array(2);
i16[0] = 1;
i16[1] = 2;
assert.deepStrictEqual(wasm.import_rust_i16(i16), i16);
assert.deepStrictEqual(wasm.import_rust_uninit_i16(i16), i16);
const u16 = new Uint16Array(2);
u16[0] = 1;
u16[1] = 2;
assert.deepStrictEqual(wasm.import_rust_u16(u16), u16);
assert.deepStrictEqual(wasm.import_rust_uninit_u16(u16), u16);

const i32 = new Int32Array(2);
i32[0] = 1;
i32[1] = 2;
assert.deepStrictEqual(wasm.import_rust_i32(i32), i32);
assert.deepStrictEqual(wasm.import_rust_isize(i32), i32);
assert.deepStrictEqual(wasm.import_rust_uninit_i32(i32), i32);
assert.deepStrictEqual(wasm.import_rust_uninit_isize(i32), i32);
const u32 = new Uint32Array(2);
u32[0] = 1;
u32[1] = 2;
assert.deepStrictEqual(wasm.import_rust_u32(u32), u32);
assert.deepStrictEqual(wasm.import_rust_usize(u32), u32);
assert.deepStrictEqual(wasm.import_rust_uninit_u32(u32), u32);
assert.deepStrictEqual(wasm.import_rust_uninit_usize(u32), u32);

const f32 = new Float32Array(2);
f32[0] = 1;
f32[1] = 2;
assert.deepStrictEqual(wasm.import_rust_f32(f32), f32);
assert.deepStrictEqual(wasm.import_rust_uninit_f32(f32), f32);
const f64 = new Float64Array(2);
f64[0] = 1;
f64[1] = 2;
assert.deepStrictEqual(wasm.import_rust_f64(f64), f64);
assert.deepStrictEqual(wasm.import_rust_uninit_f64(f64), f64);
};

exports.js_pass_array = () => {
Expand All @@ -135,6 +187,17 @@ exports.js_pass_array = () => {
wasm.pass_array_rust_usize([1, 2]);
wasm.pass_array_rust_f32([1, 2]);
wasm.pass_array_rust_f64([1, 2]);

wasm.pass_array_rust_uninit_i8([1, 2]);
wasm.pass_array_rust_uninit_u8([1, 2]);
wasm.pass_array_rust_uninit_i16([1, 2]);
wasm.pass_array_rust_uninit_u16([1, 2]);
wasm.pass_array_rust_uninit_i32([1, 2]);
wasm.pass_array_rust_uninit_u32([1, 2]);
wasm.pass_array_rust_uninit_isize([1, 2]);
wasm.pass_array_rust_uninit_usize([1, 2]);
wasm.pass_array_rust_uninit_f32([1, 2]);
wasm.pass_array_rust_uninit_f64([1, 2]);
};

const import_mut_foo = (a, b, c) => {
Expand Down Expand Up @@ -163,6 +226,17 @@ exports.import_mut_js_usize = import_mut_foo;
exports.import_mut_js_f32 = import_mut_foo;
exports.import_mut_js_f64 = import_mut_foo;

exports.import_mut_js_uninit_i8 = import_mut_foo;
exports.import_mut_js_uninit_u8 = import_mut_foo;
exports.import_mut_js_uninit_i16 = import_mut_foo;
exports.import_mut_js_uninit_u16 = import_mut_foo;
exports.import_mut_js_uninit_i32 = import_mut_foo;
exports.import_mut_js_uninit_u32 = import_mut_foo;
exports.import_mut_js_uninit_isize = import_mut_foo;
exports.import_mut_js_uninit_usize = import_mut_foo;
exports.import_mut_js_uninit_f32 = import_mut_foo;
exports.import_mut_js_uninit_f64 = import_mut_foo;

const export_mut_run = (a, rust) => {
assert.strictEqual(a.length, 3);
a[0] = 1;
Expand All @@ -188,6 +262,17 @@ exports.js_export_mut = () => {
export_mut_run(new Uint32Array(3), wasm.export_mut_usize);
export_mut_run(new Float32Array(3), wasm.export_mut_f32);
export_mut_run(new Float64Array(3), wasm.export_mut_f64);

export_mut_run(new Int8Array(3), wasm.export_mut_uninit_i8);
export_mut_run(new Uint8Array(3), wasm.export_mut_uninit_u8);
export_mut_run(new Int16Array(3), wasm.export_mut_uninit_i16);
export_mut_run(new Uint16Array(3), wasm.export_mut_uninit_u16);
export_mut_run(new Int32Array(3), wasm.export_mut_uninit_i32);
export_mut_run(new Uint32Array(3), wasm.export_mut_uninit_u32);
export_mut_run(new Int32Array(3), wasm.export_mut_uninit_isize);
export_mut_run(new Uint32Array(3), wasm.export_mut_uninit_usize);
export_mut_run(new Float32Array(3), wasm.export_mut_uninit_f32);
export_mut_run(new Float64Array(3), wasm.export_mut_uninit_f64);
};

exports.js_return_vec = () => {
Expand Down
Loading

0 comments on commit 2c6b2d0

Please sign in to comment.