Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 27 additions & 2 deletions scripts/build-components.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,21 @@ build_component() {
local dir="$1"
local wasm_dir="$HERE/wasm/cm/$dir"
printf " building %-16s..." "$dir" >&2
( cd "$wasm_dir" && cargo component build --release --target wasm32-wasip2 --no-default-features 2>&1 ) \
| grep -E "^error" | sed 's/^/ /' >&2 || true
# FAIL LOUD (v1.130): this used to end in `|| true`, so a build error was
# printed and then IGNORED — the script fell through to a stale artifact from
# a previous build and shipped it. That is exactly how falcon-rate:1.129.0 was
# published as a raw CORE MODULE: the no_std wasip2 build failed
# ("module does not export a function named `cabi_realloc`"), the failure was
# swallowed, and the fallback picked up a pre-componentization module.
# A build failure must stop the bundle, not degrade it silently.
if ! ( cd "$wasm_dir" && cargo component build --release --target wasm32-wasip2 --no-default-features 2>&1 ) \
| tee /tmp/falcon-build-$dir.log | grep -E "^error" | sed 's/^/ /' >&2; then
: # grep found no "^error" lines — that is the success path
fi
if grep -qE "^error" /tmp/falcon-build-$dir.log 2>/dev/null; then
echo " ERROR: cargo component build failed for $dir (see above)" >&2
exit 1
fi
# Prefer the wasip2 path; cargo-component <0.20 emits wasip1.
local src
src=$(ls "$wasm_dir"/target/wasm32-wasip2/release/*.wasm 2>/dev/null | head -1 || true)
Expand All @@ -66,6 +79,18 @@ build_component() {
local slug="${dir#falcon-}"
local dest="$BUNDLE_DIR/falcon-$slug-v$MM.wasm"
cp "$src" "$dest"
# ASSERT the payload really is a Component, not a core module (v1.130).
# jess found falcon-rate:1.129.0 shipped as a core module — `meld fuse`
# rejected it outright. The OCI config mediaType says "component" regardless
# of the bytes, so metadata cannot catch this; check the 8-byte header.
# core module : 00 61 73 6d 01 00 00 00
# component : 00 61 73 6d 0d 00 01 00
magic=$(od -An -tx1 -N8 "$dest" | tr -d ' \n')
if [ "$magic" != "0061736d0d000100" ]; then
echo " ERROR: $dest is NOT a wasm component (header $magic)" >&2
echo " expected 0061736d0d000100; a core module is 0061736d01000000" >&2
exit 1
fi
local bytes
bytes=$(wc -c < "$dest" | tr -d ' ')
printf " %s bytes\n" "$bytes" >&2
Expand Down
34 changes: 34 additions & 0 deletions wasm/cm/rate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,40 @@
static ALLOC: lol_alloc::AssumeSingleThreaded<lol_alloc::FreeListAllocator> =
unsafe { lol_alloc::AssumeSingleThreaded::new(lol_alloc::FreeListAllocator::new()) };

// The Component-Model canonical ABI requires the guest to export
// `cabi_realloc`. wit-bindgen-rt provides it ONLY when it can lean on std —
// its implementation is `#[cfg(not(target_env = "p2"))]`, because on
// wasm32-wasip2 it expects the std toolchain to supply the symbol. This crate
// is `no_std` on the cargo-component path, so nothing exported it and
// `wasm-component-ld` failed with "module does not export a function named
// `cabi_realloc`" — leaving a raw CORE MODULE where a component was expected.
// Export it here, backed by the same single-threaded allocator.
#[cfg(not(feature = "bazel-bindings"))]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cabi_realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8 {
use core::alloc::{GlobalAlloc, Layout};
unsafe {
if old_len == 0 {
// Canonical ABI: a zero-size allocation returns the alignment as a
// non-null, suitably-aligned dangling pointer.
if new_len == 0 {
return align as *mut u8;
}
return ALLOC.alloc(Layout::from_size_align_unchecked(new_len, align));
}
ALLOC.realloc(
old_ptr,
Layout::from_size_align_unchecked(old_len, align),
new_len,
)
}
}

// Bindings generated by cargo-component as src/bindings.rs.
#[allow(warnings)]
#[cfg(feature = "bazel-bindings")]
Expand Down
Loading