RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.
This commit is contained in:
225
zeroidc/vendor/wasm-bindgen/src/convert/closures.rs
vendored
Normal file
225
zeroidc/vendor/wasm-bindgen/src/convert/closures.rs
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
use core::mem;
|
||||
|
||||
use crate::convert::slices::WasmSlice;
|
||||
use crate::convert::RefFromWasmAbi;
|
||||
use crate::convert::{FromWasmAbi, IntoWasmAbi, ReturnWasmAbi};
|
||||
use crate::describe::{inform, WasmDescribe, FUNCTION};
|
||||
use crate::throw_str;
|
||||
|
||||
macro_rules! stack_closures {
|
||||
($( ($cnt:tt $invoke:ident $invoke_mut:ident $($var:ident)*) )*) => ($(
|
||||
impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a (dyn Fn($($var),*) -> R + 'b)
|
||||
where $($var: FromWasmAbi,)*
|
||||
R: ReturnWasmAbi
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
unsafe {
|
||||
let (a, b): (usize, usize) = mem::transmute(self);
|
||||
WasmSlice { ptr: a as u32, len: b as u32 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe extern "C" fn $invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||
a: usize,
|
||||
b: usize,
|
||||
$($var: <$var as FromWasmAbi>::Abi),*
|
||||
) -> <R as ReturnWasmAbi>::Abi {
|
||||
if a == 0 {
|
||||
throw_str("closure invoked recursively or destroyed already");
|
||||
}
|
||||
// Scope all local variables before we call `return_abi` to
|
||||
// ensure they're all destroyed as `return_abi` may throw
|
||||
let ret = {
|
||||
let f: &dyn Fn($($var),*) -> R = mem::transmute((a, b));
|
||||
$(
|
||||
let $var = <$var as FromWasmAbi>::from_abi($var);
|
||||
)*
|
||||
f($($var),*)
|
||||
};
|
||||
ret.return_abi()
|
||||
}
|
||||
|
||||
impl<'a, $($var,)* R> WasmDescribe for dyn Fn($($var),*) -> R + 'a
|
||||
where $($var: FromWasmAbi,)*
|
||||
R: ReturnWasmAbi
|
||||
{
|
||||
fn describe() {
|
||||
inform(FUNCTION);
|
||||
inform($invoke::<$($var,)* R> as u32);
|
||||
inform($cnt);
|
||||
$(<$var as WasmDescribe>::describe();)*
|
||||
<R as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, $($var,)* R> IntoWasmAbi for &'a mut (dyn FnMut($($var),*) -> R + 'b)
|
||||
where $($var: FromWasmAbi,)*
|
||||
R: ReturnWasmAbi
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
unsafe {
|
||||
let (a, b): (usize, usize) = mem::transmute(self);
|
||||
WasmSlice { ptr: a as u32, len: b as u32 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe extern "C" fn $invoke_mut<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
|
||||
a: usize,
|
||||
b: usize,
|
||||
$($var: <$var as FromWasmAbi>::Abi),*
|
||||
) -> <R as ReturnWasmAbi>::Abi {
|
||||
if a == 0 {
|
||||
throw_str("closure invoked recursively or destroyed already");
|
||||
}
|
||||
// Scope all local variables before we call `return_abi` to
|
||||
// ensure they're all destroyed as `return_abi` may throw
|
||||
let ret = {
|
||||
let f: &mut dyn FnMut($($var),*) -> R = mem::transmute((a, b));
|
||||
$(
|
||||
let $var = <$var as FromWasmAbi>::from_abi($var);
|
||||
)*
|
||||
f($($var),*)
|
||||
};
|
||||
ret.return_abi()
|
||||
}
|
||||
|
||||
impl<'a, $($var,)* R> WasmDescribe for dyn FnMut($($var),*) -> R + 'a
|
||||
where $($var: FromWasmAbi,)*
|
||||
R: ReturnWasmAbi
|
||||
{
|
||||
fn describe() {
|
||||
inform(FUNCTION);
|
||||
inform($invoke_mut::<$($var,)* R> as u32);
|
||||
inform($cnt);
|
||||
$(<$var as WasmDescribe>::describe();)*
|
||||
<R as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
stack_closures! {
|
||||
(0 invoke0 invoke0_mut)
|
||||
(1 invoke1 invoke1_mut A)
|
||||
(2 invoke2 invoke2_mut A B)
|
||||
(3 invoke3 invoke3_mut A B C)
|
||||
(4 invoke4 invoke4_mut A B C D)
|
||||
(5 invoke5 invoke5_mut A B C D E)
|
||||
(6 invoke6 invoke6_mut A B C D E F)
|
||||
(7 invoke7 invoke7_mut A B C D E F G)
|
||||
(8 invoke8 invoke8_mut A B C D E F G H)
|
||||
}
|
||||
|
||||
impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(&A) -> R + 'b)
|
||||
where
|
||||
A: RefFromWasmAbi,
|
||||
R: ReturnWasmAbi,
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
unsafe {
|
||||
let (a, b): (usize, usize) = mem::transmute(self);
|
||||
WasmSlice {
|
||||
ptr: a as u32,
|
||||
len: b as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe extern "C" fn invoke1_ref<A: RefFromWasmAbi, R: ReturnWasmAbi>(
|
||||
a: usize,
|
||||
b: usize,
|
||||
arg: <A as RefFromWasmAbi>::Abi,
|
||||
) -> <R as ReturnWasmAbi>::Abi {
|
||||
if a == 0 {
|
||||
throw_str("closure invoked recursively or destroyed already");
|
||||
}
|
||||
// Scope all local variables before we call `return_abi` to
|
||||
// ensure they're all destroyed as `return_abi` may throw
|
||||
let ret = {
|
||||
let f: &dyn Fn(&A) -> R = mem::transmute((a, b));
|
||||
let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
|
||||
f(&*arg)
|
||||
};
|
||||
ret.return_abi()
|
||||
}
|
||||
|
||||
impl<'a, A, R> WasmDescribe for dyn Fn(&A) -> R + 'a
|
||||
where
|
||||
A: RefFromWasmAbi,
|
||||
R: ReturnWasmAbi,
|
||||
{
|
||||
fn describe() {
|
||||
inform(FUNCTION);
|
||||
inform(invoke1_ref::<A, R> as u32);
|
||||
inform(1);
|
||||
<&A as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, A, R> IntoWasmAbi for &'a mut (dyn FnMut(&A) -> R + 'b)
|
||||
where
|
||||
A: RefFromWasmAbi,
|
||||
R: ReturnWasmAbi,
|
||||
{
|
||||
type Abi = WasmSlice;
|
||||
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
unsafe {
|
||||
let (a, b): (usize, usize) = mem::transmute(self);
|
||||
WasmSlice {
|
||||
ptr: a as u32,
|
||||
len: b as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe extern "C" fn invoke1_mut_ref<A: RefFromWasmAbi, R: ReturnWasmAbi>(
|
||||
a: usize,
|
||||
b: usize,
|
||||
arg: <A as RefFromWasmAbi>::Abi,
|
||||
) -> <R as ReturnWasmAbi>::Abi {
|
||||
if a == 0 {
|
||||
throw_str("closure invoked recursively or destroyed already");
|
||||
}
|
||||
// Scope all local variables before we call `return_abi` to
|
||||
// ensure they're all destroyed as `return_abi` may throw
|
||||
let ret = {
|
||||
let f: &mut dyn FnMut(&A) -> R = mem::transmute((a, b));
|
||||
let arg = <A as RefFromWasmAbi>::ref_from_abi(arg);
|
||||
f(&*arg)
|
||||
};
|
||||
ret.return_abi()
|
||||
}
|
||||
|
||||
impl<'a, A, R> WasmDescribe for dyn FnMut(&A) -> R + 'a
|
||||
where
|
||||
A: RefFromWasmAbi,
|
||||
R: ReturnWasmAbi,
|
||||
{
|
||||
fn describe() {
|
||||
inform(FUNCTION);
|
||||
inform(invoke1_mut_ref::<A, R> as u32);
|
||||
inform(1);
|
||||
<&A as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
<R as WasmDescribe>::describe();
|
||||
}
|
||||
}
|
||||
474
zeroidc/vendor/wasm-bindgen/src/convert/impls.rs
vendored
Normal file
474
zeroidc/vendor/wasm-bindgen/src/convert/impls.rs
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
use core::char;
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
|
||||
use crate::convert::traits::WasmAbi;
|
||||
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi};
|
||||
use crate::convert::{OptionFromWasmAbi, OptionIntoWasmAbi, ReturnWasmAbi};
|
||||
use crate::{Clamped, JsError, JsValue};
|
||||
|
||||
unsafe impl WasmAbi for () {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmOptionalI32 {
|
||||
pub present: u32,
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmOptionalI32 {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmOptionalU32 {
|
||||
pub present: u32,
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmOptionalU32 {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmOptionalF32 {
|
||||
pub present: u32,
|
||||
pub value: f32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmOptionalF32 {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmOptionalF64 {
|
||||
pub present: u32,
|
||||
pub value: f64,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmOptionalF64 {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Wasm64 {
|
||||
pub low: u32,
|
||||
pub high: u32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for Wasm64 {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmOptional64 {
|
||||
pub present: u32,
|
||||
pub low: u32,
|
||||
pub high: u32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmOptional64 {}
|
||||
|
||||
macro_rules! type_wasm_native {
|
||||
($($t:tt as $c:tt => $r:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = $c;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> $c { self as $c }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = $c;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: $c) -> Self { js as $t }
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for Option<$t> {
|
||||
type Abi = $r;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> $r {
|
||||
match self {
|
||||
None => $r {
|
||||
present: 0,
|
||||
value: 0 as $c,
|
||||
},
|
||||
Some(me) => $r {
|
||||
present: 1,
|
||||
value: me as $c,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for Option<$t> {
|
||||
type Abi = $r;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: $r) -> Self {
|
||||
if js.present == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(js.value as $t)
|
||||
}
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
type_wasm_native!(
|
||||
i32 as i32 => WasmOptionalI32
|
||||
isize as i32 => WasmOptionalI32
|
||||
u32 as u32 => WasmOptionalU32
|
||||
usize as u32 => WasmOptionalU32
|
||||
f32 as f32 => WasmOptionalF32
|
||||
f64 as f64 => WasmOptionalF64
|
||||
);
|
||||
|
||||
macro_rules! type_abi_as_u32 {
|
||||
($($t:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 { self as u32 }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> Self { js as $t }
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for $t {
|
||||
#[inline]
|
||||
fn none() -> u32 { 0x00FF_FFFFu32 }
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for $t {
|
||||
#[inline]
|
||||
fn is_none(js: &u32) -> bool { *js == 0x00FF_FFFFu32 }
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
type_abi_as_u32!(i8 u8 i16 u16);
|
||||
|
||||
macro_rules! type_64 {
|
||||
($($t:tt)*) => ($(
|
||||
impl IntoWasmAbi for $t {
|
||||
type Abi = Wasm64;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> Wasm64 {
|
||||
Wasm64 {
|
||||
low: self as u32,
|
||||
high: (self >> 32) as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for $t {
|
||||
type Abi = Wasm64;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: Wasm64) -> $t {
|
||||
$t::from(js.low) | ($t::from(js.high) << 32)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for Option<$t> {
|
||||
type Abi = WasmOptional64;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> WasmOptional64 {
|
||||
match self {
|
||||
None => WasmOptional64 {
|
||||
present: 0,
|
||||
low: 0 as u32,
|
||||
high: 0 as u32,
|
||||
},
|
||||
Some(me) => WasmOptional64 {
|
||||
present: 1,
|
||||
low: me as u32,
|
||||
high: (me >> 32) as u32,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for Option<$t> {
|
||||
type Abi = WasmOptional64;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: WasmOptional64) -> Self {
|
||||
if js.present == 0 {
|
||||
None
|
||||
} else {
|
||||
Some($t::from(js.low) | ($t::from(js.high) << 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
type_64!(i64 u64);
|
||||
|
||||
impl IntoWasmAbi for bool {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for bool {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> bool {
|
||||
js != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for bool {
|
||||
#[inline]
|
||||
fn none() -> u32 {
|
||||
0x00FF_FFFFu32
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for bool {
|
||||
#[inline]
|
||||
fn is_none(js: &u32) -> bool {
|
||||
*js == 0x00FF_FFFFu32
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for char {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for char {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> char {
|
||||
char::from_u32_unchecked(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for char {
|
||||
#[inline]
|
||||
fn none() -> u32 {
|
||||
0x00FF_FFFFu32
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for char {
|
||||
#[inline]
|
||||
fn is_none(js: &u32) -> bool {
|
||||
*js == 0x00FF_FFFFu32
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoWasmAbi for *const T {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromWasmAbi for *const T {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> *const T {
|
||||
js as *const T
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoWasmAbi for *mut T {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromWasmAbi for *mut T {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> *mut T {
|
||||
js as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
let ret = self.idx;
|
||||
mem::forget(self);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: u32) -> JsValue {
|
||||
JsValue::_new(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a JsValue {
|
||||
type Abi = u32;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
}
|
||||
|
||||
impl RefFromWasmAbi for JsValue {
|
||||
type Abi = u32;
|
||||
type Anchor = ManuallyDrop<JsValue>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: u32) -> Self::Anchor {
|
||||
ManuallyDrop::new(JsValue::_new(js))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: OptionIntoWasmAbi> IntoWasmAbi for Option<T> {
|
||||
type Abi = T::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> T::Abi {
|
||||
match self {
|
||||
None => T::none(),
|
||||
Some(me) => me.into_abi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: OptionFromWasmAbi> FromWasmAbi for Option<T> {
|
||||
type Abi = T::Abi;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: T::Abi) -> Self {
|
||||
if T::is_none(&js) {
|
||||
None
|
||||
} else {
|
||||
Some(T::from_abi(js))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoWasmAbi> IntoWasmAbi for Clamped<T> {
|
||||
type Abi = T::Abi;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
self.0.into_abi()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromWasmAbi> FromWasmAbi for Clamped<T> {
|
||||
type Abi = T::Abi;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: T::Abi) -> Self {
|
||||
Clamped(T::from_abi(js))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for () {
|
||||
type Abi = ();
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// This is an encoding of a Result. It can only store things that can be decoded by the JS
|
||||
/// bindings.
|
||||
///
|
||||
/// At the moment, we do not write the exact struct packing layout of everything into the
|
||||
/// glue/descriptions of datatypes, so T cannot be arbitrary. The current requirements of the
|
||||
/// struct unpacker (StructUnpacker), which apply to ResultAbi<T> as a whole, are as follows:
|
||||
///
|
||||
/// - repr(C), of course
|
||||
/// - u32/i32/f32/f64 fields at the "leaf fields" of the "field tree"
|
||||
/// - layout equivalent to a completely flattened repr(C) struct, constructed by an in order
|
||||
/// traversal of all the leaf fields in it.
|
||||
///
|
||||
/// This means that you can't embed struct A(u32, f64) as struct B(u32, A); because the "completely
|
||||
/// flattened" struct AB(u32, u32, f64) would miss the 4 byte padding that is actually present
|
||||
/// within B and then as a consequence also miss the 4 byte padding within A that repr(C) inserts.
|
||||
///
|
||||
/// The enemy is padding. Padding is only required when there is an `f64` field. So the enemy is
|
||||
/// `f64` after anything else, particularly anything arbitrary. There is no smaller sized type, so
|
||||
/// we don't need to worry about 1-byte integers, etc. It's best, therefore, to place your f64s
|
||||
/// first in your structs, that's why we have `abi` first, although here it doesn't matter as the
|
||||
/// other two fields total 8 bytes anyway.
|
||||
///
|
||||
#[repr(C)]
|
||||
pub struct ResultAbi<T> {
|
||||
/// This field is the same size/align as `T`.
|
||||
abi: ResultAbiUnion<T>,
|
||||
/// Order of args here is such that we can pop() the possible error first, deal with it and
|
||||
/// move on. Later fields are popped off the stack first.
|
||||
err: u32,
|
||||
is_err: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub union ResultAbiUnion<T> {
|
||||
// ManuallyDrop is #[repr(transparent)]
|
||||
ok: std::mem::ManuallyDrop<T>,
|
||||
err: (),
|
||||
}
|
||||
|
||||
unsafe impl<T: WasmAbi> WasmAbi for ResultAbi<T> {}
|
||||
unsafe impl<T: WasmAbi> WasmAbi for ResultAbiUnion<T> {}
|
||||
|
||||
impl<T: IntoWasmAbi, E: Into<JsValue>> ReturnWasmAbi for Result<T, E> {
|
||||
type Abi = ResultAbi<T::Abi>;
|
||||
#[inline]
|
||||
fn return_abi(self) -> Self::Abi {
|
||||
match self {
|
||||
Ok(v) => {
|
||||
let abi = ResultAbiUnion {
|
||||
ok: std::mem::ManuallyDrop::new(v.into_abi()),
|
||||
};
|
||||
ResultAbi {
|
||||
abi,
|
||||
is_err: 0,
|
||||
err: 0,
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let jsval = e.into();
|
||||
ResultAbi {
|
||||
abi: ResultAbiUnion { err: () },
|
||||
is_err: 1,
|
||||
err: jsval.into_abi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWasmAbi for JsError {
|
||||
type Abi = <JsValue as IntoWasmAbi>::Abi;
|
||||
|
||||
fn into_abi(self) -> Self::Abi {
|
||||
self.value.into_abi()
|
||||
}
|
||||
}
|
||||
11
zeroidc/vendor/wasm-bindgen/src/convert/mod.rs
vendored
Normal file
11
zeroidc/vendor/wasm-bindgen/src/convert/mod.rs
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
//! This is mostly an internal module, no stability guarantees are provided. Use
|
||||
//! at your own risk.
|
||||
|
||||
mod closures;
|
||||
mod impls;
|
||||
mod slices;
|
||||
mod traits;
|
||||
|
||||
pub use self::impls::*;
|
||||
pub use self::slices::WasmSlice;
|
||||
pub use self::traits::*;
|
||||
311
zeroidc/vendor/wasm-bindgen/src/convert/slices.rs
vendored
Normal file
311
zeroidc/vendor/wasm-bindgen/src/convert/slices.rs
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
#[cfg(feature = "std")]
|
||||
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;
|
||||
|
||||
if_std! {
|
||||
use core::mem;
|
||||
use crate::convert::OptionFromWasmAbi;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WasmSlice {
|
||||
pub ptr: u32,
|
||||
pub len: u32,
|
||||
}
|
||||
|
||||
unsafe impl WasmAbi for WasmSlice {}
|
||||
|
||||
#[inline]
|
||||
fn null_slice() -> WasmSlice {
|
||||
WasmSlice { ptr: 0, len: 0 }
|
||||
}
|
||||
|
||||
macro_rules! vectors {
|
||||
($($t:ident)*) => ($(
|
||||
if_std! {
|
||||
impl IntoWasmAbi for Box<[$t]> {
|
||||
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 OptionIntoWasmAbi for Box<[$t]> {
|
||||
#[inline]
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for Box<[$t]> {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_abi(js: WasmSlice) -> Self {
|
||||
let ptr = <*mut $t>::from_abi(js.ptr);
|
||||
let len = js.len as usize;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for Box<[$t]> {
|
||||
#[inline]
|
||||
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a [$t] {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
WasmSlice {
|
||||
ptr: self.as_ptr().into_abi(),
|
||||
len: self.len() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionIntoWasmAbi for &'a [$t] {
|
||||
#[inline]
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
}
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a mut [$t] {
|
||||
type Abi = WasmSlice;
|
||||
|
||||
#[inline]
|
||||
fn into_abi(self) -> WasmSlice {
|
||||
(&*self).into_abi()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionIntoWasmAbi for &'a mut [$t] {
|
||||
#[inline]
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
}
|
||||
|
||||
impl RefFromWasmAbi for [$t] {
|
||||
type Abi = WasmSlice;
|
||||
type Anchor = Box<[$t]>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: WasmSlice) -> Box<[$t]> {
|
||||
<Box<[$t]>>::from_abi(js)
|
||||
}
|
||||
}
|
||||
|
||||
impl RefMutFromWasmAbi for [$t] {
|
||||
type Abi = WasmSlice;
|
||||
type Anchor = &'static mut [$t];
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_mut_from_abi(js: WasmSlice)
|
||||
-> &'static mut [$t]
|
||||
{
|
||||
slice::from_raw_parts_mut(
|
||||
<*mut $t>::from_abi(js.ptr),
|
||||
js.len as usize,
|
||||
)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
vectors! {
|
||||
u8 i8 u16 i16 u32 i32 u64 i64 usize isize f32 f64
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "enable-interning")] {
|
||||
#[inline]
|
||||
fn unsafe_get_cached_str(x: &str) -> Option<WasmSlice> {
|
||||
// This uses 0 for the ptr as an indication that it is a JsValue and not a str.
|
||||
crate::cache::intern::unsafe_get_str(x).map(|x| WasmSlice { ptr: 0, len: x })
|
||||
}
|
||||
|
||||
} else {
|
||||
#[inline]
|
||||
fn unsafe_get_cached_str(_x: &str) -> Option<WasmSlice> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#[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 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())
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionIntoWasmAbi for String {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi { null_slice() }
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for String {
|
||||
#[inline]
|
||||
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoWasmAbi for &'a str {
|
||||
type Abi = <&'a [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.as_bytes().into_abi())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionIntoWasmAbi for &'a str {
|
||||
#[inline]
|
||||
fn none() -> Self::Abi {
|
||||
null_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl RefFromWasmAbi for str {
|
||||
type Abi = <[u8] as RefFromWasmAbi>::Abi;
|
||||
type Anchor = Box<str>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
|
||||
mem::transmute::<Box<[u8]>, Box<str>>(<Box<[u8]>>::from_abi(js))
|
||||
}
|
||||
}
|
||||
|
||||
if_std! {
|
||||
use crate::JsValue;
|
||||
|
||||
impl IntoWasmAbi for Box<[JsValue]> {
|
||||
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 OptionIntoWasmAbi for Box<[JsValue]> {
|
||||
#[inline]
|
||||
fn none() -> WasmSlice { null_slice() }
|
||||
}
|
||||
|
||||
impl FromWasmAbi for Box<[JsValue]> {
|
||||
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;
|
||||
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionFromWasmAbi for Box<[JsValue]> {
|
||||
#[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 }
|
||||
}
|
||||
}
|
||||
129
zeroidc/vendor/wasm-bindgen/src/convert/traits.rs
vendored
Normal file
129
zeroidc/vendor/wasm-bindgen/src/convert/traits.rs
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::describe::*;
|
||||
|
||||
/// A trait for anything that can be converted into a type that can cross the
|
||||
/// wasm ABI directly, eg `u32` or `f64`.
|
||||
///
|
||||
/// This is the opposite operation as `FromWasmAbi` and `Ref[Mut]FromWasmAbi`.
|
||||
pub trait IntoWasmAbi: WasmDescribe {
|
||||
/// The wasm ABI type that this converts into when crossing the ABI
|
||||
/// boundary.
|
||||
type Abi: WasmAbi;
|
||||
|
||||
/// Convert `self` into `Self::Abi` so that it can be sent across the wasm
|
||||
/// ABI boundary.
|
||||
fn into_abi(self) -> Self::Abi;
|
||||
}
|
||||
|
||||
/// A trait for anything that can be recovered by-value from the wasm ABI
|
||||
/// boundary, eg a Rust `u8` can be recovered from the wasm ABI `u32` type.
|
||||
///
|
||||
/// This is the by-value variant of the opposite operation as `IntoWasmAbi`.
|
||||
pub trait FromWasmAbi: WasmDescribe {
|
||||
/// The wasm ABI type that this converts from when coming back out from the
|
||||
/// ABI boundary.
|
||||
type Abi: WasmAbi;
|
||||
|
||||
/// Recover a `Self` from `Self::Abi`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This is only safe to call when -- and implementations may assume that --
|
||||
/// the supplied `Self::Abi` was previously generated by a call to `<Self as
|
||||
/// IntoWasmAbi>::into_abi()` or the moral equivalent in JS.
|
||||
unsafe fn from_abi(js: Self::Abi) -> Self;
|
||||
}
|
||||
|
||||
/// A trait for anything that can be recovered as some sort of shared reference
|
||||
/// from the wasm ABI boundary.
|
||||
///
|
||||
/// This is the shared reference variant of the opposite operation as
|
||||
/// `IntoWasmAbi`.
|
||||
pub trait RefFromWasmAbi: WasmDescribe {
|
||||
/// The wasm ABI type references to `Self` are recovered from.
|
||||
type Abi: WasmAbi;
|
||||
|
||||
/// The type that holds the reference to `Self` for the duration of the
|
||||
/// invocation of the function that has an `&Self` parameter. This is
|
||||
/// required to ensure that the lifetimes don't persist beyond one function
|
||||
/// call, and so that they remain anonymous.
|
||||
type Anchor: Deref<Target = Self>;
|
||||
|
||||
/// Recover a `Self::Anchor` from `Self::Abi`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Same as `FromWasmAbi::from_abi`.
|
||||
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor;
|
||||
}
|
||||
|
||||
/// Dual of the `RefFromWasmAbi` trait, except for mutable references.
|
||||
pub trait RefMutFromWasmAbi: WasmDescribe {
|
||||
/// Same as `RefFromWasmAbi::Abi`
|
||||
type Abi: WasmAbi;
|
||||
/// Same as `RefFromWasmAbi::Anchor`
|
||||
type Anchor: DerefMut<Target = Self>;
|
||||
/// Same as `RefFromWasmAbi::ref_from_abi`
|
||||
unsafe fn ref_mut_from_abi(js: Self::Abi) -> Self::Anchor;
|
||||
}
|
||||
|
||||
/// Indicates that this type can be passed to JS as `Option<Self>`.
|
||||
///
|
||||
/// This trait is used when implementing `IntoWasmAbi for Option<T>`.
|
||||
pub trait OptionIntoWasmAbi: IntoWasmAbi {
|
||||
/// Returns an ABI instance indicating "none", which JS will interpret as
|
||||
/// the `None` branch of this option.
|
||||
///
|
||||
/// It should be guaranteed that the `IntoWasmAbi` can never produce the ABI
|
||||
/// value returned here.
|
||||
fn none() -> Self::Abi;
|
||||
}
|
||||
|
||||
/// Indicates that this type can be received from JS as `Option<Self>`.
|
||||
///
|
||||
/// This trait is used when implementing `FromWasmAbi for Option<T>`.
|
||||
pub trait OptionFromWasmAbi: FromWasmAbi {
|
||||
/// Tests whether the argument is a "none" instance. If so it will be
|
||||
/// deserialized as `None`, and otherwise it will be passed to
|
||||
/// `FromWasmAbi`.
|
||||
fn is_none(abi: &Self::Abi) -> bool;
|
||||
}
|
||||
|
||||
/// An unsafe trait which represents types that are ABI-safe to pass via wasm
|
||||
/// arguments.
|
||||
///
|
||||
/// This is an unsafe trait to implement as there's no guarantee the type is
|
||||
/// actually safe to transfer across the was boundary, it's up to you to
|
||||
/// guarantee this so codegen works correctly.
|
||||
pub unsafe trait WasmAbi {}
|
||||
|
||||
unsafe impl WasmAbi for u32 {}
|
||||
unsafe impl WasmAbi for i32 {}
|
||||
unsafe impl WasmAbi for f32 {}
|
||||
unsafe impl WasmAbi for f64 {}
|
||||
|
||||
/// A trait representing how to interepret the return value of a function for
|
||||
/// the wasm ABI.
|
||||
///
|
||||
/// This is very similar to the `IntoWasmAbi` trait and in fact has a blanket
|
||||
/// implementation for all implementors of the `IntoWasmAbi`. The primary use
|
||||
/// case of this trait is to enable functions to return `Result`, interpreting
|
||||
/// an error as "rethrow this to JS"
|
||||
pub trait ReturnWasmAbi: WasmDescribe {
|
||||
/// Same as `IntoWasmAbi::Abi`
|
||||
type Abi: WasmAbi;
|
||||
|
||||
/// Same as `IntoWasmAbi::into_abi`, except that it may throw and never
|
||||
/// return in the case of `Err`.
|
||||
fn return_abi(self) -> Self::Abi;
|
||||
}
|
||||
|
||||
impl<T: IntoWasmAbi> ReturnWasmAbi for T {
|
||||
type Abi = T::Abi;
|
||||
|
||||
#[inline]
|
||||
fn return_abi(self) -> Self::Abi {
|
||||
self.into_abi()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user