WebAssemblyのtrunc_sat命令

ようやくWebAssemblyのバイナリパーサを書き終えそうなので、次はそこへのコンパイラを書きたいな、と妄想しています。妄想するのは自由なので。ちなみにバイナリパーサに関してはまだ完全に終わったわけではありませんが、最も地道な作業と思われる、各Instructionへの対応はだいたい終わっています。だいたい、というのは一部Ver1.1で新しく追加されたと思われる(ちゃんと確認はしてません)命令を置いているからです。いや、別に難しいわけではないんですが、気力の問題です。具体的には以下の8つ。

The saturating truncation instructions all have a one byte prefix, whereas the actual opcode is encoded by a variable-length unsigned integer.

まず0xFCというprefixがあって、その次のバイトで変換元、変換先の型が決定されるみたいですね(ちなみにLEB128なので、u32でも7bitに収まる範囲では1byteしか使いませんよ)

0xFC 0:u32 => i32.trunc_sat_f32_s
0xFC 1:u32 => i32.trunc_sat_f32_u
0xFC 2:u32 => i32.trunc_sat_f64_s
0xFC 3:u32 => i32.trunc_sat_f64_u
0xFC 4:u32 => i64.trunc_sat_f32_s
0xFC 5:u32 => i64.trunc_sat_f32_u
0xFC 6:u32 => i64.trunc_sat_f64_s
0xFC 7:u32 => i64.trunc_sat_f64_u

上記、不動小数点数を整数に変換する命令群ですが、すでに存在するtruncとはちがって、例えばNaNに対しては0を返します。

f:id:ironoir:20210212124558p:plain

そしてこれが従来のtrunc命令。partial、つまり部分関数だと書かれていて、NaNに対してこっちはundefinedです。undefinedなときってどうする決まりだったっけ。とは言えtrapぐらいしかできそうなことはないんだけど。どこかに明記されてないかな。 f:id:ironoir:20210212124519p:plain

There is no undefined behavior, i.e., the execution rules cover all possible cases that can occur in a valid program, and the rules are mutually consistent.

探してみたところ、soundnessに関する記述がありましたが、これを見るとそもそもundefinedなコードがvalidではなくWebAssemblyのモジュールとして認められないみたいです。ということは例えば、その前にチェックして弾け、ということなんでしょうか。あと、trunc_satが有効に働くユースケースも知りたいところ。ぼちぼち、調べます。