Skip to content

Failed to build a Wasm component from the Wasm core module with "non-component" imports #334

Closed
@greenhat

Description

@greenhat

TLDR; Using core Wasm module imports for our intrinsics and Miden SDK functions is not playing well with the Wasm component model.

What

When building a Wasm component from a Wasm core module compiled from the basic-wallet with Rust SDK example, the build fails with the following error:

Caused by:
    0: module was not valid
    1: module requires an import interface named `miden::account`

Why

The reason for this error is that the Wasm core module contains imports that wit-component(used by cargo-component to build the Wasm component) fails to recognize as component imports, i.e. imports that are defined in the WIT file. In this case, it's miden::account::add_asset tx kernel function from the Miden SDK. Effectively, all our intrinsics and Miden SDK functions are triggering this error.

This happens at https://github.com/bytecodealliance/wasm-tools/blob/51ade657f6d6874b1bdfb87a47299dbe7e61d5c2/crates/wit-component/src/validation.rs#L411-L491, where the module name of the core module import is expected to be found in the interface imports in the WIT file.

How to reproduce

In #329 branch run:

RUST_LOG=debug cargo test rust_sdk_basic

To check out the Wasm core module, use wasm-tools print PATH_TO_CORE_WASM with the path reported in logs at componentizing WebAssembly module ...

How to fix

The most promising approach IMO would be to not use Wasm core module imports for our intrinsics and Miden SDK functions. The reason why wit-component treats them as errors is fair, and I think it'd be difficult if at all possible to alter that behavior in the upstream.

So instead of defining our Miden SDK functions and intrinsics as extern https://github.com/0xPolygonMiden/compiler/blob/a876d8b134bc118e1944b5a72747cf2c13a235a1/sdk/base-sys/src/bindings/tx/externs.rs#L5-L13
we could define them as functions with unreachable!() bodies and recognize them by function names and signatures in the frontend:

#[inline(never)]
#[no_mangle]
fn miden_account_add_asset(_: Felt, _: Felt, _: Felt, _: Felt, ptr: *mut CoreAsset) {
    unreachable!()
}

Although, #[inline(never)] is only a hint to the compiler, with a side effect in the body we should be safe from inlining.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockerThis issue is one of our top priorities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions