Fix hotpatched assets (#4326)

* wip: fixes to get docsite working again

* Fix asset location with PIC in hot patched builds

* Add an hidden cli flag to exit early in hot patch tests on failure

* add a test for hot patching with assets

* fix clippy

* fix looks_like_manganis_symbol

* longer timeout for hot patching in CI

* log page content

* log assets

* Log asset after write

* record a playwright trace

* Explicitly enable cargo incremental for hot patching

* fix retry for patch test

* reset asset

* disable hot patching test for new exports

* add nightly playwright

* use different toolchain names

* use beta instead of nightly for less thrashing

* add failing test

* workaround hot reloading bug

* restore swapping asset tests

* add toolchain

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2025-06-30 16:23:04 -07:00
1 parent 6cc379718b
commit 2071be2b67
20 files changed
+365 -125

No files matched your search

+11 -7
View File
@@ -127,13 +127,15 @@ impl BundledAsset {
/// ```
#[derive(PartialEq, Clone, Copy)]
pub struct Asset {
/// A pointer to the bundled asset. This will be resolved after the linker has run and
/// put into the lazy asset
/// A function that returns a pointer to the bundled asset. This will be resolved after the linker has run and
/// put into the lazy asset. We use a function instead of using the pointer directly to force the compiler to
/// read the static __REFERENCE_TO_LINK_SECTION at runtime which will be offset by the hot reloading engine instead
/// of at compile time which can't be offset
///
/// WARNING: Don't read this directly. Reads can get optimized away at compile time before
/// the data for this is filled in by the CLI after the binary is built. Instead, use
/// [`std::ptr::read_volatile`] to read the data.
bundled: &'static [u8],
bundled: fn() -> &'static [u8],
}
impl Debug for Asset {
@@ -149,14 +151,15 @@ impl Asset {
#[doc(hidden)]
/// This should only be called from the macro
/// Create a new asset from the bundled form of the asset and the link section
pub const fn new(bundled: &'static [u8]) -> Self {
pub const fn new(bundled: fn() -> &'static [u8]) -> Self {
Self { bundled }
}
/// Get the bundled asset
pub fn bundled(&self) -> BundledAsset {
let len = self.bundled.len();
let ptr = self.bundled as *const [u8] as *const u8;
let bundled = (self.bundled)();
let len = bundled.len();
let ptr = bundled as *const [u8] as *const u8;
if ptr.is_null() {
panic!("Tried to use an asset that was not bundled. Make sure you are compiling dx as the linker");
}
@@ -164,7 +167,8 @@ impl Asset {
for byte in 0..len {
// SAFETY: We checked that the pointer was not null above. The pointer is valid for reads and
// since we are reading a u8 there are no alignment requirements
bytes = bytes.push(unsafe { std::ptr::read_volatile(ptr.add(byte)) });
let byte = unsafe { std::ptr::read_volatile(ptr.add(byte)) };
bytes = bytes.push(byte);
}
let read = bytes.read();
deserialize_const!(BundledAsset, read).expect("Failed to deserialize asset. Make sure you built with the matching version of the Dioxus CLI").1
@@ -120,7 +120,7 @@ impl ToTokens for AssetParser {
static __REFERENCE_TO_LINK_SECTION: &'static [u8] = &__LINK_SECTION;
manganis::Asset::new(
__REFERENCE_TO_LINK_SECTION
|| __REFERENCE_TO_LINK_SECTION
)
}
})