Skip to content

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

@kripken

Description

@kripken

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions