RemoveUnusedModuleElements drops an active elem segment whose items are global.get, so call_indirect traps

Aberta
#9,366 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
3/5
Tempo estimado
1-2 dias
Facilidade para iniciantes
68/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
cpp, wasm
Domínio
compilers

Direção de pesquisa

Start in src/passes/RemoveUnusedModuleElements.cpp, especially Analyzer::prepare() and notePossibleFunc; the issue identifies the RefFunc-only check and the missing global.get handling. Read the existing pass tests for element segments and add a regression case based on the supplied WAT module. Done means the segment and referenced global are retained as needed, and optimized execution still returns 42 instead of trapping.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

An active element segment whose item is global.get (the "Initializing a table with imported funcref global" case in the spec's elem.wast) is removed by --remove-unused-module-elements and at -O1 and above. The table slot stays null and call_indirect traps.

;; b2.wat
(module
  (type $f (func (result i32)))
  (import "env" "g" (global $g funcref))
  (table 1 funcref)
  (elem (i32.const 0) funcref (global.get $g))
  (func (export "call") (result i32)
    (call_indirect (type $f) (i32.const 0))))

wasm-opt b2.wat --enable-reference-types --remove-unused-module-elements -S -o - prints:

(module
 (type $f (func (result i32)))
 (table $0 1 funcref)
 (export "call" (func $0))
 (func $0 (result i32)
  (call_indirect $0 (type $f)
   (i32.const 0)
  )
 )
)

The segment and the import are gone. Instantiated in Node.js 26.13.0 with env.g set to a function returning 42:

unoptimized:                       call() = 42
--remove-unused-module-elements:   RuntimeError: function signature mismatch
-O1:                               RuntimeError: unreachable

The same happens when $g is a defined global initialized with ref.func (with --enable-gc).

Tested with wasm-opt version_133; on main (95a214dc48) the pass differs from version_133 only by the NFC renames in #9286/#9288.

In src/passes/RemoveUnusedModuleElements.cpp, notePossibleFunc in Analyzer::prepare() only looks at item->dynCast<RefFunc>(), so a segment with global.get items never gets into FlatTableInfo::typeElems and is considered unused.

Found with a differential-testing tool; the report was drafted with AI assistance and reviewed and edited by me.

Credit: https://ucsbplse.github.io/

Linguagem predominante
WebAssembly
Estrelas
8.7k
Forks
905
Merge médio
1d 23h
PRs com merge (30d)
86

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de WebAssembly/binaryen

Todas as issues de WebAssembly/binaryen

Issues semelhantes

Mais issues de Compilers

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.