Summary
We use MoonBit and Tinygo to construct a Wasm component and use wasmtime and jco to execute it.
The logic of this component is:
- world0 (MoonBit provider) exposes a function: ping() -> u32, which always returns 7.
- world1 (TinyGo consumer) calls the imported ping() in main().
- world1 prints the result: [min-ping] ping=7.
Wasm time prints correctly, however, jco crashed.
repo: https://github.com/xiaozzzZZzzz240/jco_issue_1391
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:
-
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
-
Implement the Moonbit program as shown in the moonbit directory shown in the repo.
-
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']
-
Use the following command to generate Tinygo binding files from generated_wit_00000b.wit.
cd xxx/tinygo/world1-consumer
xxx/go/bin/wit-bindgen-go generate xxx/witfiles/package3hl16smu1p --world world1-consumer --package-root wit_component --out .
-
Implement the Tinygo program as shown in the tinygo directory shown in the repo.
-
Use the following command to generate Wasm component file from Tinygo.
cd xxx/tinygo/world1-consumer
go mod init wit_component
go get go.bytecodealliance.org/[email protected]
go mod tidy
tinygo build -target=wasip2 -wit-package xxx/witfiles/package3hl16smu1p -wit-world world1-consumer -o xxx/componentfiles/world1-consumer_fromTinyGo.wasm .
-
Use wac to combine the two Wasm component files:
wac plug xxx/componentfiles/world1-consumer_fromTinyGo.wasm --plug xxx/componentfiles/world0-pvwxtgtmlk_fromMoonBit.wasm -o xxx/componentfiles/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasm
-
Use wasmtime to run the final Wasm component file:
wasmtime run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasm
Wasmtime prints:
- Use jco to run the same final Wasm component file:
jco run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasm
jco prints:
file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:2037
const { taskID } = _getGlobalCurrentTaskMeta(componentIdx);
^
TypeError: Cannot destructure property 'taskID' of '_getGlobalCurrentTaskMeta(...)' as it is undefined.
at _lowerImportBackwardsCompat (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:2037:11)
at main._initialize (wasm://wasm/main-002e65a6:wasm-function[124]:0xdb52)
at _initGenerator (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:9957:36)
at _initGenerator.next (<anonymous>)
at runNext (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:9969:32)
Node.js v25.8.1
Simplified reproduction steps
- Use wasmtime to run the final Wasm component file:
wasmtime run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasm
Wasmtime prints:
- Use jco to run the same final Wasm component file:
jco run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasm
jco prints:
file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:2037
const { taskID } = _getGlobalCurrentTaskMeta(componentIdx);
^
TypeError: Cannot destructure property 'taskID' of '_getGlobalCurrentTaskMeta(...)' as it is undefined.
at _lowerImportBackwardsCompat (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:2037:11)
at main._initialize (wasm://wasm/main-002e65a6:wasm-function[124]:0xdb52)
at _initGenerator (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:9957:36)
at _initGenerator.next (<anonymous>)
at runNext (file:///private/var/folders/ng/263gml_52h33wsbthhfjjr980000gn/T/ywvAxO/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.js:9969:32)
Node.js v25.8.1
Result Analysis
The cause of this bug may be that when lowering is triggered in _initialize, the current path does not set CURRENT_TASK_META first; the runtime code then assumes it must exist and directly destructures it, leading to a crash. This is a context management flaw in the jco runtime/bindgen glue.
Summary
We use MoonBit and Tinygo to construct a Wasm component and use wasmtime and jco to execute it.
The logic of this component is:
Wasm time prints correctly, however, jco crashed.
repo: https://github.com/xiaozzzZZzzz240/jco_issue_1391
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:
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-pvwxtgtmlkImplement the Moonbit program as shown in the moonbit directory shown in the repo.
Use the following command to generate Wasm component file from Moonbit.
cd xxx/moonbit/world0-pvwxtgtmlkxxx/.moon/bin/moon build --target wasm --releasewasm-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.wasmwasm-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']Use the following command to generate Tinygo binding files from generated_wit_00000b.wit.
cd xxx/tinygo/world1-consumerxxx/go/bin/wit-bindgen-go generate xxx/witfiles/package3hl16smu1p --world world1-consumer --package-root wit_component --out .Implement the Tinygo program as shown in the tinygo directory shown in the repo.
Use the following command to generate Wasm component file from Tinygo.
cd xxx/tinygo/world1-consumergo mod init wit_componentgo get go.bytecodealliance.org/[email protected]go mod tidytinygo build -target=wasip2 -wit-package xxx/witfiles/package3hl16smu1p -wit-world world1-consumer -o xxx/componentfiles/world1-consumer_fromTinyGo.wasm .Use wac to combine the two Wasm component files:
wac plug xxx/componentfiles/world1-consumer_fromTinyGo.wasm --plug xxx/componentfiles/world0-pvwxtgtmlk_fromMoonBit.wasm -o xxx/componentfiles/world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasmUse wasmtime to run the final Wasm component file:
wasmtime run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasmWasmtime prints:
jco run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasmjco prints:
Simplified reproduction steps
wasmtime run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasmWasmtime prints:
jco run world1-consumer_fromTinyGo_importworld0-pvwxtgtmlk_fromMoonBit.wasmjco prints:
Result Analysis
The cause of this bug may be that when lowering is triggered in _initialize, the current path does not set CURRENT_TASK_META first; the runtime code then assumes it must exist and directly destructures it, leading to a crash. This is a context management flaw in the jco runtime/bindgen glue.