Skip to content

Bug report: Generated Moonbit binding bug. #1587

Open

Description

@xiaozzzZZzzz240

Summary

When executing a Wasm component, there are two borrow operations of a handle. However, maybe the moonbit compilation has a bug, thus wasmtime traped.
The expected result to execute the component is:

[diag-single] borrow1=f1
[diag-single] size1=101
[diag-single] borrow2=f1
[diag-single] size2=101

repo: https://github.com/xiaozzzZZzzz240/twoborrowoperation

Environment

jco 1.16.1
wasmtime 41.0.0
OS: macOS Sequoia 15.7
CPU: Intel Core i7

Reproduce steps

The specific reproduction steps are as follows:

  1. Use the following command to generate Moonbit binding files from generated_wit_00000.wit.
    wit-bindgen moonbit xxx/witfiles/package3hl16smu1p --world world0-pvwxtgtmlk --out-dir xxx/moonbit/world0-pvwxtgtmlk

  2. Implement the Moonbit program as shown in the moonbit directory shown in the repo.

  3. Use the following command to generate Wasm component file from Moonbit.
    cd xxx/moonbit/world0-pvwxtgtmlk
    xxx/.moon/bin/moon build --target wasm --release
    wasm-tools component embed xxx/witfiles/package3hl16smu1p --world world0-pvwxtgtmlk xxx/moonbit/world0-pvwxtgtmlk/_build/wasm/release/build/gen/gen.wasm -o /var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/moonbit_3a9hf8_l.embed.wasm
    wasm-tools component new /var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/moonbit_3a9hf8_l.embed.wasm --realloc-via-memory-grow -o xxx/componentfiles/world0-pvwxtgtmlk_fromMoonBit.wasm']

  4. Use the following command to generate Rust binding files from generated_wit_00000b.wit.
    wit-bindgen rust xxx/witfiles/package3hl16smu1p --world world1-consumer --generate-all --out-dir xxx/rust/world1-consumer/wit_bindings

  5. Implement the Rust program as shown in the rust directory shown in the repo.

  6. Use the following command to generate Wasm component file from Rust.
    cd xxx/rust/world1-consumer
    cargo build --target wasm32-wasip2

  7. Use wac to combine the two Wasm component files:
    wac plug xxx/componentfiles/world1-consumer_fromRust.wasm --plug xxx/componentfiles/world0-pvwxtgtmlk_fromMoonBitwasm -o xxx/componentfiles/world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromMoonBit.wasm

  8. Use wasmtime to run the final Wasm component file:
    wasmtime run world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromMoonBit.wasm
    Wasmtime prints:

Error: failed to run main module `world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromMoonBit.wasm`

Caused by:
    0: failed to invoke `run` function
    1: error while executing at wasm backtrace:
           0:    0xf1e - <unknown>!<wasm function 42>
           1:    0xecb - <unknown>!<wasm function 38>
           2:    0xe23 - <unknown>!<wasm function 30>
           3:    0x1ef - <unknown>!<wasm function 12>
           4: 0x2bee7f - wit-component:shim!indirect-mydefined:package3hl16smu1p/itf0-tmmdqdfhit-read-borrow
           5:   0x241a - withinwit_rust_component.wasm!withinwit_rust_component::wit_bindings::mydefined::package3hl16smu1p::itf0_tmmdqdfhit::read_borrow::hafd891aec0edc6a9
           6:   0x2ae5 - withinwit_rust_component.wasm!<withinwit_rust_component::Component as withinwit_rust_component::wit_bindings::exports::wasi::cli::run::Guest>::run::hf6a1a59ac95c8ea4
           7:   0x2d16 - withinwit_rust_component.wasm!withinwit_rust_component::wit_bindings::exports::wasi::cli::run::_export_run_cabi::h276ae912c2818d67
           8:   0x2cab - withinwit_rust_component.wasm!wasi:cli/run@0.2.0#run
       note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    2: unknown handle index 1

Simplified reproduction steps

  1. Use wasmtime to run the final Wasm component file:
    wasmtime run world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromMoonBit.wasm
    Wasmtime prints:
Error: failed to run main module `world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromMoonBit.wasm`

Caused by:
    0: failed to invoke `run` function
    1: error while executing at wasm backtrace:
           0:    0xf1e - <unknown>!<wasm function 42>
           1:    0xecb - <unknown>!<wasm function 38>
           2:    0xe23 - <unknown>!<wasm function 30>
           3:    0x1ef - <unknown>!<wasm function 12>
           4: 0x2bee7f - wit-component:shim!indirect-mydefined:package3hl16smu1p/itf0-tmmdqdfhit-read-borrow
           5:   0x241a - withinwit_rust_component.wasm!withinwit_rust_component::wit_bindings::mydefined::package3hl16smu1p::itf0_tmmdqdfhit::read_borrow::hafd891aec0edc6a9
           6:   0x2ae5 - withinwit_rust_component.wasm!<withinwit_rust_component::Component as withinwit_rust_component::wit_bindings::exports::wasi::cli::run::Guest>::run::hf6a1a59ac95c8ea4
           7:   0x2d16 - withinwit_rust_component.wasm!withinwit_rust_component::wit_bindings::exports::wasi::cli::run::_export_run_cabi::h276ae912c2818d67
           8:   0x2cab - withinwit_rust_component.wasm!wasi:cli/run@0.2.0#run
       note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    2: unknown handle index 1

Result Analysis

When we use replace the Moonbit part with Rust, this bug does not exist, and
command: wasmtime run world1-consumer_fromRust_importworld0-pvwxtgtmlk_fromRust.wasm
wasmtime prints:

[diag-single] borrow1=f1
[diag-single] size1=101
[diag-single] borrow2=f1
[diag-single] size2=101

Activity

  1. changed the title [-]Bug report: Generated Moonbit glue code bug.[/-] [+]Bug report: Generated Moonbit binding bug.[/+] on Apr 14, 2026
  2. alexcrichton commented on Apr 14, 2026

    @alexcrichton
    Member
  3. peter-jerry-ye commented on Apr 15, 2026

    @peter-jerry-ye
    Contributor

    The issue is that you should not call rep on the borrowed resource. Instead of a bug, I would say this is more about a design flaw, where we didn't have the distinction between the owned and borrowed type yet, which is a missing feature.

  4. xiaozzzZZzzz240 commented on Apr 15, 2026

    @xiaozzzZZzzz240
    Author

    The issue is that you should not call rep on the borrowed resource. Instead of a bug, I would say this is more about a design flaw, where we didn't have the distinction between the owned and borrowed type yet, which is a missing feature.

    Thanks for your reply!
    Because of the current missing feature that does not distinguish between owned and borrowed, after generating the bindings, the code I wrote can also call rep within a borrow, which eventually causes wasmtime to crash. But logically, rep should not be called within a borrow. Is that what you mean?

  5. peter-jerry-ye commented on Apr 15, 2026

    @peter-jerry-ye
    Contributor

    Yes. I think you might want to play with the c generator, which has a very clear distinction between the borrowed / owned resources. That might give you some idea. I'll try to look if we can do anything to improve the user experience though.

  6. xiaozzzZZzzz240 commented on Apr 16, 2026

    @xiaozzzZZzzz240
    Author

    Yes. I think you might want to play with the c generator, which has a very clear distinction between the borrowed / owned resources. That might give you some idea. I'll try to look if we can do anything to improve the user experience though.

    Thanks for your reply!
    Will you add the distinction between owner and borrowed bindings for resources in MoonBit in the future?

  7. peter-jerry-ye commented on Apr 17, 2026

    @peter-jerry-ye
    Contributor

    I would prefer not to add the distinction, because it would make things complicated. For example, how would you put Owned[A] and Borrowed[A] into the same array?

    I think we might do some underlying handling, but not very likely to expose it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions