Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[wasm-as/wasm-dis]: Don't say the input/output is WebAssembly Text because it's not

オープン
#4,550 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
30/100
issue の種類
バグ
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
wasm

調査の方向性

まず、wasm-as と wasm-dis のエントリーポイントを通じて報告されたケースを再現し、それらが受け付ける s-expression 形式と出力する s-expression 形式を、準拠した WebAssembly Text の動作と比較します。完了とするには、対象範囲を決定する必要があります。つまり、WAT 互換性を主張しないようにツールの名前を変更するか、source order、folded instructions、multiple returns、flat form の扱いを準拠したものにします。

索引モデルが issue の本文から書いたものです。

説明

The s-expression language used by wasm-as and wasm-dis is non-compliant. It's not even just a subset, it's simultaneously a subset and a superset. So using it with compliant WAT code with certain extensions is impossible. So either we should not call it .wat/WebAssembly text, or make it compliant.

Examples

I will present a few examples to motivate this.

Source order

All memory segments must be before data segments, in source location
$ cat memory-before-data.wat
(module
  (data (i32.const 0) "Hello, world!\n")
  (memory 1))
$ wasm-as memory-before-data.wat
[parse exception: data but no memory (at 2:2)]Fatal: error in parsing input
$ wat2wasm memory-before-data.wat
$ cat memory-before-data.fixed.wat
(module
  (memory 1)
  (data (i32.const 0) "Hello, world!\n"))
$ wasm-as memory-before-data.fixed.wat
$ wat2wasm memory-before-data.fixed.wat
All globals must be defined before they are used, with respect to source location
$ cat global-before-use.wat
(module
  (func $foo (result i32) (global.get $global))
  (global $global i32 (i32.const 0)))
$ wasm-as global-before-use.wat
[parse exception: bad global.get name (at 2:26)]Fatal: error in parsing input
$ wat2wasm global-before-use.wat
$ cat global-before-use.fixed.wat
(module
  (global $global i32 (i32.const 0))
  (func $foo (result i32) (global.get $global)))
$ wasm-as global-before-use.fixed.wat
$ wat2wasm global-before-use.fixed.wat
Explanation

As defined in 6.6.13 of the WASM spec, "a module consists of a sequence of fields that can occur in any order" (180), excluding regarding composition of modules, where "all imports must occur before any regular definition of a function, table, memory or global, thereby maintaining the ordering of the respective index spaces" (181).

This is not an example of a syntactical limitation allowed as defined in section 7.2.1.

Folded instructions without correct number of arguments, but where those arguments are present on the stack

For example, consider the following function:

f(x) :=
    x = x + 1
    x + 5

While this is a bit contrived, I have come across this example in regular use. One may translate this imperative pseudocode into the following WAT:

$ cat folded-instrs.wat
(module
  (func $foo (param $x i32) (result i32)
    (local.tee $x (i32.add (local.get $x) (i32.const 1)))
    (i32.add (i32.const 5))))
$ wasm-as folded-instrs.wat
[parse exception: expected more elements in list (at 4:4)]Fatal: error in parsing input
$ wat2wasm folded-instrs.wat

There is no way to fix this within the input format of wasm-as, meaning using local.tee in any position but within another folded expression is not allowed.
This also means that using multiple returns in a compliant way is impossible (contrived, but minimal example):

$ cat multiple-returns-folded.wat
(module
  (func $foo (result i32 i32)
    (i32.const 10)
    (i32.const 15))
  (func $bar (result i32)
    (i32.add (call $foo))))
$ wasm-as multiple-returns-folded.wat                                                               
[parse exception: expected more elements in list (at 6:4)]Fatal: error in parsing input
$ wat2wasm multiple-returns-folded.wat

Note the following: as defined in section 6.5.10, "folded instructions are solely syntactic sugar, no additional syntactic or type-based checking is implied". Also, instructions in the folded form are defined as such: '(' plaininstr foldedinstr* ')'. The usage of * in foldedinstr implies that the number of elements does not have to "align" with the instruction used, as no additional syntactic checking is to be done (174).

This is not an example of a syntactical limitation allowed as defined in section 7.2.1.

This means that the only way to do multiple returns is to use the tuple syntax, which is not a part of WebAssembly Text, which I would generally consider okay, as it would be a superset. However, as this is the only way (that I can find) to use multiple returns in this s-expression language (and is the way shown by wasm-dis), I consider this to be another example of noncompliance.

Flat form is not supported.

This one is somewhat self-explanatory. Only the s-expression format of WAT is supported by wasm-as/wasm-dis, not the "flat"/non-folded format that is also supported by tools such as wabt.

This is not as much of a problem as the previous examples, but again, it is not example of a syntactical limitation allowed as defined in section 7.2.1.

Notes

All section and page references are relative to the section and page numbers shown on the current (Release 1.1, Draft 2022-03-21) WebAssembly Specification PDF.

Conclusion

Yes, this is pedantic. But I find that this seems like a terrible decision to make, as binaryen and its tooling is used by several important tools, such as emscripten. While I don't know if wasm-as/wasm-dis are specifically used anywhere, it still seems counterintuitive to have a tool that seems "officially" developed by the WebAssembly group (as a repository in its GitHub organization) to not actually support compliant examples of WAT.

主要言語
WebAssembly
スター
8.6k
フォーク
885
平均マージ
2日 4時間
マージ済み PR(30日)
77

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

WebAssembly/binaryen のほかの issue

WebAssembly/binaryen の issue をすべて見る

似ている issue

Compilers の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。