Skip to content

Commit

Permalink
Added support for the wasm32v1-none target (rustwasm#4277)
Browse files Browse the repository at this point in the history
This PR adds support for the `wasm32v1-none` target and should enable all features previously behind `cfg(feature = "std")` for both `wasm32-unknown-unknown` and `wasm32v1-none`. Additionally, now  `js-sys`, `web-sys`, `wasm-bindgen-futures` and `wasm-bindgen-test` support `no_std`.

Changes:
- Use `any(target_os = "unknown", target_os = "none")` instead of `target_os = "unknown"`.
- For globals:
  - Continue to use `once_cell::sync::Lazy` when targeting `std`.
  - Use `Send + Sync` wrapped `once_cell::unsync::Lazy` when targeting `no_std` without `target_feature = "atomics"`.
  - Use `once_cell/critical_section` when targeting `no_std` with `target_feature = "atomics"`. As recommended by `critical_section`, this is something the user has to enable. Notable this only affects `link_to!`, any other feature will work as expected with no additional work required from the user.
- For thread locals:
  - Continue to use `std::thread_local!` when targeting `std`.
  - Use `static mut` when targeting `no_std` without `target_feature = "atomics"`.
  - Use `#[thread_local]` when targeting  `no_std` with `target_feature = "atomics"`.
- Add `std` crate feature to `js-sys`, `web-sys`, `wasm-bindgen-futures` and `wasm-bindgen-test` and enable by default. This makes it possible to use these crates with `no_std` for both targets as well.
- Inlined [`console_error_panic_hook`](https://crates.io/crates/console_error_panic_hook) and a `no_std` version of [`scoped_tls`](https://crates.io/crates/scoped-tls).

Missing:
- Add `wasm32v1-none` to CI. Probably in a follow-up when its stable, ergo Rust v1.84.
  • Loading branch information
daxpedda authored Nov 28, 2024
1 parent fe5d89f commit f071c7e
Show file tree
Hide file tree
Showing 575 changed files with 2,254 additions and 1,565 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[target.wasm32-unknown-unknown]
[target.'cfg(target_arch = "wasm32")']
runner = 'cargo run -p wasm-bindgen-cli --bin wasm-bindgen-test-runner --'

[target.'cfg(all())']
Expand Down
32 changes: 31 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,37 @@ jobs:
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown -p js-sys -- -D warnings
- run: cargo clippy --no-deps --all-features --target wasm32-unknown-unknown -p web-sys -- -D warnings

# Run `cargo clippy` over crates that support `no_std`
clippy_no_std:
name: Clippy `no_std`
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rustup update --no-self-update stable && rustup default stable
- run: rustup target add wasm32-unknown-unknown
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p js-sys -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p web-sys -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen-futures -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen-test -- -D warnings

# Run `cargo clippy` over crates that support `no_std` with `target_feature = "atomics"` support.
clippy_no_std_atomics:
name: Clippy `no_std` with `atomics`
runs-on: ubuntu-latest
env:
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUSTFLAGS: -Ctarget-feature=+atomics,+bulk-memory
steps:
- uses: actions/checkout@v4
- run: rustup default nightly-2024-07-06
- run: rustup target add wasm32-unknown-unknown
- run: rustup component add clippy rust-src
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen -Zbuild-std=core,alloc -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p js-sys -Zbuild-std=core,alloc -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p web-sys -Zbuild-std=core,alloc -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen-futures --features once_cell/critical-section -Zbuild-std=core,alloc -- -D warnings
- run: cargo clippy --no-deps --no-default-features --target wasm32-unknown-unknown -p wasm-bindgen-test --features once_cell/critical-section -Zbuild-std=core,alloc -- -D warnings

# Run `cargo clippy` over the project
clippy_project:
name: Clippy (project)
Expand All @@ -100,7 +131,6 @@ jobs:
- uses: actions/checkout@v4
- run: rustup update --no-self-update stable && rustup default stable
- run: rustup target add wasm32-unknown-unknown
- 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: for i in examples/*/; do cd "$i"; cargo +stable clippy --no-deps --all-features --target wasm32-unknown-unknown -- -D warnings || exit 1; cd ../..; done
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@
* Added WASM ABI support for `u128` and `i128`
[#4222](https://github.com/rustwasm/wasm-bindgen/pull/4222)

* Added support for the `wasm32v1-none` target.
[#4277](https://github.com/rustwasm/wasm-bindgen/pull/4277)

* Added support for `no_std` to `js-sys`, `web-sys`, `wasm-bindgen-futures` and `wasm-bindgen-test`.
[#4277](https://github.com/rustwasm/wasm-bindgen/pull/4277)

* Added support for `no_std` to `link_to!`, `static_string` (via `thread_local_v2`) and `throw`.
[#4277](https://github.com/rustwasm/wasm-bindgen/pull/4277)

### Changed

* String enums now generate private TypeScript types but only if used.
Expand All @@ -46,6 +55,9 @@
* `wasm-bindgen-test-runner` now tries to restart the WebDriver on failure, instead of spending its timeout period trying to connect to a non-existing WebDriver.
[#4267](https://github.com/rustwasm/wasm-bindgen/pull/4267)

* Deprecated `#[wasm_bindgen(thread_local)]` in favor of `#[wasm_bindgen(thread_local_v2)]`, which creates a `wasm_bindgen::JsThreadLocal`. It is similar to `std::thread::LocalKey` but supports `no_std`.
[#4277](https://github.com/rustwasm/wasm-bindgen/pull/4277)

### Fixed

* Fixed methods with `self: &Self` consuming the object.
Expand Down
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ default = ["spans", "std"]
enable-interning = ["std"]
serde-serialize = ["serde", "serde_json", "std"]
spans = ["wasm-bindgen-macro/spans"]
std = []
std = ["wasm-bindgen-macro/std", "once_cell/std"]

# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
# all unused attributes
Expand All @@ -42,10 +42,15 @@ xxx_debug_only_print_generated_code = ["wasm-bindgen-macro/xxx_debug_only_print_

[dependencies]
cfg-if = "1.0.0"
once_cell = "1.12"
once_cell = { version = "1.12", default-features = false }
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true }
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95" }
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95", default-features = false }

[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), target_feature = "atomics"))'.dependencies]
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95", default-features = false, features = [
"atomics",
] }

[dev-dependencies]
wasm-bindgen-test = { path = 'crates/test' }
Expand Down
3 changes: 3 additions & 0 deletions crates/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ rust-version = "1.57"
version = "0.2.95"

[features]
atomics = []
default = ["std"]
extra-traits = ["syn/extra-traits"]
spans = []
std = []

[dependencies]
bumpalo = "3.0.0"
Expand Down
15 changes: 13 additions & 2 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,17 @@ pub struct ImportStatic {
pub js_name: String,
/// Path to wasm_bindgen
pub wasm_bindgen: Path,
/// [`true`] if using the new `thread_local` representation.
pub thread_local: bool,
/// Version of `thread_local`, if any.
pub thread_local: Option<ThreadLocal>,
}

/// Which version of the `thread_local` attribute is enabled.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ThreadLocal {
/// V1.
V1,
/// V2.
V2,
}

/// The type of a static string being imported
Expand All @@ -297,6 +306,8 @@ pub struct ImportString {
pub js_sys: Path,
/// The string to export.
pub string: String,
/// Version of `thread_local`.
pub thread_local: ThreadLocal,
}

/// The metadata for a type being imported
Expand Down
92 changes: 66 additions & 26 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl TryToTokens for ast::Program {
let prefix_json_bytes = syn::LitByteStr::new(&prefix_json_bytes, Span::call_site());

(quote! {
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
use #wasm_bindgen::__rt::{flat_len, flat_byte_slices};
Expand Down Expand Up @@ -201,9 +201,10 @@ impl TryToTokens for ast::LinkToModule {
#program
#extern_fn

static __VAL: #wasm_bindgen::__rt::Lazy<String> = #wasm_bindgen::__rt::Lazy::new(|| unsafe {
<#wasm_bindgen::__rt::alloc::string::String as #wasm_bindgen::convert::FromWasmAbi>::from_abi(#name().join())
});
static __VAL: #wasm_bindgen::__rt::once_cell::sync::Lazy<#wasm_bindgen::__rt::alloc::string::String> =
#wasm_bindgen::__rt::once_cell::sync::Lazy::new(|| unsafe {
<#wasm_bindgen::__rt::alloc::string::String as #wasm_bindgen::convert::FromWasmAbi>::from_abi(#name().join())
});

#wasm_bindgen::__rt::alloc::string::String::clone(&__VAL)
}
Expand Down Expand Up @@ -275,12 +276,12 @@ impl ToTokens for ast::Struct {
let ptr = #wasm_bindgen::convert::IntoWasmAbi::into_abi(value);

#[link(wasm_import_module = "__wbindgen_placeholder__")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
extern "C" {
fn #new_fn(ptr: u32) -> u32;
}

#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
unsafe fn #new_fn(_: u32) -> u32 {
panic!("cannot convert to JsValue outside of the Wasm target")
}
Expand All @@ -292,7 +293,7 @@ impl ToTokens for ast::Struct {
}
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#[no_mangle]
Expand Down Expand Up @@ -381,12 +382,12 @@ impl ToTokens for ast::Struct {
let idx = #wasm_bindgen::convert::IntoWasmAbi::into_abi(&value);

#[link(wasm_import_module = "__wbindgen_placeholder__")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
extern "C" {
fn #unwrap_fn(ptr: u32) -> u32;
}

#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
unsafe fn #unwrap_fn(_: u32) -> u32 {
panic!("cannot convert from JsValue outside of the Wasm target")
}
Expand Down Expand Up @@ -493,7 +494,7 @@ impl ToTokens for ast::StructField {
(quote! {
#[automatically_derived]
const _: () = {
#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), no_mangle)]
#[cfg_attr(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")), no_mangle)]
#[doc(hidden)]
#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
pub unsafe extern "C" fn #getter(js: u32)
Expand Down Expand Up @@ -532,7 +533,7 @@ impl ToTokens for ast::StructField {
let (args, names) = splat(wasm_bindgen, &Ident::new("val", rust_name.span()), &abi);

(quote! {
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#[no_mangle]
Expand Down Expand Up @@ -791,7 +792,7 @@ impl TryToTokens for ast::Export {
const _: () = {
#(#attrs)*
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
export_name = #export_name,
)]
#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
Expand Down Expand Up @@ -1066,11 +1067,11 @@ impl ToTokens for ast::ImportType {
impl JsCast for #rust_name {
fn instanceof(val: &JsValue) -> bool {
#[link(wasm_import_module = "__wbindgen_placeholder__")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
extern "C" {
fn #instanceof_shim(val: u32) -> u32;
}
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
unsafe fn #instanceof_shim(_: u32) -> u32 {
panic!("cannot check instanceof on non-wasm targets");
}
Expand Down Expand Up @@ -1675,14 +1676,15 @@ impl ToTokens for ast::ImportStatic {
fn to_tokens(&self, into: &mut TokenStream) {
let ty = &self.ty;

if self.thread_local {
if let Some(thread_local) = self.thread_local {
thread_local_import(
&self.vis,
&self.rust_name,
&self.wasm_bindgen,
ty,
ty,
&self.shim,
thread_local,
)
.to_tokens(into)
} else {
Expand All @@ -1695,7 +1697,7 @@ impl ToTokens for ast::ImportStatic {

into.extend(quote! {
#[automatically_derived]
#[deprecated = "use with `#[wasm_bindgen(thread_local)]` instead"]
#[deprecated = "use with `#[wasm_bindgen(thread_local_v2)]` instead"]
});
into.extend(
quote_spanned! { name.span() => #vis static #name: #wasm_bindgen::JsStatic<#ty> = {
Expand Down Expand Up @@ -1735,6 +1737,7 @@ impl ToTokens for ast::ImportString {
&actual_ty,
&self.ty,
&self.shim,
self.thread_local,
)
.to_tokens(into);
}
Expand All @@ -1747,15 +1750,52 @@ fn thread_local_import(
actual_ty: &syn::Type,
ty: &syn::Type,
shim_name: &Ident,
thread_local: ast::ThreadLocal,
) -> TokenStream {
let init = static_init(wasm_bindgen, ty, shim_name);

quote! {
thread_local! {
#[automatically_derived]
#vis static #name: #actual_ty = {
#init
match thread_local {
ast::ThreadLocal::V1 => quote! {
thread_local! {
#[automatically_derived]
#[deprecated = "use with `#[wasm_bindgen(thread_local_v2)]` instead"]
#vis static #name: #actual_ty = {
#init
};
}
},
ast::ThreadLocal::V2 => {
#[cfg(feature = "std")]
let inner = quote! {
thread_local!(static _VAL: #actual_ty = init(););
#wasm_bindgen::JsThreadLocal {
__inner: &_VAL,
}
};
#[cfg(all(not(feature = "std"), not(feature = "atomics")))]
let inner = quote! {
static _VAL: #wasm_bindgen::__rt::LazyCell<#actual_ty> = #wasm_bindgen::__rt::LazyCell::new(init);
#wasm_bindgen::JsThreadLocal {
__inner: &_VAL,
}
};
#[cfg(all(not(feature = "std"), feature = "atomics"))]
let inner = quote! {
#[thread_local]
static _VAL: #wasm_bindgen::__rt::LazyCell<#actual_ty> = #wasm_bindgen::__rt::LazyCell::new(init);
#wasm_bindgen::JsThreadLocal {
__inner: || unsafe { #wasm_bindgen::__rt::LazyCell::force(&_VAL) as *const #actual_ty },
}
};

quote! {
#vis static #name: #wasm_bindgen::JsThreadLocal<#actual_ty> = {
fn init() -> #actual_ty {
#init
}
#inner
};
}
}
}
}
Expand All @@ -1766,12 +1806,12 @@ fn static_init(wasm_bindgen: &syn::Path, ty: &syn::Type, shim_name: &Ident) -> T
};
quote! {
#[link(wasm_import_module = "__wbindgen_placeholder__")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
extern "C" {
fn #shim_name() -> #abi_ret;
}

#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
unsafe fn #shim_name() -> #abi_ret {
panic!("cannot access imported statics on non-wasm targets")
}
Expand Down Expand Up @@ -1818,7 +1858,7 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> {
let attrs = &self.attrs;
let wasm_bindgen = &self.wasm_bindgen;
(quote! {
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#(#attrs)*
Expand All @@ -1845,14 +1885,14 @@ fn extern_fn(
abi_ret: TokenStream,
) -> TokenStream {
quote! {
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#(#attrs)*
#[link(wasm_import_module = "__wbindgen_placeholder__")]
extern "C" {
fn #import_name(#(#abi_arguments),*) -> #abi_ret;
}

#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
unsafe fn #import_name(#(#abi_arguments),*) -> #abi_ret {
#(
drop(#abi_argument_names);
Expand Down
6 changes: 3 additions & 3 deletions crates/cli/tests/reference/anyref-import-catch.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
(type (;2;) (func (result i32 i32)))
(type (;3;) (func (param i32)))
(import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
(func $__externref_table_dealloc (;1;) (type 3) (param i32))
(func $__externref_table_alloc (;2;) (type 1) (result i32))
(func $__wbindgen_exn_store (;3;) (type 3) (param i32))
(func $__wbindgen_exn_store (;1;) (type 3) (param i32))
(func $__externref_table_dealloc (;2;) (type 3) (param i32))
(func $__externref_table_alloc (;3;) (type 1) (result i32))
(func $"exported multivalue shim" (;4;) (type 2) (result i32 i32))
(table (;0;) 128 externref)
(memory (;0;) 17)
Expand Down
Loading

0 comments on commit f071c7e

Please sign in to comment.