Fix image reuse with multi-memory images (#3846)
This commit fixes a potential issue where the fast-path instantiate in `MemoryImageSlot` where when the previous image is compared against the new image it only performed file descriptor equality, but nowadays with loading images from `*.cwasm` files there might be multiple images in the same file so the offsets also need to be considered. I think this isn't really easy to hit today, it would require combining both module linking and multi-memory which gets into the realm of being pretty esoteric so I haven't added a test case here for this.
This commit is contained in:
@@ -27,7 +27,7 @@ impl ModuleMemoryImages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// One backing image for one memory.
|
/// One backing image for one memory.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct MemoryImage {
|
pub struct MemoryImage {
|
||||||
/// The file descriptor source of this image.
|
/// The file descriptor source of this image.
|
||||||
///
|
///
|
||||||
@@ -75,6 +75,12 @@ impl FdSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for FdSource {
|
||||||
|
fn eq(&self, other: &FdSource) -> bool {
|
||||||
|
self.as_file().as_raw_fd() == other.as_file().as_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MemoryImage {
|
impl MemoryImage {
|
||||||
fn new(
|
fn new(
|
||||||
page_size: u32,
|
page_size: u32,
|
||||||
@@ -348,14 +354,7 @@ impl MemoryImageSlot {
|
|||||||
// termination. The `clear_and_remain_ready()` path also
|
// termination. The `clear_and_remain_ready()` path also
|
||||||
// mprotects memory above the initial heap size back to
|
// mprotects memory above the initial heap size back to
|
||||||
// PROT_NONE, so we don't need to do that here.
|
// PROT_NONE, so we don't need to do that here.
|
||||||
if (self.image.is_none()
|
if self.image.as_ref() == maybe_image && self.initial_size == initial_size_bytes {
|
||||||
&& maybe_image.is_none()
|
|
||||||
&& self.initial_size == initial_size_bytes)
|
|
||||||
|| (self.image.is_some()
|
|
||||||
&& maybe_image.is_some()
|
|
||||||
&& self.image.as_ref().unwrap().fd.as_file().as_raw_fd()
|
|
||||||
== maybe_image.as_ref().unwrap().fd.as_file().as_raw_fd())
|
|
||||||
{
|
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user