Skip to content

Commit

Permalink
Add Option<*const|mut T> and NonNull<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Feb 23, 2024
1 parent 557e2e6 commit 266ecfd
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* Add `TryFrom` implementations for `Number`, that allow losslessly converting from 64- and 128-bits numbers.
[#3847](https://github.com/rustwasm/wasm-bindgen/pull/3847)

* Add support for `Option<*const T>`, `Option<*mut T>` and `NonNull<T>`.
[#3852](https://github.com/rustwasm/wasm-bindgen/pull/3852)

### Fixed

* Make .wasm output deterministic when using `--reference-types`.
Expand Down
12 changes: 12 additions & 0 deletions examples/guide-supported-types-examples/non_null.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {
take_pointer_by_value,
return_pointer,
} from './guide_supported_types_examples';
import { memory } from './guide_supported_types_examples_bg';

let ptr = return_pointer();
let buf = new Uint8Array(memory.buffer);
let value = buf[ptr];
console.log(`The byte at the ${ptr} address is ${value}`);

take_pointer_by_value(ptr);
13 changes: 13 additions & 0 deletions examples/guide-supported-types-examples/src/non_null.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::ptr;
use std::ptr::NonNull;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub unsafe fn take_pointer_by_value(x: Option<NonNull<u8>>) {
Box::from_raw(x.unwrap().as_ptr());
}

#[wasm_bindgen]
pub fn return_pointer() -> Option<NonNull<u8>> {
NonNull::from(Box::new(42).leak())
}
3 changes: 2 additions & 1 deletion guide/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
- [Exported Rust Types](./reference/types/exported-rust-types.md)
- [`JsValue`](./reference/types/jsvalue.md)
- [`Box<[T]>` and `Vec<T>`](./reference/types/boxed-slices.md)
- [`*const T` and `*mut T`](./reference/types/pointers.md)
- [`*const T`, `*mut T`](./reference/types/pointers.md)
- [`NonNull<T>`](./reference/types/non-null.md)
- [Numbers](./reference/types/numbers.md)
- [`bool`](./reference/types/bool.md)
- [`char`](./reference/types/char.md)
Expand Down
17 changes: 17 additions & 0 deletions guide/src/reference/types/non-null.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# `*const T` and `*mut T`

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| No | No | No | Yes | Yes | Yes | A JavaScript number value |

## Example Rust Usage

```rust
{{#include ../../../../examples/guide-supported-types-examples/src/non_null.rs}}
```

## Example JavaScript Usage

```js
{{#include ../../../../examples/guide-supported-types-examples/non_null.js}}
```
2 changes: 1 addition & 1 deletion guide/src/reference/types/pointers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript number value |
| Yes | No | No | Yes | Yes | Yes | A JavaScript number value |

## Example Rust Usage

Expand Down
54 changes: 54 additions & 0 deletions src/convert/impls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::char;
use core::mem::{self, ManuallyDrop};
use core::ptr::NonNull;

use crate::convert::traits::{WasmAbi, WasmPrimitive};
use crate::convert::TryFromJsValue;
Expand Down Expand Up @@ -223,6 +224,20 @@ impl<T> FromWasmAbi for *const T {
}
}

impl<T> OptionIntoWasmAbi for *const T {
#[inline]
fn none() -> u32 {
0
}
}

impl<T> OptionFromWasmAbi for *const T {
#[inline]
fn is_none(js: &u32) -> bool {
*js == 0
}
}

impl<T> IntoWasmAbi for *mut T {
type Abi = u32;

Expand All @@ -241,6 +256,45 @@ impl<T> FromWasmAbi for *mut T {
}
}

impl<T> OptionIntoWasmAbi for *mut T {
#[inline]
fn none() -> u32 {
0
}
}

impl<T> OptionFromWasmAbi for *mut T {
#[inline]
fn is_none(js: &u32) -> bool {
*js == 0
}
}

impl<T> IntoWasmAbi for NonNull<T> {
type Abi = u32;

#[inline]
fn into_abi(self) -> u32 {
self.as_ptr() as u32
}
}

impl<T> OptionIntoWasmAbi for NonNull<T> {
#[inline]
fn none() -> u32 {
0
}
}

impl<T> FromWasmAbi for Option<NonNull<T>> {
type Abi = u32;

#[inline]
unsafe fn from_abi(js: Self::Abi) -> Self {
NonNull::new(js as *mut T)
}
}

impl IntoWasmAbi for JsValue {
type Abi = u32;

Expand Down
8 changes: 8 additions & 0 deletions src/describe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#![doc(hidden)]

use core::ptr::NonNull;

use crate::{Clamped, JsError, JsObject, JsValue};
use cfg_if::cfg_if;

Expand Down Expand Up @@ -114,6 +116,12 @@ impl<T> WasmDescribe for *mut T {
}
}

impl<T> WasmDescribe for NonNull<T> {
fn describe() {
inform(U32)
}
}

impl<T: WasmDescribe> WasmDescribe for [T] {
fn describe() {
inform(SLICE);
Expand Down
16 changes: 16 additions & 0 deletions tests/wasm/simple.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ptr::NonNull;

use wasm_bindgen::prelude::*;
use wasm_bindgen::{intern, unintern};
use wasm_bindgen_test::*;
Expand Down Expand Up @@ -62,6 +64,20 @@ pub unsafe fn simple_raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32
a
}

#[wasm_bindgen]
pub unsafe fn simple_option_raw_pointers_work(
a: Option<*mut u32>,
b: Option<*const u8>,
) -> Option<*const u32> {
*a.unwrap() = *b.unwrap() as u32;
a.map(|ptr| ptr as *const _)
}

#[wasm_bindgen]
pub unsafe fn simple_option_nonnull_work(a: Option<NonNull<u32>>) -> Option<NonNull<u32>> {
a
}

#[wasm_bindgen_test]
fn string_arguments() {
test_string_arguments();
Expand Down

0 comments on commit 266ecfd

Please sign in to comment.