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

I64ToI32Lowering: return_call_indirect gets a (func (result unreachable)) type, binary writer hits UNREACHABLE

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

メンテナーはふだん 1 日以内に返信

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

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
65/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
cpp, wasm
領域
compilers

調査の方向性

Start with the reproducer, wasm-opt -all input.wat --i64-to-i32-lowering, then read visitGenericCall and visitCallIndirect in src/passes/I64ToI32Lowering.cpp, where the new heap type for a return call gets its results. The issue suggests the fix is to take the results from the lowered curr->heapType.getSignature() instead of the unreachable result. Done means the call keeps (type $t), and both binary and text output round-trip through wasm-opt.

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

説明

--i64-to-i32-lowering rewrites the type of a return_call_indirect to (func (result unreachable)), even in a module with no i64 at all, so writing a binary aborts and writing text produces a module that does not parse.

(module (type $t (func)) (table 1 funcref) (func $a (return_call_indirect (type $t) (i32.const 0))))
wasm-opt -all input.wat --i64-to-i32-lowering -o /dev/null
unexpected type
UNREACHABLE executed at src/wasm/wasm-binary.cpp:2104!
    #1 wasm::handle_unreachable(char const*, char const*, unsigned int) src/support/utilities.cpp:39
    #2 wasm::WasmBinaryWriter::writeType(wasm::Type) src/wasm/wasm-binary.cpp:2104
    #3 wasm::WasmBinaryWriter::writeTypes() src/wasm/wasm-binary.cpp:307
    #4 wasm::WasmBinaryWriter::write() src/wasm/wasm-binary.cpp:63
    #5 wasm::ModuleWriter::writeBinary(wasm::Module&, wasm::BufferWithRandomAccess&) src/wasm/wasm-io.cpp:164

With -S -o out.wat instead, wasm-opt exits 0 and writes this, which the same wasm-opt then rejects with out.wat:3:24: error: expected valtype:

(module
 (type $t (func))
 (type $1 (func (result unreachable)))
 (global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0))
 (table $0 1 funcref)
 (func $a (type $t)
  (return_call_indirect $0 (type $1)
   (i32.const 0)
  )
 )
)

I expected the call to keep (type $t): the input is valid (wasm-opt without the pass accepts it), there is nothing to lower, and the pass only rejects return calls with i64 results (with a clean Fatal), so other return calls look meant to be supported.

Found at commit 93d6e9de7e1d99be22a49b8952426906a65df397 and still reproduces at 207bbaec4b30. A release build aborts the same way (SIGABRT) on binary output; with text output it exits 0 and writes the invalid module above. The validator does not report anything before writing.

Looks like visitGenericCall in src/passes/I64ToI32Lowering.cpp passes curr->type as the results when the call does not return i64, and for a return call that is unreachable, so visitCallIndirect builds Signature(Type(params), unreachable) as the new heap type; using the lowered curr->heapType.getSignature().results would avoid it.

Found with an LLM-based testing tool; I used Claude to reduce it and look for the cause.

主要言語
WebAssembly
スター
8.7k
フォーク
895
平均マージ
1日 23時間
マージ済み PR(30日)
105

環境構築

はじめの一歩

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

WebAssembly/binaryen のほかの issue

WebAssembly/binaryen の issue をすべて見る

似ている issue

Compilers の issue をもっと見る

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

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