Stream: git-wasmtime

Topic: wasmtime / PR #13591 feat(runtime): Memory swapping


view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 21:09):

frau requested dicej for a review on PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 21:09):

frau requested wasmtime-core-reviewers for a review on PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 21:09):

frau opened PR #13591 from frau:memory-swap to bytecodealliance:main:

Hot swap an existing Memory backing buffer with another. Requires the new memory to be shaped the same as the old.

Obviously this won't be safe for the semantics of a wasm module that isn't expecting it, but I'm writing a program which would benefit from hot-swapping specific linear memory banks in and out while retaining the same code module.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 22:13):

github-actions[bot] added the label wasmtime:api on PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 23:48):

alexcrichton requested alexcrichton for a review on PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 23:48):

alexcrichton unassigned dicej from PR #13591 feat(runtime): Memory swapping.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 08 2026 at 23:53):

alexcrichton commented on PR #13591:

Thanks for the PR and interest here, but Wasmtime's memory implementation is not something that can be easily changed and modified to contain a new major feature. Even with LLM assistance this is still quite difficult to do, for example this test aborts with this PR:

#[test]
fn smoke() -> Result<()> {
    let mut pool = crate::small_pool_config();
    pool.total_memories(2).max_memory_size(1 << 16);
    let mut config = Config::new();
    config.allocation_strategy(pool);
    config.memory_guard_size(0);
    config.memory_reservation(1 << 16);
    let engine = Engine::new(&config)?;
    let module = Module::new(
        &engine,
        r#"
            (module
                (memory (export "m") 1 1)
                (func (export "store") (param i32 i32)
                    local.get 0
                    local.get 1
                    i32.store8)
                (func (export "load") (param i32) (result i32)
                    local.get 0
                    i32.load8_u))
        "#,
    )?;
    let mut store = Store::new(&engine, ());
    let instance = Instance::new(&mut store, &module, &[])?;
    let pooled = instance.get_memory(&mut store, "m").unwrap();
    let host = Memory::new(&mut store, MemoryType::new(1, Some(1)))?;
    pooled.data_mut(&mut store)[0] = 0x11;
    host.data_mut(&mut store)[0] = 0x22;
    pooled
        .swap(&mut store, &host)
        .expect("swap should be (incorrectly) accepted across allocators");
    let load = instance.get_typed_func::<i32, i32>(&mut store, "load")?;
    assert_eq!(load.call(&mut store, 0)?, 0x22);
    drop(store);
    Ok(())
}

If you are able to you'll get a lot more mileage out of this if you can reframe your problem in terms of standard wasm primitives and/or Wasmtime's APIs. For example if you can create an entirely new instance that should be a pretty cheap operation. You could then be responsible for transferring over state not related to a memory (e.g. globals) or things like that.

As-is I don't believe that there's going to be a way to add this feature to Wasmtime easily, which is why I'd encuorage you to try to reframe this in terms of preexisting primitives.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 05:57):

frau commented on PR #13591:

Thank you for the counter example. I gather that you wouldn't be interested in supporting this as a primitive even with a guard on matching allocator types and other fixes as needed. I might go back to fanning out multiple instances or maintain this privately depending on perf.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 14:23):

alexcrichton commented on PR #13591:

What I'm pointing out here is that extending the memory subsystem is a significant investment. Pointing an LLM at it and making a PR isn't sufficient, but instead it needs to be deeply thought about with how it relates to the rest of the system. By posting this PR you're asking maintainer sto take on this investment and perform this review/analysis/etc, and what I'm trying to do is point this out and recommend trying alternatives first. If an alternative of using instances or similar works for you then that would be ideal.

If using instances does not work for your use case and this sort of API is absolutely required, then I'm not saying it's impossible to implement. The exact reason of why it doesn't work for your use case would shape the conversation about possibly including this in Wasmtime itself, and we're basically not quite there yet for at least me to offer opinions one way or another as to whether it would make sense to land.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 18:30):

frau commented on PR #13591:

It would have to fit with the system harmoniously, I understand. Thank you for your consideration

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 20:21):

frau updated PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 20:23):

:cross_mark: frau closed without merge PR #13591.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 09 2026 at 20:23):

frau commented on PR #13591:

I pushed some simple fixes in case anyone else stumbles on this branch. I'll go back to cooking on my project.


Last updated: Jul 29 2026 at 05:03 UTC