Stream: git-wasmtime

Topic: wasmtime / PR #14462 component(breaking): support canonic...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:21):

chenyan2002 opened PR #14462 from chenyan2002:namemap to bytecodealliance:main:

Fix https://github.com/bytecodealliance/wasmtime/issues/14346

Breaking changes:

Concretely, we changed the following:

As a side effect, this fixed a bug about define_unknown_imports_as_traps. Before, this flag was not semver aware, so a guest importing a:b/c@0.1.0 with a:b/c@0.1.1 on the host will get traps for the imports, instead of linking to 0.1.1.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:21):

chenyan2002 requested cfallin for a review on PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:21):

chenyan2002 requested wasmtime-core-reviewers for a review on PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:21):

chenyan2002 requested alexcrichton for a review on PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:21):

chenyan2002 requested wasmtime-default-reviewers for a review on PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 03:35):

chenyan2002 updated PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 04:45):

chenyan2002 edited PR #14462:

Fix https://github.com/bytecodealliance/wasmtime/issues/14346

Breaking changes:

Concretely, we changed the following:

As a side effect, this fixed a bug about define_unknown_imports_as_traps. Before, this flag was not semver aware, so a guest importing a:b/c@0.1.0 with a:b/c@0.1.1 on the host will get traps for the imports, instead of linking to 0.1.1.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 04:46):

chenyan2002 updated PR #14462.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2026 at 05:49):

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

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2026 at 21:19):

:memo: alexcrichton submitted PR review:

Thanks for this! At a high level this feels like a good approach to take, but I think that there might be some details to work out still. My main hesitation here has to do with how Wasmtime reinterepts loaded components. Rejecting duplicate-exports-named-different-ways seems fine to me, but as-implemented this has some interesting behavior on some components:

An example of the first issue is:

<details>

#[test]
#[cfg_attr(miri, ignore)]
fn component_type_covers_imports_with_same_full_name() -> Result<()> {
    let mut config = Config::new();
    config.wasm_component_model_canonical_names(true);
    let engine = Engine::new(&config)?;
    // Two distinct imports with the same full name, `a:b/c@0.2.1`, but
    // different types.
    let component = r#"
        (component
            (import "a:b/c@0.2" (versionsuffix ".1") (instance
                (export "f" (func))
            ))
            (import "a:b/c@0.2.1" (instance
                (export "g" (func))
            ))
        )
    "#;
    let component = Component::new(&engine, component)?;

    // Define everything that `component_type` says is imported, which should
    // be enough to instantiate the component.
    let mut linker = Linker::<()>::new(&engine);
    for (name, import) in component.component_type().imports(&engine) {
        let types::ComponentItem::ComponentInstance(ty) = import.ty else {
            panic!("expected an instance");
        };
        let mut instance = linker.instance(name)?;
        for (export, _) in ty.exports(&engine) {
            instance.func_wrap(export, |_, (): ()| Ok(()))?;
        }
    }

    let mut store = Store::new(&engine, ());
    linker.instantiate(&mut store, &component)?;

    Ok(())
}

</details>

and an example of the second issue is:

<details>

#[test]
#[cfg_attr(miri, ignore)]
fn nested_export_keeps_highest_with_versionsuffix() -> Result<()> {
    let mut config = Config::new();
    config.wasm_component_model_canonical_names(true);
    let engine = Engine::new(&config)?;
    let component = r#"
        (component
            (core module $m1)
            (core module $m2 (import "" "" (func)))
            (instance $i1 (export "m" (core module $m1)))
            (instance $i2 (export "m" (core module $m2)))

            (instance $o
                (export "a:b/n@0.2.1" (instance $i1))
                (export "a:b/n@0.2" (versionsuffix ".3") (instance $i2))
            )
            (export "o" (instance $o))
        )
    "#;

    fn assert_m2(module: &Module) {
        assert_eq!(module.imports().len(), 1);
    }

    let component = Component::new(&engine, component)?;

    // Only the highest full version on a semver track is exported, which for
    // `a:b/n@0.2` is `a:b/n@0.2.3` due to its `versionsuffix`.
    let ty = component.component_type();
    let (_, o) = ty
        .exports(&engine)
        .find(|(name, _)| *name == "o")
        .unwrap();
    let types::ComponentItem::ComponentInstance(o) = o.ty else {
        panic!("expected an instance");
    };
    let names = o
        .exports(&engine)
        .map(|(name, _)| name.to_string())
        .collect::<Vec<_>>();
    assert_eq!(names, ["a:b/n@0.2.3"]);

    let mut store = Store::new(&engine, ());
    let instance = Linker::new(&engine).instantiate(&mut store, &component)?;

    let o = component.get_export_index(None, "o").unwrap();
    for name in ["a:b/n@0.2.1", "a:b/n@0.2.3", "a:b/n@0.2"] {
        println!("test {name}");
        let i = component.get_export_index(Some(&o), name).unwrap();
        let m = component.get_export_index(Some(&i), "m").unwrap();
        assert_m2(&instance.get_module(&mut store, &m).unwrap());
    }

    Ok(())
}

</details>

Overall though I like the idea of moving closer to a world where we might actually be able to only accept canonical names by default. I mostly just want to make sure that everything's lined up to at least not break anyone as-is while we transition over.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2026 at 21:19):

:speech_balloon: alexcrichton created PR review comment:

Could this have a small comment for what it's rejecting? This is rejecting [method]a.b for an instance name, right?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2026 at 21:22):

alexcrichton commented on PR #14462:

Oh another thing I want to mention -- I think it'd be good to try to get as much feedback about this before landing this as this has a nontrivial chance of breaking downstream consumers. One example I think would be to update https://github.com/spinframework/spin to use this PR (on a branch or maybe in CI over there) to ensure that all tests still pass. I'm not sure if that'd be a complete test suite, but I know Spin often exposes various colorful ways of satisfying component imports and such. It might also be good to run wac's test suite, and perhaps wit-bindgen's, although wit-bindgen's I doubt would stress anything here.

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

chenyan2002 edited PR #14462:

Fix https://github.com/bytecodealliance/wasmtime/issues/14346

Breaking changes:

Concretely, we changed the following:

As a side effect, this fixed a bug about define_unknown_imports_as_traps. Before, this flag was not semver aware, so a guest importing a:b/c@0.1.0 with a:b/c@0.1.1 on the host will get traps for the imports, instead of linking to 0.1.1.

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

chenyan2002 updated PR #14462.

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

:memo: chenyan2002 submitted PR review.

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

:speech_balloon: chenyan2002 created PR review comment:

Yes, added.


Last updated: Oct 11 2026 at 04:10 UTC