Skip to content

Fix async flattened in-variant f32/f64 representation lifts/lowers #1428

@vados-cosmonic

Description

@vados-cosmonic

There is a problem with current bindgen that is pretty subtle -- f32/f64 values in async flat lifts (e.g. task.return params) must be somewhat dynamically handled.

A normal function with the following signature:

foo: async func() -> f32;

Will return a core f32 type, but WIT like the following:

variant x {
    unsigned(u32)
    float(f32)
}

foo: async func() -> x;

Will undergo more complex "variant flattening" (See the Flattening section in CanonicalABI.md) that has more complex rules, in particular when all results are returned as parameters (see the join function):

def flatten_variant(cases, opts):
  flat = []
  for c in cases:
    if c.t is not None:
      for i,ft in enumerate(flatten_type(c.t, opts)):
        if i < len(flat):
          flat[i] = join(flat[i], ft)
        else:
          flat.append(ft)
  return flatten_type(discriminant_type(cases), opts) + flat

def join(a, b):
  if a == b: return a
  if (a == 'i32' and b == 'f32') or (a == 'f32' and b == 'i32'): return 'i32'
  return 'i64'

For example, in the above example, a x::float(...) may turn into [1, 480923, 0] where the second value is actually the f32 reinterpeted as a i32, due to flattening rules.

Another anomalous example is of a similar variant with u32 and a f64 -- this a type list like [i32, i64] and requires re-interpretation.

This behavior also affects lowering -- we need tests for both sides with these anomalous cases.

The additional code to navigate these cases should likely land in LiftIntrinsic::LiftFlatVariant/LowerIntrinsic::LowerFlatVariant, as these exceptions affect the lifting of f32/f64, but are a property of the container (in this case the variant).

NOTE: this problem also seems to be present when dealing with tuples.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions