WebAssembly / WebAssembly/binaryen

Bad interaction with tuples and local.tee using the value type

Open
#3,704 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
WebAssembly
Stars
8.6k
Forks
885
Avg merge
1d 19h
Merged PRs (30d)
69

Description

Investigating the feasibility of using the type of local.tee's value, instead of the local type, for the local.tee (which most of us prefer I think, but we were worried it might not be easy), I ran into this issue:

(module
 (type $N=>N (func))
 (func $0 (result f32 (ref null $N=>N))
  (local $temp (f32 funcref)) ;; tee through a supertype (funcref instead of the specific type)
  (local.tee $temp
   (tuple.make
    (f32.const 0)
    (ref.null $N=>N)
   )
  )
 )
)

Roundtripping that fails. What happens is that the tuple $temp has a funcref, a supertype of the specific one. If the tee has the type of the value, and not of the local, then this module validates. But when we roundtrip our binary writer first emits a local for each part of a tuple local, so we end up using funcref and not the specialized type, but then we fail when we try to create a tuple for the function return:

(module
 (type $none_=>_none (func))
 (type $none_=>_f32_ref?|none_->_none| (func (result f32 (ref null $none_=>_none))))
 (func $0 (result f32 (ref null $none_=>_none))
  (local $0 f32)
  (local $1 funcref)
  (local $2 f32)
  (tuple.make
   (local.tee $0
    (block (result f32)
     (local.set $2
      (f32.const 0)
     )
     (local.set $1
      (ref.null $none_=>_none)
     )
     (local.get $2)
    )
   )
   (local.get $1) ;; this has type funcref, but we need the specialized function type
  )
 )
)

It seems like a simple mapping of tuple locals to locals won't work, and the mapping needs to take into account the actual types assigned to the locals? Sounds more complex.

cc @tlively

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the issue's WAT roundtrip example and trace the tuple-local lowering and type mapping described there. Done means the original module roundtrips and validates without replacing the specialized reference type with funcref.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.