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.
There is a problem with current bindgen that is pretty subtle -- f32/f64 values in async flat lifts (e.g.
task.returnparams) must be somewhat dynamically handled.A normal function with the following signature:
Will return a core f32 type, but WIT like the following:
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
joinfunction):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 ai32, due to flattening rules.Another anomalous example is of a similar variant with
u32and af64-- 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 thevariant).NOTE: this problem also seems to be present when dealing with
tuples.