Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move cabi_realloc to a wit-bindgen-rt crate #876

Merged
merged 4 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ jobs:
- run: cargo build --no-default-features --features csharp
- run: cargo build --no-default-features --features markdown

# Feature combos of the `wit-bindgen` crate
- run: cargo build --target wasm32-wasi -p wit-bindgen --no-default-features
- run: cargo build --target wasm32-wasi -p wit-bindgen --no-default-features --features realloc
- run: cargo build --target wasm32-wasi -p wit-bindgen --no-default-features --features macros
- run: cargo build --target wasm32-wasi -p wit-bindgen --no-default-features --features macros,realloc

# Verity that documentation can be generated for the rust bindings crate.
- run: cargo doc -p wit-bindgen --no-deps
env:
Expand Down
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions ci/rebuild-libcabi-realloc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ version=$(grep '^version =' ./Cargo.toml | sed 's/.*"\(.*\)"/\1/' | sed 's/\./_/

sym=cabi_realloc_wit_bindgen_$version

cat >./crates/guest-rust/src/cabi_realloc.rs <<-EOF
cat >./crates/guest-rust/rt/src/cabi_realloc.rs <<-EOF
// This file is generated by $0

#[no_mangle]
Expand All @@ -53,11 +53,11 @@ pub unsafe extern "C" fn $sym(
align: usize,
new_len: usize,
) -> *mut u8 {
crate::rt::cabi_realloc(old_ptr, old_len, align, new_len)
crate::cabi_realloc(old_ptr, old_len, align, new_len)
}
EOF

cat >./crates/guest-rust/src/cabi_realloc.c <<-EOF
cat >./crates/guest-rust/rt/src/cabi_realloc.c <<-EOF
// This file is generated by $0

#include <stdint.h>
Expand All @@ -70,16 +70,16 @@ void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
}
EOF

rm -f crates/guest-rust/src/cabi_realloc.o
$WASI_SDK_PATH/bin/clang crates/guest-rust/src/cabi_realloc.c \
-O -c -o crates/guest-rust/src/cabi_realloc.o
rm -f crates/guest-rust/rt/src/cabi_realloc.o
$WASI_SDK_PATH/bin/clang crates/guest-rust/rt/src/cabi_realloc.c \
-O -c -o crates/guest-rust/rt/src/cabi_realloc.o

# Remove the `producers` section. This appears to differ whether the host for
# clang is either macOS or Linux. Not needed here anyway, so discard it to help
# either host produce the same object.
wasm-tools strip -d producers ./crates/guest-rust/src/cabi_realloc.o \
-o ./crates/guest-rust/src/cabi_realloc.o
wasm-tools strip -d producers ./crates/guest-rust/rt/src/cabi_realloc.o \
-o ./crates/guest-rust/rt/src/cabi_realloc.o

rm -f crates/guest-rust/src/libwit_bindgen_cabi_realloc.a
$WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/src/libwit_bindgen_cabi_realloc.a \
crates/guest-rust/src/cabi_realloc.o
rm -f crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a
$WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a \
crates/guest-rust/rt/src/cabi_realloc.o
7 changes: 4 additions & 3 deletions crates/guest-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ Used when compiling Rust programs to the component model.
"""

[dependencies]
wit-bindgen-rust-macro = { path = "../rust-macro", optional = true, version = "0.20.0" }
wit-bindgen-rust-macro = { path = "./macro", optional = true, version = "0.20.0" }
wit-bindgen-rt = { path = "./rt", optional = true, version = "0.20.0" }
bitflags = { workspace = true }

[features]
default = ["macros", "realloc"]
macros = ["wit-bindgen-rust-macro"]
realloc = []
macros = ["dep:wit-bindgen-rust-macro"]
realloc = ["dep:wit-bindgen-rt"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions crates/guest-rust/rt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "wit-bindgen-rt"
version.workspace = true
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
homepage = 'https://github.com/bytecodealliance/wit-bindgen'
description = """
Runtime support for the `wit-bindgen` crate
"""
File renamed without changes.
Binary file added crates/guest-rust/rt/src/cabi_realloc.o
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ pub unsafe extern "C" fn cabi_realloc_wit_bindgen_0_20_0(
align: usize,
new_len: usize,
) -> *mut u8 {
crate::rt::cabi_realloc(old_ptr, old_len, align, new_len)
crate::cabi_realloc(old_ptr, old_len, align, new_len)
}
81 changes: 81 additions & 0 deletions crates/guest-rust/rt/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
extern crate alloc;

/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
mod cabi_realloc;

/// This function is called from generated bindings and will be deleted by
/// the linker. The purpose of this function is to force a reference to the
/// symbol `cabi_realloc` to make its way through to the final linker
/// command line. That way `wasm-ld` will pick it up, see it needs to be
/// exported, and then export it.
///
/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
pub fn maybe_link_cabi_realloc() {
#[cfg(target_family = "wasm")]
{
#[cfg(feature = "realloc")]
peterhuene marked this conversation as resolved.
Show resolved Hide resolved
extern "C" {
fn cabi_realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8;
}
// Force the `cabi_realloc` symbol to be referenced from here. This
// is done with a `#[used]` Rust `static` to ensure that this
// reference makes it all the way to the linker before it's
// considered for garbage collection. When the linker sees it it'll
// remove this `static` here (due to it not actually being needed)
// but the linker will have at that point seen the `cabi_realloc`
// symbol and it should get exported.
#[cfg(feature = "realloc")]
peterhuene marked this conversation as resolved.
Show resolved Hide resolved
#[used]
static _NAME_DOES_NOT_MATTER: unsafe extern "C" fn(
*mut u8,
usize,
usize,
usize,
) -> *mut u8 = cabi_realloc;
}
}

/// NB: this function is called by a generated function in the
/// `cabi_realloc` module above. It's otherwise never explicitly called.
///
/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
pub unsafe fn cabi_realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8 {
use self::alloc::alloc::{self, Layout};

let layout;
let ptr = if old_len == 0 {
if new_len == 0 {
return align as *mut u8;
}
layout = Layout::from_size_align_unchecked(new_len, align);
alloc::alloc(layout)
} else {
debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!");
layout = Layout::from_size_align_unchecked(old_len, align);
alloc::realloc(old_ptr, layout, new_len)
};
if ptr.is_null() {
// Print a nice message in debug mode, but in release mode don't
// pull in so many dependencies related to printing so just emit an
// `unreachable` instruction.
if cfg!(debug_assertions) {
alloc::handle_alloc_error(layout);
} else {
#[cfg(target_arch = "wasm32")]
core::arch::wasm32::unreachable();
#[cfg(not(target_arch = "wasm32"))]
unreachable!();
}
}
return ptr;
}
80 changes: 3 additions & 77 deletions crates/guest-rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,94 +845,20 @@ pub use wit_bindgen_rust_macro::generate;
#[doc(hidden)]
pub use bitflags;

/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
#[cfg(feature = "realloc")]
mod cabi_realloc;

mod pre_wit_bindgen_0_20_0;

#[cfg(docsrs)]
pub mod examples;

#[doc(hidden)]
pub mod rt {
/// This function is called from generated bindings and will be deleted by
/// the linker. The purpose of this function is to force a reference to the
/// symbol `cabi_realloc` to make its way through to the final linker
/// command line. That way `wasm-ld` will pick it up, see it needs to be
/// exported, and then export it.
///
/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
pub fn maybe_link_cabi_realloc() {
#[cfg(target_family = "wasm")]
{
#[cfg(feature = "realloc")]
extern "C" {
fn cabi_realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8;
}
// Force the `cabi_realloc` symbol to be referenced from here. This
// is done with a `#[used]` Rust `static` to ensure that this
// reference makes it all the way to the linker before it's
// considered for garbage collection. When the linker sees it it'll
// remove this `static` here (due to it not actually being needed)
// but the linker will have at that point seen the `cabi_realloc`
// symbol and it should get exported.
#[cfg(feature = "realloc")]
#[used]
static _NAME_DOES_NOT_MATTER: unsafe extern "C" fn(
*mut u8,
usize,
usize,
usize,
) -> *mut u8 = cabi_realloc;
}
#[cfg(feature = "realloc")]
wit_bindgen_rt::maybe_link_cabi_realloc();
}

/// NB: this function is called by a generated function in the
/// `cabi_realloc` module above. It's otherwise never explicitly called.
///
/// For more information about this see `./ci/rebuild-libcabi-realloc.sh`.
#[cfg(feature = "realloc")]
pub unsafe fn cabi_realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8 {
use alloc::Layout;

let layout;
let ptr = if old_len == 0 {
if new_len == 0 {
return align as *mut u8;
}
layout = Layout::from_size_align_unchecked(new_len, align);
alloc::alloc(layout)
} else {
debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!");
layout = Layout::from_size_align_unchecked(old_len, align);
alloc::realloc(old_ptr, layout, new_len)
};
if ptr.is_null() {
// Print a nice message in debug mode, but in release mode don't
// pull in so many dependencies related to printing so just emit an
// `unreachable` instruction.
if cfg!(debug_assertions) {
alloc::handle_alloc_error(layout);
} else {
#[cfg(target_arch = "wasm32")]
core::arch::wasm32::unreachable();
#[cfg(not(target_arch = "wasm32"))]
unreachable!();
}
}
return ptr;
}
pub use wit_bindgen_rt::cabi_realloc;

pub use crate::pre_wit_bindgen_0_20_0::*;
}
Loading