🔖
jco componentizeで-d allしてもimport wasi:io/pollが残ってしまう
発生事象
jcoのドキュメント上にあるサンプルをベースに以下を実行する。
> npx jco --version
1.8.1
> npx jco componentize cowsay.js --wit cowsay.wit -o cowsay.wasm
> npx jco wit .\cowsay.wasm
package root:component;
world root {
import wasi:io/error@0.2.2;
import wasi:io/poll@0.2.2;
import wasi:io/streams@0.2.2;
import wasi:cli/stdin@0.2.2;
import wasi:cli/stdout@0.2.2;
import wasi:cli/stderr@0.2.2;
import wasi:cli/terminal-input@0.2.2;
import wasi:cli/terminal-output@0.2.2;
import wasi:cli/terminal-stdin@0.2.2;
import wasi:cli/terminal-stdout@0.2.2;
import wasi:cli/terminal-stderr@0.2.2;
import wasi:clocks/monotonic-clock@0.2.2;
import wasi:clocks/wall-clock@0.2.2;
import wasi:filesystem/types@0.2.2;
import wasi:filesystem/preopens@0.2.2;
import wasi:random/random@0.2.2;
import wasi:http/types@0.2.2;
import wasi:http/outgoing-handler@0.2.2;
export cow: interface {
enum cows {
default,
owl,
}
say: func(text: string, cow: option<cows>) -> string;
}
}
> npx jco componentize cowsay.js --wit cowsay.wit -o cowsay.wasm -d all
> npx jco wit .\cowsay.wasm
package root:component;
world root {
import wasi:io/poll@0.2.2;
export cow: interface {
enum cows {
default,
owl,
}
say: func(text: string, cow: option<cows>) -> string;
}
}
本来jcoの-dオプションにallを指定するとimportがなくなるはずだが、wasi:io/pollが残ってしまう。
推測される原因
ComponentizeJSでは同問題の報告がある。
ComponentizeJS側では修正をリリース済みだが、jcoには取り込まれていないと考えられる。
対処法
ComponentizeJSを直接利用する。
参考:https://github.com/bytecodealliance/ComponentizeJS/blob/main/EXAMPLE.md
componentize-jsのバージョン
> npm list @bytecodealliance/componentize-js
20250109_jco@1.0.0
├── @bytecodealliance/componentize-js@0.15.1
└─┬ @bytecodealliance/jco@1.8.1
└── @bytecodealliance/componentize-js@0.14.0
以下の内容でconvert.mjsを作成
import { componentize } from '@bytecodealliance/componentize-js';
import { readFile, writeFile } from 'node:fs/promises';
const jsSource = await readFile('cowsay.js', 'utf8');
const witSource = await readFile('cowsay.wit', 'utf8');
const { component } = await componentize(jsSource, witSource, {disableFeatures: ['clocks', 'http', 'random', 'stdio']});
await writeFile('cowsay2.wasm', component);
以下のコマンドを実行
> node convert.mjs
> npx jco wit .\cowsay2.wasm
package root:component;
world root {
export cow: interface {
enum cows {
default,
owl,
}
say: func(text: string, cow: option<cows>) -> string;
}
}
生成されたwasmファイルは10MBくらい、変換には50秒(@Core i5-8265U)程度を要した。
(かなり弱めのCPUなので通常のデスクトップならもっと早いと思われる)
動作確認
実際に動かしてみる。
WASM Componentは動かす方法が良く分からない...(適当にcli向けラッパを作るのが良い?)
wasmtime run(失敗)
wasmtime runでinvokeは出来無さそう
>wasmtime run --invoke say cowsay2.wasm
Error: failed to run main module `cowsay2.wasm`
Caused by:
using `--invoke` with components is not supported
Pythonから
Pythonから呼んでみる。
(参考: https://component-model.bytecodealliance.org/language-support/python.html#running-components-from-python-applications )
binding生成
> pipenv run python -m wasmtime.bindgen cowsay2.wasm --out-dir cowsay2py
Generating cowsay2py\__init__.py
Generating cowsay2py\exports\__init__.py
Generating cowsay2py\exports\cow.py
Generating cowsay2py\intrinsics.py
Generating cowsay2py\root.core0.wasm
load2.py
from cowsay2py import Root
from cowsay2py.exports.cow import Cow, Cows
from wasmtime import Store
def main():
store = Store()
component = Root(store)
cow = Cow(component)
print(cow.say(store, "Hello, World!", Cows.DEFAULT))
print(cow.say(store, "Hello, World from owl!", Cows.OWL))
if __name__ == '__main__':
main()
実行
> pipenv run python .\load2.py
Hello, World!
\ ^__^
\ (oo)\______
(__)\ )/\
||----w |
|| ||
Hello, World from owl!
___
(o o)
( V )
/--m-m-
Discussion