mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-30 12:33:54 +03:00
Fix no-std compatibility (#4005)
This commit is contained in:
parent
7ad1a2703d
commit
06b347f908
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -37,6 +37,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- run: rustup update --no-self-update stable && rustup default stable
|
||||
- run: cargo check --all
|
||||
- run: cargo check --no-default-features
|
||||
|
||||
# Run `cargo clippy` over everything
|
||||
clippy:
|
||||
@ -66,6 +67,7 @@ jobs:
|
||||
- run: cargo clippy --no-deps --all-features -p wasm-bindgen-webidl -- -D warnings
|
||||
- run: cargo clippy --no-deps --all-features -p webidl-tests -- -D warnings
|
||||
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown -p web-sys -- -D warnings
|
||||
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -- -D warnings
|
||||
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown -- -D warnings
|
||||
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown --tests -- -D warnings
|
||||
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown -p wasm-bindgen-benchmark -- -D warnings
|
||||
|
@ -130,6 +130,9 @@
|
||||
* Fix `__wbindgen_thread_destroy()` ignoring parameters.
|
||||
[#3995](https://github.com/rustwasm/wasm-bindgen/pull/3995)
|
||||
|
||||
* Fix `no_std` support and therefor compiling with `default-features = false`.
|
||||
[#4005](https://github.com/rustwasm/wasm-bindgen/pull/4005)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## [0.2.92](https://github.com/rustwasm/wasm-bindgen/compare/0.2.91...0.2.92)
|
||||
|
@ -221,12 +221,6 @@ impl ToTokens for ast::Struct {
|
||||
impl #wasm_bindgen::describe::WasmDescribe for #name {
|
||||
fn describe() {
|
||||
use #wasm_bindgen::__wbindgen_if_not_std;
|
||||
__wbindgen_if_not_std! {
|
||||
compile_error! {
|
||||
"exporting a class to JS requires the `std` feature to \
|
||||
be enabled in the `wasm-bindgen` crate"
|
||||
}
|
||||
}
|
||||
use #wasm_bindgen::describe::*;
|
||||
inform(RUST_STRUCT);
|
||||
inform(#name_len);
|
||||
@ -239,7 +233,7 @@ impl ToTokens for ast::Struct {
|
||||
type Abi = u32;
|
||||
|
||||
fn into_abi(self) -> u32 {
|
||||
use #wasm_bindgen::__rt::std::rc::Rc;
|
||||
use #wasm_bindgen::__rt::alloc::rc::Rc;
|
||||
use #wasm_bindgen::__rt::WasmRefCell;
|
||||
Rc::into_raw(Rc::new(WasmRefCell::new(self))) as u32
|
||||
}
|
||||
@ -250,8 +244,8 @@ impl ToTokens for ast::Struct {
|
||||
type Abi = u32;
|
||||
|
||||
unsafe fn from_abi(js: u32) -> Self {
|
||||
use #wasm_bindgen::__rt::std::rc::Rc;
|
||||
use #wasm_bindgen::__rt::std::result::Result::{Ok, Err};
|
||||
use #wasm_bindgen::__rt::alloc::rc::Rc;
|
||||
use #wasm_bindgen::__rt::core::result::Result::{Ok, Err};
|
||||
use #wasm_bindgen::__rt::{assert_not_null, WasmRefCell};
|
||||
|
||||
let ptr = js as *mut WasmRefCell<#name>;
|
||||
@ -299,7 +293,7 @@ impl ToTokens for ast::Struct {
|
||||
// `allow_delayed` is whether it's ok to not actually free the `ptr` immediately
|
||||
// if it's still borrowed.
|
||||
pub unsafe extern "C" fn #free_fn(ptr: u32, allow_delayed: u32) {
|
||||
use #wasm_bindgen::__rt::std::rc::Rc;
|
||||
use #wasm_bindgen::__rt::alloc::rc::Rc;
|
||||
|
||||
if allow_delayed != 0 {
|
||||
// Just drop the implicit `Rc` owned by JS, and then if the value is still
|
||||
@ -320,7 +314,7 @@ impl ToTokens for ast::Struct {
|
||||
type Anchor = #wasm_bindgen::__rt::RcRef<#name>;
|
||||
|
||||
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
|
||||
use #wasm_bindgen::__rt::std::rc::Rc;
|
||||
use #wasm_bindgen::__rt::alloc::rc::Rc;
|
||||
|
||||
let js = js as *mut #wasm_bindgen::__rt::WasmRefCell<#name>;
|
||||
#wasm_bindgen::__rt::assert_not_null(js);
|
||||
@ -337,7 +331,7 @@ impl ToTokens for ast::Struct {
|
||||
type Anchor = #wasm_bindgen::__rt::RcRefMut<#name>;
|
||||
|
||||
unsafe fn ref_mut_from_abi(js: Self::Abi) -> Self::Anchor {
|
||||
use #wasm_bindgen::__rt::std::rc::Rc;
|
||||
use #wasm_bindgen::__rt::alloc::rc::Rc;
|
||||
|
||||
let js = js as *mut #wasm_bindgen::__rt::WasmRefCell<#name>;
|
||||
#wasm_bindgen::__rt::assert_not_null(js);
|
||||
@ -375,7 +369,7 @@ impl ToTokens for ast::Struct {
|
||||
type Error = #wasm_bindgen::JsValue;
|
||||
|
||||
fn try_from_js_value(value: #wasm_bindgen::JsValue)
|
||||
-> #wasm_bindgen::__rt::std::result::Result<Self, Self::Error> {
|
||||
-> #wasm_bindgen::__rt::core::result::Result<Self, Self::Error> {
|
||||
let idx = #wasm_bindgen::convert::IntoWasmAbi::into_abi(&value);
|
||||
|
||||
#[link(wasm_import_module = "__wbindgen_placeholder__")]
|
||||
@ -391,13 +385,13 @@ impl ToTokens for ast::Struct {
|
||||
|
||||
let ptr = unsafe { #unwrap_fn(idx) };
|
||||
if ptr == 0 {
|
||||
#wasm_bindgen::__rt::std::result::Result::Err(value)
|
||||
#wasm_bindgen::__rt::core::result::Result::Err(value)
|
||||
} else {
|
||||
// Don't run `JsValue`'s destructor, `unwrap_fn` already did that for us.
|
||||
#[allow(clippy::mem_forget)]
|
||||
#wasm_bindgen::__rt::std::mem::forget(value);
|
||||
#wasm_bindgen::__rt::core::mem::forget(value);
|
||||
unsafe {
|
||||
#wasm_bindgen::__rt::std::result::Result::Ok(
|
||||
#wasm_bindgen::__rt::core::result::Result::Ok(
|
||||
<Self as #wasm_bindgen::convert::FromWasmAbi>::from_abi(ptr)
|
||||
)
|
||||
}
|
||||
@ -417,12 +411,12 @@ impl ToTokens for ast::Struct {
|
||||
|
||||
impl #wasm_bindgen::convert::VectorIntoWasmAbi for #name {
|
||||
type Abi = <
|
||||
#wasm_bindgen::__rt::std::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
#wasm_bindgen::__rt::alloc::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
as #wasm_bindgen::convert::IntoWasmAbi
|
||||
>::Abi;
|
||||
|
||||
fn vector_into_abi(
|
||||
vector: #wasm_bindgen::__rt::std::boxed::Box<[#name]>
|
||||
vector: #wasm_bindgen::__rt::alloc::boxed::Box<[#name]>
|
||||
) -> Self::Abi {
|
||||
#wasm_bindgen::convert::js_value_vector_into_abi(vector)
|
||||
}
|
||||
@ -430,19 +424,19 @@ impl ToTokens for ast::Struct {
|
||||
|
||||
impl #wasm_bindgen::convert::VectorFromWasmAbi for #name {
|
||||
type Abi = <
|
||||
#wasm_bindgen::__rt::std::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
#wasm_bindgen::__rt::alloc::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
as #wasm_bindgen::convert::FromWasmAbi
|
||||
>::Abi;
|
||||
|
||||
unsafe fn vector_from_abi(
|
||||
js: Self::Abi
|
||||
) -> #wasm_bindgen::__rt::std::boxed::Box<[#name]> {
|
||||
) -> #wasm_bindgen::__rt::alloc::boxed::Box<[#name]> {
|
||||
#wasm_bindgen::convert::js_value_vector_from_abi(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl #wasm_bindgen::__rt::VectorIntoJsValue for #name {
|
||||
fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::std::boxed::Box<[#name]>) -> #wasm_bindgen::JsValue {
|
||||
fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::alloc::boxed::Box<[#name]>) -> #wasm_bindgen::JsValue {
|
||||
#wasm_bindgen::__rt::js_value_vector_into_jsvalue(vector)
|
||||
}
|
||||
}
|
||||
@ -597,7 +591,7 @@ impl TryToTokens for ast::Export {
|
||||
quote!(long_ref_from_abi),
|
||||
quote!(
|
||||
<<#class as #wasm_bindgen::convert::LongRefFromWasmAbi>
|
||||
::Anchor as #wasm_bindgen::__rt::std::borrow::Borrow<#class>>
|
||||
::Anchor as #wasm_bindgen::__rt::core::borrow::Borrow<#class>>
|
||||
::borrow(&me)
|
||||
),
|
||||
)
|
||||
@ -1589,13 +1583,13 @@ impl ToTokens for ast::Enum {
|
||||
type Error = #wasm_bindgen::JsValue;
|
||||
|
||||
fn try_from_js_value(value: #wasm_bindgen::JsValue)
|
||||
-> #wasm_bindgen::__rt::std::result::Result<Self, <#enum_name as #wasm_bindgen::convert::TryFromJsValue>::Error> {
|
||||
-> #wasm_bindgen::__rt::core::result::Result<Self, <#enum_name as #wasm_bindgen::convert::TryFromJsValue>::Error> {
|
||||
use #wasm_bindgen::__rt::core::convert::TryFrom;
|
||||
let js = f64::try_from(&value)? as u32;
|
||||
|
||||
#wasm_bindgen::__rt::std::result::Result::Ok(
|
||||
#wasm_bindgen::__rt::core::result::Result::Ok(
|
||||
#(#try_from_cast_clauses else)* {
|
||||
return #wasm_bindgen::__rt::std::result::Result::Err(value)
|
||||
return #wasm_bindgen::__rt::core::result::Result::Err(value)
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -1611,12 +1605,12 @@ impl ToTokens for ast::Enum {
|
||||
|
||||
impl #wasm_bindgen::convert::VectorIntoWasmAbi for #enum_name {
|
||||
type Abi = <
|
||||
#wasm_bindgen::__rt::std::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
#wasm_bindgen::__rt::alloc::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
as #wasm_bindgen::convert::IntoWasmAbi
|
||||
>::Abi;
|
||||
|
||||
fn vector_into_abi(
|
||||
vector: #wasm_bindgen::__rt::std::boxed::Box<[#enum_name]>
|
||||
vector: #wasm_bindgen::__rt::alloc::boxed::Box<[#enum_name]>
|
||||
) -> Self::Abi {
|
||||
#wasm_bindgen::convert::js_value_vector_into_abi(vector)
|
||||
}
|
||||
@ -1624,19 +1618,19 @@ impl ToTokens for ast::Enum {
|
||||
|
||||
impl #wasm_bindgen::convert::VectorFromWasmAbi for #enum_name {
|
||||
type Abi = <
|
||||
#wasm_bindgen::__rt::std::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
#wasm_bindgen::__rt::alloc::boxed::Box<[#wasm_bindgen::JsValue]>
|
||||
as #wasm_bindgen::convert::FromWasmAbi
|
||||
>::Abi;
|
||||
|
||||
unsafe fn vector_from_abi(
|
||||
js: Self::Abi
|
||||
) -> #wasm_bindgen::__rt::std::boxed::Box<[#enum_name]> {
|
||||
) -> #wasm_bindgen::__rt::alloc::boxed::Box<[#enum_name]> {
|
||||
#wasm_bindgen::convert::js_value_vector_from_abi(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl #wasm_bindgen::__rt::VectorIntoJsValue for #enum_name {
|
||||
fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::std::boxed::Box<[#enum_name]>) -> #wasm_bindgen::JsValue {
|
||||
fn vector_into_jsvalue(vector: #wasm_bindgen::__rt::alloc::boxed::Box<[#enum_name]>) -> #wasm_bindgen::JsValue {
|
||||
#wasm_bindgen::__rt::js_value_vector_into_jsvalue(vector)
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,10 @@
|
||||
|
||||
#![allow(clippy::fn_to_numeric_cast)]
|
||||
|
||||
use std::fmt;
|
||||
use std::mem::{self, ManuallyDrop};
|
||||
use std::prelude::v1::*;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use core::fmt;
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
|
||||
use crate::convert::*;
|
||||
use crate::describe::*;
|
||||
@ -356,7 +357,7 @@ where
|
||||
/// lifetime dynamically managed by the JS GC. This function can be used
|
||||
/// to drop this `Closure` while keeping the associated JS function still
|
||||
/// valid.
|
||||
///
|
||||
///
|
||||
/// If the platform supports weak references, the Rust memory will be
|
||||
/// reclaimed when the JS closure is GC'd. If weak references is not
|
||||
/// supported, this can be dangerous if this function is called many times
|
||||
@ -685,7 +686,7 @@ macro_rules! doit {
|
||||
}
|
||||
|
||||
fn into_js_function(self) -> JsValue {
|
||||
use std::rc::Rc;
|
||||
use alloc::rc::Rc;
|
||||
use crate::__rt::WasmRefCell;
|
||||
|
||||
let mut me = Some(self);
|
||||
@ -866,7 +867,7 @@ where
|
||||
|
||||
fn into_js_function(self) -> JsValue {
|
||||
use crate::__rt::WasmRefCell;
|
||||
use std::rc::Rc;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
let mut me = Some(self);
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use core::char;
|
||||
use core::fmt::Debug;
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::ptr::NonNull;
|
||||
|
||||
@ -8,12 +11,6 @@ use crate::convert::{FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, RefFromWasmAb
|
||||
use crate::convert::{OptionFromWasmAbi, OptionIntoWasmAbi, ReturnWasmAbi};
|
||||
use crate::{Clamped, JsError, JsValue, UnwrapThrowExt};
|
||||
|
||||
if_std! {
|
||||
use std::boxed::Box;
|
||||
use std::fmt::Debug;
|
||||
use std::vec::Vec;
|
||||
}
|
||||
|
||||
// Primitive types can always be passed over the ABI.
|
||||
impl<T: WasmPrimitive> WasmAbi for T {
|
||||
type Prim1 = Self;
|
||||
@ -473,36 +470,39 @@ impl IntoWasmAbi for JsError {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
// Note: this can't take `&[T]` because the `Into<JsValue>` impl needs
|
||||
// ownership of `T`.
|
||||
pub fn js_value_vector_into_abi<T: Into<JsValue>>(vector: Box<[T]>) -> <Box<[JsValue]> as IntoWasmAbi>::Abi {
|
||||
let js_vals: Box<[JsValue]> = vector
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect();
|
||||
// Note: this can't take `&[T]` because the `Into<JsValue>` impl needs
|
||||
// ownership of `T`.
|
||||
pub fn js_value_vector_into_abi<T: Into<JsValue>>(
|
||||
vector: Box<[T]>,
|
||||
) -> <Box<[JsValue]> as IntoWasmAbi>::Abi {
|
||||
let js_vals: Box<[JsValue]> = vector.into_vec().into_iter().map(|x| x.into()).collect();
|
||||
|
||||
js_vals.into_abi()
|
||||
}
|
||||
|
||||
pub unsafe fn js_value_vector_from_abi<T: TryFromJsValue>(js: <Box<[JsValue]> as FromWasmAbi>::Abi) -> Box<[T]> where T::Error: Debug {
|
||||
let js_vals = <Vec<JsValue> as FromWasmAbi>::from_abi(js);
|
||||
|
||||
let mut result = Vec::with_capacity(js_vals.len());
|
||||
for value in js_vals {
|
||||
// We push elements one-by-one instead of using `collect` in order to improve
|
||||
// error messages. When using `collect`, this `expect_throw` is buried in a
|
||||
// giant chain of internal iterator functions, which results in the actual
|
||||
// function that takes this `Vec` falling off the end of the call stack.
|
||||
// So instead, make sure to call it directly within this function.
|
||||
//
|
||||
// This is only a problem in debug mode. Since this is the browser's error stack
|
||||
// we're talking about, it can only see functions that actually make it to the
|
||||
// final wasm binary (i.e., not inlined functions). All of those internal
|
||||
// iterator functions get inlined in release mode, and so they don't show up.
|
||||
result.push(T::try_from_js_value(value).expect_throw("array contains a value of the wrong type"));
|
||||
}
|
||||
result.into_boxed_slice()
|
||||
}
|
||||
js_vals.into_abi()
|
||||
}
|
||||
|
||||
pub unsafe fn js_value_vector_from_abi<T: TryFromJsValue>(
|
||||
js: <Box<[JsValue]> as FromWasmAbi>::Abi,
|
||||
) -> Box<[T]>
|
||||
where
|
||||
T::Error: Debug,
|
||||
{
|
||||
let js_vals = <Vec<JsValue> as FromWasmAbi>::from_abi(js);
|
||||
|
||||
let mut result = Vec::with_capacity(js_vals.len());
|
||||
for value in js_vals {
|
||||
// We push elements one-by-one instead of using `collect` in order to improve
|
||||
// error messages. When using `collect`, this `expect_throw` is buried in a
|
||||
// giant chain of internal iterator functions, which results in the actual
|
||||
// function that takes this `Vec` falling off the end of the call stack.
|
||||
// So instead, make sure to call it directly within this function.
|
||||
//
|
||||
// This is only a problem in debug mode. Since this is the browser's error stack
|
||||
// we're talking about, it can only see functions that actually make it to the
|
||||
// final wasm binary (i.e., not inlined functions). All of those internal
|
||||
// iterator functions get inlined in release mode, and so they don't show up.
|
||||
result.push(
|
||||
T::try_from_js_value(value).expect_throw("array contains a value of the wrong type"),
|
||||
);
|
||||
}
|
||||
result.into_boxed_slice()
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
#[cfg(feature = "std")]
|
||||
use std::prelude::v1::*;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::mem;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::str;
|
||||
|
||||
use crate::__wbindgen_copy_to_typed_array;
|
||||
use crate::cast::JsObject;
|
||||
use crate::convert::OptionIntoWasmAbi;
|
||||
use crate::convert::{js_value_vector_from_abi, js_value_vector_into_abi};
|
||||
use crate::convert::{
|
||||
FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi,
|
||||
FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, OptionFromWasmAbi, OptionIntoWasmAbi,
|
||||
RefFromWasmAbi, RefMutFromWasmAbi, VectorFromWasmAbi, VectorIntoWasmAbi, WasmAbi,
|
||||
};
|
||||
use crate::convert::{VectorFromWasmAbi, VectorIntoWasmAbi};
|
||||
use crate::describe::*;
|
||||
use cfg_if::cfg_if;
|
||||
use crate::JsValue;
|
||||
|
||||
if_std! {
|
||||
use core::mem;
|
||||
use crate::convert::OptionFromWasmAbi;
|
||||
use crate::convert::{js_value_vector_from_abi, js_value_vector_into_abi};
|
||||
}
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
// note: `WasmAbi` types do not need to be FFI-safe themselves, it's just more
|
||||
// convenient to directly write `WasmSlice` in some of the manually-written FFI
|
||||
@ -53,104 +53,100 @@ fn null_slice() -> WasmSlice {
|
||||
WasmSlice { ptr: 0, len: 0 }
|
||||
}
|
||||
|
||||
if_std! {
|
||||
pub struct WasmMutSlice {
|
||||
pub slice: WasmSlice,
|
||||
pub idx: u32,
|
||||
pub struct WasmMutSlice {
|
||||
pub slice: WasmSlice,
|
||||
pub idx: u32,
|
||||
}
|
||||
|
||||
impl WasmAbi for WasmMutSlice {
|
||||
/// `self.slice.ptr`
|
||||
type Prim1 = u32;
|
||||
/// `self.slice.len`
|
||||
type Prim2 = u32;
|
||||
/// `self.idx`
|
||||
type Prim3 = u32;
|
||||
type Prim4 = ();
|
||||
|
||||
#[inline]
|
||||
fn split(self) -> (u32, u32, u32, ()) {
|
||||
(self.slice.ptr, self.slice.len, self.idx, ())
|
||||
}
|
||||
|
||||
impl WasmAbi for WasmMutSlice {
|
||||
/// `self.slice.ptr`
|
||||
type Prim1 = u32;
|
||||
/// `self.slice.len`
|
||||
type Prim2 = u32;
|
||||
/// `self.idx`
|
||||
type Prim3 = u32;
|
||||
type Prim4 = ();
|
||||
|
||||
#[inline]
|
||||
fn split(self) -> (u32, u32, u32, ()) {
|
||||
(self.slice.ptr, self.slice.len, self.idx, ())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn join(ptr: u32, len: u32, idx: u32, _: ()) -> Self {
|
||||
Self {
|
||||
slice: WasmSlice { ptr, len },
|
||||
idx,
|
||||
}
|
||||
#[inline]
|
||||
fn join(ptr: u32, len: u32, idx: u32, _: ()) -> Self {
|
||||
Self {
|
||||
slice: WasmSlice { ptr, len },
|
||||
idx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The representation of a mutable slice passed from JS to Rust.
|
||||
pub struct MutSlice<T> {
|
||||
/// A copy of the data in the JS typed array.
|
||||
contents: Box<[T]>,
|
||||
/// A reference to the original JS typed array.
|
||||
js: JsValue,
|
||||
}
|
||||
/// The representation of a mutable slice passed from JS to Rust.
|
||||
pub struct MutSlice<T> {
|
||||
/// A copy of the data in the JS typed array.
|
||||
contents: Box<[T]>,
|
||||
/// A reference to the original JS typed array.
|
||||
js: JsValue,
|
||||
}
|
||||
|
||||
impl<T> Drop for MutSlice<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
__wbindgen_copy_to_typed_array(
|
||||
self.contents.as_ptr() as *const u8,
|
||||
self.contents.len() * mem::size_of::<T>(),
|
||||
self.js.idx
|
||||
);
|
||||
}
|
||||
impl<T> Drop for MutSlice<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
__wbindgen_copy_to_typed_array(
|
||||
self.contents.as_ptr() as *const u8,
|
||||
self.contents.len() * mem::size_of::<T>(),
|
||||
self.js.idx,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for MutSlice<T> {
|
||||
type Target = [T];
|
||||
impl<T> Deref for MutSlice<T> {
|
||||
type Target = [T];
|
||||
|
||||
fn deref(&self) -> &[T] {
|
||||
&self.contents
|
||||
}
|
||||
fn deref(&self) -> &[T] {
|
||||
&self.contents
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for MutSlice<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
&mut self.contents
|
||||
}
|
||||
impl<T> DerefMut for MutSlice<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
&mut self.contents
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! vectors {
|
||||
($($t:ident)*) => ($(
|
||||
if_std! {
|
||||
impl WasmDescribeVector for $t {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
$t::describe();
|
||||
impl WasmDescribeVector for $t {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
$t::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorIntoWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[$t]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorIntoWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
impl VectorFromWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[$t]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorFromWasmAbi for $t {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[$t]> {
|
||||
let ptr = <*mut $t>::from_abi(js.ptr);
|
||||
let len = js.len as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[$t]> {
|
||||
let ptr = <*mut $t>::from_abi(js.ptr);
|
||||
let len = js.len as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,36 +219,34 @@ vectors! {
|
||||
u8 i8 u16 i16 u32 i32 u64 i64 usize isize f32 f64
|
||||
}
|
||||
|
||||
if_std! {
|
||||
impl WasmDescribeVector for String {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
inform(NAMED_EXTERNREF);
|
||||
// Trying to use an actual loop for this breaks the wasm interpreter.
|
||||
inform(6);
|
||||
inform('s' as u32);
|
||||
inform('t' as u32);
|
||||
inform('r' as u32);
|
||||
inform('i' as u32);
|
||||
inform('n' as u32);
|
||||
inform('g' as u32);
|
||||
}
|
||||
impl WasmDescribeVector for String {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
inform(NAMED_EXTERNREF);
|
||||
// Trying to use an actual loop for this breaks the wasm interpreter.
|
||||
inform(6);
|
||||
inform('s' as u32);
|
||||
inform('t' as u32);
|
||||
inform('r' as u32);
|
||||
inform('i' as u32);
|
||||
inform('n' as u32);
|
||||
inform('g' as u32);
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorIntoWasmAbi for String {
|
||||
type Abi = <Box<[JsValue]> as IntoWasmAbi>::Abi;
|
||||
impl VectorIntoWasmAbi for String {
|
||||
type Abi = <Box<[JsValue]> as IntoWasmAbi>::Abi;
|
||||
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi {
|
||||
js_value_vector_into_abi(vector)
|
||||
}
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi {
|
||||
js_value_vector_into_abi(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorFromWasmAbi for String {
|
||||
type Abi = <Box<[JsValue]> as FromWasmAbi>::Abi;
|
||||
impl VectorFromWasmAbi for String {
|
||||
type Abi = <Box<[JsValue]> as FromWasmAbi>::Abi;
|
||||
|
||||
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]> {
|
||||
js_value_vector_from_abi(js)
|
||||
}
|
||||
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]> {
|
||||
js_value_vector_from_abi(js)
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,63 +266,81 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
impl<T> IntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi<Abi = WasmSlice> {
|
||||
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
||||
impl<T> IntoWasmAbi for Vec<T>
|
||||
where
|
||||
Box<[T]>: IntoWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
type Abi = <Box<[T]> as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
self.into_boxed_slice().into_abi()
|
||||
}
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
self.into_boxed_slice().into_abi()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OptionIntoWasmAbi for Vec<T> where Box<[T]>: IntoWasmAbi<Abi = WasmSlice> {
|
||||
#[inline]
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
impl<T> OptionIntoWasmAbi for Vec<T>
|
||||
where
|
||||
Box<[T]>: IntoWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
#[inline]
|
||||
fn none() -> WasmSlice {
|
||||
null_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi<Abi = WasmSlice> {
|
||||
type Abi = <Box<[T]> as FromWasmAbi>::Abi;
|
||||
impl<T> FromWasmAbi for Vec<T>
|
||||
where
|
||||
Box<[T]>: FromWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
type Abi = <Box<[T]> as FromWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
<Box<[T]>>::from_abi(js).into()
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
<Box<[T]>>::from_abi(js).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OptionFromWasmAbi for Vec<T> where Box<[T]>: FromWasmAbi<Abi = WasmSlice> {
|
||||
#[inline]
|
||||
fn is_none(abi: &WasmSlice) -> bool { abi.ptr == 0 }
|
||||
impl<T> OptionFromWasmAbi for Vec<T>
|
||||
where
|
||||
Box<[T]>: FromWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
#[inline]
|
||||
fn is_none(abi: &WasmSlice) -> bool {
|
||||
abi.ptr == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||
impl IntoWasmAbi for String {
|
||||
type Abi = <Vec<u8> as IntoWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
// This is safe because the JsValue is immediately looked up in the heap and
|
||||
// then returned, so use-after-free cannot occur.
|
||||
unsafe_get_cached_str(&self).unwrap_or_else(|| self.into_bytes().into_abi())
|
||||
}
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
// This is safe because the JsValue is immediately looked up in the heap and
|
||||
// then returned, so use-after-free cannot occur.
|
||||
unsafe_get_cached_str(&self).unwrap_or_else(|| self.into_bytes().into_abi())
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for String {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi { null_slice() }
|
||||
impl OptionIntoWasmAbi for String {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi {
|
||||
null_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for String {
|
||||
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
|
||||
impl FromWasmAbi for String {
|
||||
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js))
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
String::from_utf8_unchecked(<Vec<u8>>::from_abi(js))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for String {
|
||||
#[inline]
|
||||
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
|
||||
impl OptionFromWasmAbi for String {
|
||||
#[inline]
|
||||
fn is_none(slice: &WasmSlice) -> bool {
|
||||
slice.ptr == 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,87 +382,98 @@ impl LongRefFromWasmAbi for str {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use crate::JsValue;
|
||||
impl<T: VectorIntoWasmAbi> IntoWasmAbi for Box<[T]> {
|
||||
type Abi = <T as VectorIntoWasmAbi>::Abi;
|
||||
|
||||
impl<T: VectorIntoWasmAbi> IntoWasmAbi for Box<[T]> {
|
||||
type Abi = <T as VectorIntoWasmAbi>::Abi;
|
||||
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
T::vector_into_abi(self)
|
||||
}
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
T::vector_into_abi(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OptionIntoWasmAbi for Box<[T]> where Self: IntoWasmAbi<Abi = WasmSlice> {
|
||||
fn none() -> WasmSlice {
|
||||
null_slice()
|
||||
}
|
||||
impl<T> OptionIntoWasmAbi for Box<[T]>
|
||||
where
|
||||
Self: IntoWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
fn none() -> WasmSlice {
|
||||
null_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: VectorFromWasmAbi> FromWasmAbi for Box<[T]> {
|
||||
type Abi = <T as VectorFromWasmAbi>::Abi;
|
||||
impl<T: VectorFromWasmAbi> FromWasmAbi for Box<[T]> {
|
||||
type Abi = <T as VectorFromWasmAbi>::Abi;
|
||||
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
T::vector_from_abi(js)
|
||||
}
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self {
|
||||
T::vector_from_abi(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OptionFromWasmAbi for Box<[T]> where Self: FromWasmAbi<Abi = WasmSlice> {
|
||||
fn is_none(slice: &WasmSlice) -> bool {
|
||||
slice.ptr == 0
|
||||
}
|
||||
impl<T> OptionFromWasmAbi for Box<[T]>
|
||||
where
|
||||
Self: FromWasmAbi<Abi = WasmSlice>,
|
||||
{
|
||||
fn is_none(slice: &WasmSlice) -> bool {
|
||||
slice.ptr == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorIntoWasmAbi for JsValue {
|
||||
type Abi = WasmSlice;
|
||||
impl VectorIntoWasmAbi for JsValue {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorFromWasmAbi for JsValue {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[Self]> {
|
||||
let ptr = <*mut JsValue>::from_abi(js.ptr);
|
||||
let len = js.len as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VectorIntoWasmAbi for T where T: JsObject {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[T]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VectorFromWasmAbi for T where T: JsObject {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[T]> {
|
||||
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();
|
||||
vec.into_boxed_slice()
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VectorFromWasmAbi for JsValue {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[Self]> {
|
||||
let ptr = <*mut JsValue>::from_abi(js.ptr);
|
||||
let len = js.len as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VectorIntoWasmAbi for T
|
||||
where
|
||||
T: JsObject,
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn vector_into_abi(vector: Box<[T]>) -> WasmSlice {
|
||||
let ptr = vector.as_ptr();
|
||||
let len = vector.len();
|
||||
mem::forget(vector);
|
||||
WasmSlice {
|
||||
ptr: ptr.into_abi(),
|
||||
len: len as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VectorFromWasmAbi for T
|
||||
where
|
||||
T: JsObject,
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn vector_from_abi(js: WasmSlice) -> Box<[T]> {
|
||||
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();
|
||||
vec.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
@ -192,25 +192,23 @@ impl<T: IntoWasmAbi> ReturnWasmAbi for T {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use core::marker::Sized;
|
||||
use std::boxed::Box;
|
||||
use alloc::boxed::Box;
|
||||
use core::marker::Sized;
|
||||
|
||||
/// Trait for element types to implement IntoWasmAbi for vectors of
|
||||
/// themselves.
|
||||
pub trait VectorIntoWasmAbi: WasmDescribeVector + Sized {
|
||||
type Abi: WasmAbi;
|
||||
/// Trait for element types to implement IntoWasmAbi for vectors of
|
||||
/// themselves.
|
||||
pub trait VectorIntoWasmAbi: WasmDescribeVector + Sized {
|
||||
type Abi: WasmAbi;
|
||||
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi;
|
||||
}
|
||||
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi;
|
||||
}
|
||||
|
||||
/// Trait for element types to implement FromWasmAbi for vectors of
|
||||
/// themselves.
|
||||
pub trait VectorFromWasmAbi: WasmDescribeVector + Sized {
|
||||
type Abi: WasmAbi;
|
||||
/// Trait for element types to implement FromWasmAbi for vectors of
|
||||
/// themselves.
|
||||
pub trait VectorFromWasmAbi: WasmDescribeVector + Sized {
|
||||
type Abi: WasmAbi;
|
||||
|
||||
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]>;
|
||||
}
|
||||
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]>;
|
||||
}
|
||||
|
||||
/// A repr(C) struct containing all of the primitives of a `WasmAbi` type, in
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#![doc(hidden)]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
use crate::{Clamped, JsError, JsObject, JsValue};
|
||||
@ -145,46 +148,45 @@ impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a mut T {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use std::prelude::v1::*;
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "enable-interning")] {
|
||||
simple! {
|
||||
String => CACHED_STRING
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "enable-interning")] {
|
||||
simple! {
|
||||
String => CACHED_STRING
|
||||
}
|
||||
|
||||
} else {
|
||||
simple! {
|
||||
String => STRING
|
||||
}
|
||||
} else {
|
||||
simple! {
|
||||
String => STRING
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmDescribeVector for JsValue {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
JsValue::describe();
|
||||
}
|
||||
impl WasmDescribeVector for JsValue {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
JsValue::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JsObject> WasmDescribeVector for T {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
T::describe();
|
||||
}
|
||||
impl<T: JsObject> WasmDescribeVector for T {
|
||||
fn describe_vector() {
|
||||
inform(VECTOR);
|
||||
T::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: WasmDescribeVector> WasmDescribe for Box<[T]> {
|
||||
fn describe() {
|
||||
T::describe_vector();
|
||||
}
|
||||
impl<T: WasmDescribeVector> WasmDescribe for Box<[T]> {
|
||||
fn describe() {
|
||||
T::describe_vector();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
|
||||
fn describe() {
|
||||
<Box<[T]>>::describe();
|
||||
}
|
||||
impl<T> WasmDescribe for Vec<T>
|
||||
where
|
||||
Box<[T]>: WasmDescribe,
|
||||
{
|
||||
fn describe() {
|
||||
<Box<[T]>>::describe();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::JsValue;
|
||||
use std::cell::Cell;
|
||||
use std::slice;
|
||||
use std::vec::Vec;
|
||||
use std::cmp::max;
|
||||
|
||||
use alloc::slice;
|
||||
use alloc::vec::Vec;
|
||||
use core::cell::Cell;
|
||||
use core::cmp::max;
|
||||
|
||||
externs! {
|
||||
#[link(wasm_import_module = "__wbindgen_externref_xform__")]
|
||||
@ -98,10 +99,19 @@ impl Slab {
|
||||
}
|
||||
|
||||
fn internal_error(msg: &str) -> ! {
|
||||
if cfg!(debug_assertions) {
|
||||
super::throw_str(msg)
|
||||
} else {
|
||||
std::process::abort()
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(debug_assertions)] {
|
||||
super::throw_str(msg)
|
||||
} else if #[cfg(feature = "std")] {
|
||||
std::process::abort();
|
||||
} else if #[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", target_os = "wasi"))
|
||||
))] {
|
||||
core::arch::wasm32::unreachable();
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +170,3 @@ pub unsafe extern "C" fn __externref_heap_live_count() -> u32 {
|
||||
})
|
||||
.unwrap_or_else(|_| internal_error("tls access failure"))
|
||||
}
|
||||
|
||||
// see comment in module above this in `link_mem_intrinsics`
|
||||
#[inline(never)]
|
||||
pub fn link_intrinsics() {}
|
||||
|
591
src/lib.rs
591
src/lib.rs
@ -9,8 +9,12 @@
|
||||
#![allow(coherence_leak_check)]
|
||||
#![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt;
|
||||
use core::marker;
|
||||
use core::mem;
|
||||
use core::ops::{
|
||||
@ -50,6 +54,7 @@ macro_rules! externs {
|
||||
/// use wasm_bindgen::prelude::*;
|
||||
/// ```
|
||||
pub mod prelude {
|
||||
pub use crate::closure::Closure;
|
||||
pub use crate::JsCast;
|
||||
pub use crate::JsValue;
|
||||
pub use crate::UnwrapThrowExt;
|
||||
@ -57,17 +62,15 @@ pub mod prelude {
|
||||
pub use wasm_bindgen_macro::__wasm_bindgen_class_marker;
|
||||
pub use wasm_bindgen_macro::wasm_bindgen;
|
||||
|
||||
if_std! {
|
||||
pub use crate::closure::Closure;
|
||||
}
|
||||
|
||||
pub use crate::JsError;
|
||||
}
|
||||
|
||||
pub use wasm_bindgen_macro::link_to;
|
||||
|
||||
pub mod closure;
|
||||
pub mod convert;
|
||||
pub mod describe;
|
||||
mod link;
|
||||
|
||||
mod cast;
|
||||
pub use crate::cast::{JsCast, JsObject};
|
||||
@ -75,9 +78,7 @@ pub use crate::cast::{JsCast, JsObject};
|
||||
if_std! {
|
||||
extern crate std;
|
||||
use std::prelude::v1::*;
|
||||
pub mod closure;
|
||||
mod externref;
|
||||
|
||||
mod cache;
|
||||
pub use cache::intern::{intern, unintern};
|
||||
}
|
||||
@ -293,7 +294,6 @@ impl JsValue {
|
||||
/// caveats about the encodings.
|
||||
///
|
||||
/// [caveats]: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/str.html
|
||||
#[cfg(feature = "std")]
|
||||
#[inline]
|
||||
pub fn as_string(&self) -> Option<String> {
|
||||
unsafe { FromWasmAbi::from_abi(__wbindgen_string_get(self.idx)) }
|
||||
@ -512,18 +512,16 @@ impl<'a> PartialEq<&'a str> for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
impl PartialEq<String> for JsValue {
|
||||
#[inline]
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
<JsValue as PartialEq<str>>::eq(self, other)
|
||||
}
|
||||
impl PartialEq<String> for JsValue {
|
||||
#[inline]
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
<JsValue as PartialEq<str>>::eq(self, other)
|
||||
}
|
||||
impl<'a> PartialEq<&'a String> for JsValue {
|
||||
#[inline]
|
||||
fn eq(&self, other: &&'a String) -> bool {
|
||||
<JsValue as PartialEq<str>>::eq(self, other)
|
||||
}
|
||||
}
|
||||
impl<'a> PartialEq<&'a String> for JsValue {
|
||||
#[inline]
|
||||
fn eq(&self, other: &&'a String) -> bool {
|
||||
<JsValue as PartialEq<str>>::eq(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
@ -797,40 +795,38 @@ impl<T> From<NonNull<T>> for JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
impl<'a> From<&'a String> for JsValue {
|
||||
#[inline]
|
||||
fn from(s: &'a String) -> JsValue {
|
||||
JsValue::from_str(s)
|
||||
impl<'a> From<&'a String> for JsValue {
|
||||
#[inline]
|
||||
fn from(s: &'a String) -> JsValue {
|
||||
JsValue::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for JsValue {
|
||||
#[inline]
|
||||
fn from(s: String) -> JsValue {
|
||||
JsValue::from_str(&s)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsValue> for String {
|
||||
type Error = JsValue;
|
||||
|
||||
fn try_from(value: JsValue) -> Result<Self, Self::Error> {
|
||||
match value.as_string() {
|
||||
Some(s) => Ok(s),
|
||||
None => Err(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for JsValue {
|
||||
#[inline]
|
||||
fn from(s: String) -> JsValue {
|
||||
JsValue::from_str(&s)
|
||||
}
|
||||
}
|
||||
impl TryFromJsValue for String {
|
||||
type Error = JsValue;
|
||||
|
||||
impl TryFrom<JsValue> for String {
|
||||
type Error = JsValue;
|
||||
|
||||
fn try_from(value: JsValue) -> Result<Self, Self::Error> {
|
||||
match value.as_string() {
|
||||
Some(s) => Ok(s),
|
||||
None => Err(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromJsValue for String {
|
||||
type Error = JsValue;
|
||||
|
||||
fn try_from_js_value(value: JsValue) -> Result<Self, Self::Error> {
|
||||
match value.as_string() {
|
||||
Some(s) => Ok(s),
|
||||
None => Err(value),
|
||||
}
|
||||
fn try_from_js_value(value: JsValue) -> Result<Self, Self::Error> {
|
||||
match value.as_string() {
|
||||
Some(s) => Ok(s),
|
||||
None => Err(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1132,15 +1128,15 @@ impl Clone for JsValue {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl fmt::Debug for JsValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
impl core::fmt::Debug for JsValue {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "JsValue({})", self.as_debug_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl fmt::Debug for JsValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
impl core::fmt::Debug for JsValue {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.write_str("JsValue")
|
||||
}
|
||||
}
|
||||
@ -1345,7 +1341,7 @@ pub trait UnwrapThrowExt<T>: Sized {
|
||||
fn unwrap_throw(self) -> T {
|
||||
if cfg!(all(debug_assertions, feature = "std")) {
|
||||
let loc = core::panic::Location::caller();
|
||||
let msg = std::format!(
|
||||
let msg = alloc::format!(
|
||||
"`unwrap_throw` failed ({}:{}:{})",
|
||||
loc.file(),
|
||||
loc.line(),
|
||||
@ -1430,12 +1426,18 @@ pub mod __rt {
|
||||
use core::borrow::{Borrow, BorrowMut};
|
||||
use core::cell::{Cell, UnsafeCell};
|
||||
use core::convert::Infallible;
|
||||
use core::mem;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
pub extern crate alloc;
|
||||
pub extern crate core;
|
||||
#[cfg(feature = "std")]
|
||||
pub extern crate std;
|
||||
|
||||
use alloc::alloc::{alloc, dealloc, realloc, Layout};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
@ -1609,151 +1611,157 @@ pub mod __rt {
|
||||
);
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use std::rc::Rc;
|
||||
/// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a `Ref`
|
||||
/// to the contents of that `WasmRefCell`.
|
||||
///
|
||||
/// The `'static` requirement is an unfortunate consequence of how this
|
||||
/// is implemented.
|
||||
pub struct RcRef<T: ?Sized + 'static> {
|
||||
// The 'static is a lie.
|
||||
//
|
||||
// We could get away without storing this, since we're in the same module as
|
||||
// `WasmRefCell` and can directly manipulate its `borrow`, but I'm considering
|
||||
// turning it into a wrapper around `std`'s `RefCell` to reduce `unsafe` in
|
||||
// which case that would stop working. This also requires less `unsafe` as is.
|
||||
//
|
||||
// It's important that this goes before `Rc` so that it gets dropped first.
|
||||
ref_: Ref<'static, T>,
|
||||
_rc: Rc<WasmRefCell<T>>,
|
||||
}
|
||||
|
||||
/// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a `Ref`
|
||||
/// to the contents of that `WasmRefCell`.
|
||||
///
|
||||
/// The `'static` requirement is an unfortunate consequence of how this
|
||||
/// is implemented.
|
||||
pub struct RcRef<T: ?Sized + 'static> {
|
||||
// The 'static is a lie.
|
||||
//
|
||||
// We could get away without storing this, since we're in the same module as
|
||||
// `WasmRefCell` and can directly manipulate its `borrow`, but I'm considering
|
||||
// turning it into a wrapper around `std`'s `RefCell` to reduce `unsafe` in
|
||||
// which case that would stop working. This also requires less `unsafe` as is.
|
||||
//
|
||||
// It's important that this goes before `Rc` so that it gets dropped first.
|
||||
ref_: Ref<'static, T>,
|
||||
_rc: Rc<WasmRefCell<T>>,
|
||||
impl<T: ?Sized> RcRef<T> {
|
||||
pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
|
||||
let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow() };
|
||||
Self { _rc: rc, ref_ }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> RcRef<T> {
|
||||
pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
|
||||
let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow() };
|
||||
Self { _rc: rc, ref_ }
|
||||
impl<T: ?Sized> Deref for RcRef<T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Borrow<T> for RcRef<T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a
|
||||
/// `RefMut` to the contents of that `WasmRefCell`.
|
||||
///
|
||||
/// The `'static` requirement is an unfortunate consequence of how this
|
||||
/// is implemented.
|
||||
pub struct RcRefMut<T: ?Sized + 'static> {
|
||||
ref_: RefMut<'static, T>,
|
||||
_rc: Rc<WasmRefCell<T>>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> RcRefMut<T> {
|
||||
pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
|
||||
let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow_mut() };
|
||||
Self { _rc: rc, ref_ }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for RcRefMut<T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> DerefMut for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Borrow<T> for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> BorrowMut<T> for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn borrow_mut(&mut self) -> &mut T {
|
||||
&mut self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __wbindgen_malloc(size: usize, align: usize) -> *mut u8 {
|
||||
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||
unsafe {
|
||||
if layout.size() > 0 {
|
||||
let ptr = alloc(layout);
|
||||
if !ptr.is_null() {
|
||||
return ptr;
|
||||
}
|
||||
} else {
|
||||
return align as *mut u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for RcRef<T> {
|
||||
type Target = T;
|
||||
malloc_failure();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
&self.ref_
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_realloc(
|
||||
ptr: *mut u8,
|
||||
old_size: usize,
|
||||
new_size: usize,
|
||||
align: usize,
|
||||
) -> *mut u8 {
|
||||
debug_assert!(old_size > 0);
|
||||
debug_assert!(new_size > 0);
|
||||
if let Ok(layout) = Layout::from_size_align(old_size, align) {
|
||||
let ptr = realloc(ptr, layout, new_size);
|
||||
if !ptr.is_null() {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
malloc_failure();
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Borrow<T> for RcRef<T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that encapsulates an `Rc<WasmRefCell<T>>` as well as a
|
||||
/// `RefMut` to the contents of that `WasmRefCell`.
|
||||
///
|
||||
/// The `'static` requirement is an unfortunate consequence of how this
|
||||
/// is implemented.
|
||||
pub struct RcRefMut<T: ?Sized + 'static> {
|
||||
ref_: RefMut<'static, T>,
|
||||
_rc: Rc<WasmRefCell<T>>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> RcRefMut<T> {
|
||||
pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
|
||||
let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow_mut() };
|
||||
Self { _rc: rc, ref_ }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for RcRefMut<T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> DerefMut for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Borrow<T> for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &T {
|
||||
&self.ref_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> BorrowMut<T> for RcRefMut<T> {
|
||||
#[inline]
|
||||
fn borrow_mut(&mut self) -> &mut T {
|
||||
&mut self.ref_
|
||||
#[cold]
|
||||
fn malloc_failure() -> ! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(debug_assertions)] {
|
||||
super::throw_str("invalid malloc request")
|
||||
} else if #[cfg(feature = "std")] {
|
||||
std::process::abort();
|
||||
} else if #[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", target_os = "wasi"))
|
||||
))] {
|
||||
core::arch::wasm32::unreachable();
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use std::alloc::{alloc, dealloc, realloc, Layout};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __wbindgen_malloc(size: usize, align: usize) -> *mut u8 {
|
||||
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||
unsafe {
|
||||
if layout.size() > 0 {
|
||||
let ptr = alloc(layout);
|
||||
if !ptr.is_null() {
|
||||
return ptr
|
||||
}
|
||||
} else {
|
||||
return align as *mut u8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
malloc_failure();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_realloc(ptr: *mut u8, old_size: usize, new_size: usize, align: usize) -> *mut u8 {
|
||||
debug_assert!(old_size > 0);
|
||||
debug_assert!(new_size > 0);
|
||||
if let Ok(layout) = Layout::from_size_align(old_size, align) {
|
||||
let ptr = realloc(ptr, layout, new_size);
|
||||
if !ptr.is_null() {
|
||||
return ptr
|
||||
}
|
||||
}
|
||||
malloc_failure();
|
||||
}
|
||||
|
||||
#[cold]
|
||||
fn malloc_failure() -> ! {
|
||||
if cfg!(debug_assertions) {
|
||||
super::throw_str("invalid malloc request")
|
||||
} else {
|
||||
std::process::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize, align: usize) {
|
||||
// This happens for zero-length slices, and in that case `ptr` is
|
||||
// likely bogus so don't actually send this to the system allocator
|
||||
if size == 0 {
|
||||
return
|
||||
}
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
dealloc(ptr, layout);
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_free(ptr: *mut u8, size: usize, align: usize) {
|
||||
// This happens for zero-length slices, and in that case `ptr` is
|
||||
// likely bogus so don't actually send this to the system allocator
|
||||
if size == 0 {
|
||||
return;
|
||||
}
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
dealloc(ptr, layout);
|
||||
}
|
||||
|
||||
/// This is a curious function necessary to get wasm-bindgen working today,
|
||||
@ -1790,31 +1798,33 @@ pub mod __rt {
|
||||
///
|
||||
/// Ideas for how to improve this are most welcome!
|
||||
pub fn link_mem_intrinsics() {
|
||||
crate::externref::link_intrinsics();
|
||||
crate::link::link_intrinsics();
|
||||
}
|
||||
|
||||
std::thread_local! {
|
||||
static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
|
||||
}
|
||||
if_std! {
|
||||
std::thread_local! {
|
||||
static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
|
||||
GLOBAL_EXNDATA.with(|data| {
|
||||
debug_assert_eq!(data.get()[0], 0);
|
||||
data.set([1, idx]);
|
||||
});
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
|
||||
GLOBAL_EXNDATA.with(|data| {
|
||||
debug_assert_eq!(data.get()[0], 0);
|
||||
data.set([1, idx]);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn take_last_exception() -> Result<(), super::JsValue> {
|
||||
GLOBAL_EXNDATA.with(|data| {
|
||||
let ret = if data.get()[0] == 1 {
|
||||
Err(super::JsValue::_new(data.get()[1]))
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
data.set([0, 0]);
|
||||
ret
|
||||
})
|
||||
pub fn take_last_exception() -> Result<(), super::JsValue> {
|
||||
GLOBAL_EXNDATA.with(|data| {
|
||||
let ret = if data.get()[0] == 1 {
|
||||
Err(super::JsValue::_new(data.get()[1]))
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
data.set([0, 0]);
|
||||
ret
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal helper trait for usage in `#[wasm_bindgen]` on `async`
|
||||
@ -1902,11 +1912,11 @@ pub mod __rt {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: std::fmt::Debug> Main for &mut MainWrapper<Result<(), E>> {
|
||||
impl<E: core::fmt::Debug> Main for &mut MainWrapper<Result<(), E>> {
|
||||
#[inline]
|
||||
fn __wasm_bindgen_main(&mut self) {
|
||||
if let Err(e) = self.0.take().unwrap() {
|
||||
crate::throw_str(&std::format!("{:?}", e));
|
||||
crate::throw_str(&alloc::format!("{:?}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1957,33 +1967,28 @@ pub mod __rt {
|
||||
result
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use core::mem;
|
||||
use std::boxed::Box;
|
||||
/// Trait for element types to implement `Into<JsValue>` for vectors of
|
||||
/// themselves, which isn't possible directly thanks to the orphan rule.
|
||||
pub trait VectorIntoJsValue: Sized {
|
||||
fn vector_into_jsvalue(vector: Box<[Self]>) -> JsValue;
|
||||
}
|
||||
|
||||
/// Trait for element types to implement `Into<JsValue>` for vectors of
|
||||
/// themselves, which isn't possible directly thanks to the orphan rule.
|
||||
pub trait VectorIntoJsValue: Sized {
|
||||
fn vector_into_jsvalue(vector: Box<[Self]>) -> JsValue;
|
||||
impl<T: VectorIntoJsValue> From<Box<[T]>> for JsValue {
|
||||
fn from(vector: Box<[T]>) -> Self {
|
||||
T::vector_into_jsvalue(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: VectorIntoJsValue> From<Box<[T]>> for JsValue {
|
||||
fn from(vector: Box<[T]>) -> Self {
|
||||
T::vector_into_jsvalue(vector)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn js_value_vector_into_jsvalue<T: Into<JsValue>>(vector: Box<[T]>) -> JsValue {
|
||||
let result = unsafe { JsValue::_new(super::__wbindgen_array_new()) };
|
||||
for value in vector.into_vec() {
|
||||
let js: JsValue = value.into();
|
||||
unsafe { super::__wbindgen_array_push(result.idx, js.idx) }
|
||||
// `__wbindgen_array_push` takes ownership over `js` and has already dropped it,
|
||||
// so don't drop it again.
|
||||
mem::forget(js);
|
||||
}
|
||||
result
|
||||
pub fn js_value_vector_into_jsvalue<T: Into<JsValue>>(vector: Box<[T]>) -> JsValue {
|
||||
let result = unsafe { JsValue::_new(super::__wbindgen_array_new()) };
|
||||
for value in vector.into_vec() {
|
||||
let js: JsValue = value.into();
|
||||
unsafe { super::__wbindgen_array_push(result.idx, js.idx) }
|
||||
// `__wbindgen_array_push` takes ownership over `js` and has already dropped it,
|
||||
// so don't drop it again.
|
||||
mem::forget(js);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@ -2105,74 +2110,72 @@ impl From<JsError> for JsValue {
|
||||
}
|
||||
|
||||
macro_rules! typed_arrays {
|
||||
($($ty:ident $ctor:ident $clamped_ctor:ident,)*) => {
|
||||
$(
|
||||
impl From<Box<[$ty]>> for JsValue {
|
||||
fn from(mut vector: Box<[$ty]>) -> Self {
|
||||
let result = unsafe { JsValue::_new($ctor(vector.as_mut_ptr(), vector.len())) };
|
||||
mem::forget(vector);
|
||||
result
|
||||
($($ty:ident $ctor:ident $clamped_ctor:ident,)*) => {
|
||||
$(
|
||||
impl From<Box<[$ty]>> for JsValue {
|
||||
fn from(mut vector: Box<[$ty]>) -> Self {
|
||||
let result = unsafe { JsValue::_new($ctor(vector.as_mut_ptr(), vector.len())) };
|
||||
mem::forget(vector);
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Clamped<Box<[$ty]>>> for JsValue {
|
||||
fn from(mut vector: Clamped<Box<[$ty]>>) -> Self {
|
||||
let result = unsafe { JsValue::_new($clamped_ctor(vector.as_mut_ptr(), vector.len())) };
|
||||
mem::forget(vector);
|
||||
result
|
||||
impl From<Clamped<Box<[$ty]>>> for JsValue {
|
||||
fn from(mut vector: Clamped<Box<[$ty]>>) -> Self {
|
||||
let result = unsafe { JsValue::_new($clamped_ctor(vector.as_mut_ptr(), vector.len())) };
|
||||
mem::forget(vector);
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
typed_arrays! {
|
||||
u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new,
|
||||
u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new,
|
||||
u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new,
|
||||
u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new,
|
||||
i8 __wbindgen_int8_array_new __wbindgen_int8_array_new,
|
||||
i16 __wbindgen_int16_array_new __wbindgen_int16_array_new,
|
||||
i32 __wbindgen_int32_array_new __wbindgen_int32_array_new,
|
||||
i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new,
|
||||
f32 __wbindgen_float32_array_new __wbindgen_float32_array_new,
|
||||
f64 __wbindgen_float64_array_new __wbindgen_float64_array_new,
|
||||
}
|
||||
|
||||
if_std! {
|
||||
typed_arrays! {
|
||||
u8 __wbindgen_uint8_array_new __wbindgen_uint8_clamped_array_new,
|
||||
u16 __wbindgen_uint16_array_new __wbindgen_uint16_array_new,
|
||||
u32 __wbindgen_uint32_array_new __wbindgen_uint32_array_new,
|
||||
u64 __wbindgen_biguint64_array_new __wbindgen_biguint64_array_new,
|
||||
i8 __wbindgen_int8_array_new __wbindgen_int8_array_new,
|
||||
i16 __wbindgen_int16_array_new __wbindgen_int16_array_new,
|
||||
i32 __wbindgen_int32_array_new __wbindgen_int32_array_new,
|
||||
i64 __wbindgen_bigint64_array_new __wbindgen_bigint64_array_new,
|
||||
f32 __wbindgen_float32_array_new __wbindgen_float32_array_new,
|
||||
f64 __wbindgen_float64_array_new __wbindgen_float64_array_new,
|
||||
}
|
||||
|
||||
impl __rt::VectorIntoJsValue for JsValue {
|
||||
fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<JsValue>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JsObject> __rt::VectorIntoJsValue for T {
|
||||
fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<T>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl __rt::VectorIntoJsValue for String {
|
||||
fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<String>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Vec<T>> for JsValue
|
||||
where
|
||||
JsValue: From<Box<[T]>>,
|
||||
{
|
||||
fn from(vector: Vec<T>) -> Self {
|
||||
JsValue::from(vector.into_boxed_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Clamped<Vec<T>>> for JsValue
|
||||
where
|
||||
JsValue: From<Clamped<Box<[T]>>>,
|
||||
{
|
||||
fn from(vector: Clamped<Vec<T>>) -> Self {
|
||||
JsValue::from(Clamped(vector.0.into_boxed_slice()))
|
||||
}
|
||||
impl __rt::VectorIntoJsValue for JsValue {
|
||||
fn vector_into_jsvalue(vector: Box<[JsValue]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<JsValue>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JsObject> __rt::VectorIntoJsValue for T {
|
||||
fn vector_into_jsvalue(vector: Box<[T]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<T>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl __rt::VectorIntoJsValue for String {
|
||||
fn vector_into_jsvalue(vector: Box<[String]>) -> JsValue {
|
||||
__rt::js_value_vector_into_jsvalue::<String>(vector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Vec<T>> for JsValue
|
||||
where
|
||||
JsValue: From<Box<[T]>>,
|
||||
{
|
||||
fn from(vector: Vec<T>) -> Self {
|
||||
JsValue::from(vector.into_boxed_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Clamped<Vec<T>>> for JsValue
|
||||
where
|
||||
JsValue: From<Clamped<Box<[T]>>>,
|
||||
{
|
||||
fn from(vector: Clamped<Vec<T>>) -> Self {
|
||||
JsValue::from(Clamped(vector.0.into_boxed_slice()))
|
||||
}
|
||||
}
|
||||
|
3
src/link.rs
Normal file
3
src/link.rs
Normal file
@ -0,0 +1,3 @@
|
||||
// see comment in module above this in `link_mem_intrinsics`
|
||||
#[inline(never)]
|
||||
pub fn link_intrinsics() {}
|
Loading…
Reference in New Issue
Block a user