Skip to content

Commit

Permalink
Fix no-std compatibility (#4005)
Browse files Browse the repository at this point in the history
  • Loading branch information
Systemcluster authored Jul 28, 2024
1 parent 7ad1a27 commit 06b347f
Show file tree
Hide file tree
Showing 11 changed files with 635 additions and 600 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
54 changes: 24 additions & 30 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
}
Expand All @@ -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>;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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__")]
Expand All @@ -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)
)
}
Expand All @@ -417,32 +411,32 @@ 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)
}
}

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)
}
}
Expand Down Expand Up @@ -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)
),
)
Expand Down Expand Up @@ -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)
}
)
}
Expand All @@ -1611,32 +1605,32 @@ 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)
}
}

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)
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down
76 changes: 38 additions & 38 deletions src/convert/impls.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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();

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()
}
// 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()
}
Loading

0 comments on commit 06b347f

Please sign in to comment.