Skip to content

Commit

Permalink
Implement To/FromWasmAbi traits for boxed slices of JsValue wrappers
Browse files Browse the repository at this point in the history
  • Loading branch information
Jules-Bertholet committed Jul 9, 2021
1 parent eb855e3 commit afdbda2
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
4 changes: 3 additions & 1 deletion crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ impl ToTokens for ast::ImportType {
use wasm_bindgen::convert::{OptionIntoWasmAbi, OptionFromWasmAbi};
use wasm_bindgen::convert::RefFromWasmAbi;
use wasm_bindgen::describe::WasmDescribe;
use wasm_bindgen::{JsValue, JsCast};
use wasm_bindgen::{JsValue, JsCast, JsObject};
use wasm_bindgen::__rt::core;

impl WasmDescribe for #rust_name {
Expand Down Expand Up @@ -761,6 +761,8 @@ impl ToTokens for ast::ImportType {
}
}

impl JsObject for #rust_name {}

()
};
})
Expand Down
5 changes: 4 additions & 1 deletion src/cast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::JsValue;
use crate::{describe::WasmDescribe, JsValue};

/// A trait for checked and unchecked casting between JS types.
///
Expand Down Expand Up @@ -154,3 +154,6 @@ where
/// won't need to call this.
fn unchecked_from_js_ref(val: &JsValue) -> &Self;
}

/// Trait implemented for wrappers around `JsValue`s generated by `#[wasm_bindgen]`.
pub trait JsObject: JsCast + WasmDescribe {}
38 changes: 38 additions & 0 deletions src/convert/slices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::prelude::v1::*;
use core::slice;
use core::str;

use crate::cast::JsObject;
use crate::convert::OptionIntoWasmAbi;
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
use cfg_if::cfg_if;
Expand Down Expand Up @@ -270,4 +271,41 @@ if_std! {
#[inline]
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
}

impl<T> IntoWasmAbi for Box<[T]> where T: JsObject {
type Abi = WasmSlice;

#[inline]
fn into_abi(self) -> WasmSlice {
let ptr = self.as_ptr();
let len = self.len();
mem::forget(self);
WasmSlice {
ptr: ptr.into_abi(),
len: len as u32,
}
}
}

impl<T> OptionIntoWasmAbi for Box<[T]> where T: JsObject {
#[inline]
fn none() -> WasmSlice { null_slice() }
}

impl<T> FromWasmAbi for Box<[T]> where T: JsObject {
type Abi = WasmSlice;

#[inline]
unsafe fn from_abi(js: WasmSlice) -> Self {
let ptr = <*mut JsValue>::from_abi(js.ptr);
let len = js.len as usize;
let vec: Vec<T> = Vec::from_raw_parts(ptr, len, len).drain(..).map(|js_value| T::unchecked_from_js(js_value)).collect();
return vec.into_boxed_slice();
}
}

impl<T> OptionFromWasmAbi for Box<[T]> where T: JsObject {
#[inline]
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub mod describe;

mod cast;
pub use crate::cast::JsCast;
pub use crate::cast::JsObject;

if_std! {
extern crate std;
Expand Down

0 comments on commit afdbda2

Please sign in to comment.