Merge pull request from GHSA-wh6w-3828-g9qf
* Unconditionally use `MemoryImageSlot` This commit removes the internal branching within the pooling instance allocator to sometimes use a `MemoryImageSlot` and sometimes now. Instead this is now unconditionally used in all situations on all platforms. This fixes an issue where the state of a slot could get corrupted if modules being instantiated switched from having images to not having an image or vice versa. The bulk of this commit is the removal of the `memory-init-cow` compile-time feature in addition to adding Windows support to the `cow.rs` file. * Fix compile on Unix * Add a stricter assertion for static memory bounds Double-check that when a memory is allocated the configuration required is satisfied by the pooling allocator.
This commit is contained in:
@@ -579,6 +579,63 @@ fn drop_externref_global_during_module_init() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switch_image_and_non_image() -> Result<()> {
|
||||
let mut pool = PoolingAllocationConfig::default();
|
||||
pool.instance_count(1);
|
||||
let mut c = Config::new();
|
||||
c.allocation_strategy(InstanceAllocationStrategy::Pooling(pool));
|
||||
let engine = Engine::new(&c)?;
|
||||
let module1 = Module::new(
|
||||
&engine,
|
||||
r#"
|
||||
(module
|
||||
(memory 1)
|
||||
(func (export "load") (param i32) (result i32)
|
||||
local.get 0
|
||||
i32.load
|
||||
)
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
let module2 = Module::new(
|
||||
&engine,
|
||||
r#"
|
||||
(module
|
||||
(memory (export "memory") 1)
|
||||
(data (i32.const 0) "1234")
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let assert_zero = || -> Result<()> {
|
||||
let mut store = Store::new(&engine, ());
|
||||
let instance = Instance::new(&mut store, &module1, &[])?;
|
||||
let func = instance.get_typed_func::<i32, i32, _>(&mut store, "load")?;
|
||||
assert_eq!(func.call(&mut store, 0)?, 0);
|
||||
Ok(())
|
||||
};
|
||||
|
||||
// Initialize with a heap image and make sure the next instance, without an
|
||||
// image, is zeroed
|
||||
Instance::new(&mut Store::new(&engine, ()), &module2, &[])?;
|
||||
assert_zero()?;
|
||||
|
||||
// ... transition back to heap image and do this again
|
||||
Instance::new(&mut Store::new(&engine, ()), &module2, &[])?;
|
||||
assert_zero()?;
|
||||
|
||||
// And go back to an image and make sure it's read/write on the host.
|
||||
let mut store = Store::new(&engine, ());
|
||||
let instance = Instance::new(&mut store, &module2, &[])?;
|
||||
let memory = instance.get_memory(&mut store, "memory").unwrap();
|
||||
let mem = memory.data_mut(&mut store);
|
||||
assert!(mem.starts_with(b"1234"));
|
||||
mem[..6].copy_from_slice(b"567890");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn instance_too_large() -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user