🌕

MoonbitのFFI周りを試してみたよ

2024/10/06に公開

@corocn です。Moonbit もくもく会 に参加したので、やったことまとめておきます。

書いてる人のスキル感

  • 普段はスタートアップでWebアプリケーション書いてる。だいたい TS + Ruby。
  • Rustbookを3年前に2周して、適当な画像合成ツール作った程度(ほとんど忘れている)
  • WASMをちゃんと動かしたこともない。
  • もくもく会ではじめて触る。

やりたいこと

  • WASM出力できるのでせっかくならFFIでconsole.logしたい(皆もそうだろ?)
  • JSから関数を渡す -> 渡された関数呼んでごにょごにょする関数作ってexport -> JSから呼んで実行

作ったもの

Math.random を実行して、適当に加工して出力する

https://github.com/corocn/moonbit-wasm-ffi-sample

ソース

moon new して以下を設置

index.html
<html lang="ja">
<head>
  <script type="module" src="main.mjs"></script>
</head>
</html>
main.mjs
const { instance: { exports } } = await WebAssembly.instantiateStreaming(
    fetch(new URL("/target/wasm-gc/release/build/main/main.wasm", import.meta.url)),
    {
        Math: {
            random: Math.random
        }
    }
);

const ret = exports.moonbit_random();
console.log(ret)
src/main/main.mbt
fn js_math_random() -> Double = "Math" "random"

pub fn moonbit_random() -> Int {
  let x = js_math_random() * 100.0
  x.to_int()
}
src/main/moon.pkg.json
{
  "link": {
    "wasm": {
      "exports": ["moonbit_random"]
    },
    "wasm-gc": {
      "exports": ["moonbit_random"]
    }
  }
}

実行

moon build --target wasm-gc
python3 -m http.server 8080

結果

ちゃんと出た

ちなみに上記コードで吐き出されたwasmは119byte でした。
めちゃくちゃ小さいね。

感想

RustっぽいけどRustより読みやすいなという雑な感想でした。(簡単なコードしか見てないので、参照&が出てこないせいかな・・・)

FFIは環境インスコしてから1時間ぐらいで動いたので非常に楽だったように思えます。

この開発段階でtoolchainやlspが一定揃ってるのは凄いですね。
moon newするまでノートラブルで、コンパイラもVSCode拡張もさくっと入った。

触ってみた感じ、期待したより結構良さそうな感じでした。
名前が若干流行らなさそうなのは気になっています!
あとIntelliJ用の拡張がほしい!

Reference

Discussion