Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@blackenedgold

WebAssemblyのloopはまりどころ

はじめてWebAssemblyを書く時は恐らくloopではまります。

以下の関数を見て下さい。1からnまでの和を計算する関数のつもりです。

  ;; i32型引数$nを取りi32の返り値を返す関数。さらにローカル変数として$iと$sumを使う。
  ;; ローカル変数は0初期化されるのでそのまま使う
  (func $sum_bad (param $n i32) (result i32)  (local $i i32) (local $sum i32)
    (loop $loop
      ;; もし$iが$nを以上ならloopから抜ける
      (br_if $loop (i32.le_s (get_local $n) (get_local $i)))
      ;; $sum = $sum + $i
      (set_local $sum (i32.add (get_local $sum) (get_local $i)))
      ;; $i = $i + 1
      (set_local $i (i32.add (get_local $i) (i32.const 1))))
    ;; ループから抜けたらreturn
    (return (get_local $sum)))

これを動かすと

sum_bad: 0

と返ってきます。何故でしょう。

なんとloopはただの後方ジャンプのためのラベルで、末尾まで到達してもloopの位置まで戻りません。戻りたければ br を呼ぶとloopの位置に飛ぶことになっています。
loopに対するbrが一般の言語でいう continue 相当になっている訳ですね。なので上記実装だとloop内は一度しか実行されずに抜けてしまいます。

それを踏まえた実装がこちら。

  (func $sum_good (param $n i32) (result i32)  (local $i i32) (local $sum i32)
    ;; loopから脱出するためのラベルを作っておく
    (block $exit 
      (loop $loop
        ;; ループから脱出するときは$exitの方を指定する
        (br_if $exit (i32.le_s (get_local $n) (get_local $i)))
        (set_local $sum (i32.add (get_local $sum) (get_local $i)))
        (set_local $i (i32.add (get_local $i) (i32.const 1)))
        ;; **ちゃんと** ループするためにbrを呼ぶ
        (br $loop)))
    (return (get_local $sum)))

今回のコードはこちらで試せます。皆様ご安全に。

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What is going on with this article?