component-model icon indicating copy to clipboard operation
component-model copied to clipboard

working with gc types

Open oovm opened this issue 1 year ago • 4 comments

Add Canonical ABI options to support passing parameters by reference type

  • Close #305

oovm avatar Mar 13 '24 06:03 oovm

I realized that the discriminant actually is required for variants that have multiple arms of the same type, like:

variant either-list {
    left(list<u8>),
    right(list<u8>),
}

In this case, both left and right would have the same (ref eq) subtype.

@fitzgen It occurred to me that the method compiled to (ref eq) still exists, that is, each variant is actually a new type.

If a language went the (enum, ref null eq) route, then the binding might look like (rust pseudocode):

enum Variants {
    Null,                 // (0, 0, 0)
    Bool { value: i32 },  // (1, i32, 0)
    U64 { value: i64 },   // (2, i64) , flatten i64 to i32 + i32
    I64 { value: i64 },   // (3, i64) , flatten i64 to i32 + i32
}

impl Variants {
    fn is_bool(&self) -> bool {
        match self {
            Variants::Bool { value } => true,
            _ => false,
        }
    }
}

If a language took the (ref eq) route, then the binding might look like (C# pseudocode):

// (struct $variants)
abstract class Variants
{
    // (struct $None)
    // (ref eq $variants)
    class Null : Variants
    {
        public override bool isBool()
        {
            return false;
        }
    }
    // (struct $Bool (field value i32))
    // (ref eq $variants)
    class Bool : Variants
    {
        int value;

        public override bool isBool()
        {
            return true;
        }
    }

    // (struct $U64 (field value u64))
    // (ref eq $variants)
    class U64 : Variants
    {
        long value;

        public override bool isBool()
        {
            return false;
        }
    }
    // (struct $U64 (field value i64))
    // (ref eq $variants)
    class I64 : Variants
    {
        int value;

        public override bool isBool()
        {
            return false;
        }
    }

    // virtual table pointer
    public abstract bool isBool();

    // static method
    public static bool isBool(Variants v)
    {
        switch (v)
        {
            case Null _:
                return false;
            case Bool _:
                return true;
            case U64 _:
                return false;
            case I64 _:
                return false;
            default:
                throw new Exception("unreachable");
        }
    }
}

These languages are more likely to implement variant determination through virtual tables

  • X is Variants
  • X is Variants::None
  • X is Variants::Bool
  • X is Variants::U64
  • X is Variants::I64

I think it would also help to achieve: https://github.com/WebAssembly/component-model/issues/136

oovm avatar Mar 16 '24 06:03 oovm

reference-type now focuses on the mapping of three heap types: string, array, and struct.

The reference types corresponding to option, result, variants have been moved to https://github.com/WebAssembly/component-model/issues/325

oovm avatar Mar 20 '24 07:03 oovm

Super excited about the possibilities here. What's the status?

kevmoo avatar Jun 25 '24 03:06 kevmoo

  • The mapping of struct <-> record, struct <-> tuple, list <-> array has been agreed upon.
  • For enum and flags, no mapping is required.
  • For variant and string, there are objections and they have been removed from the proposal.

The unprepared part is mainly the implementation of the python validator (definitions.py), which has recently changed.

I have not been able to spend too much time on implementing this part recently due to my employer, so I am very sorry.

oovm avatar Jun 25 '24 06:06 oovm

Closed because the underlying runtime model has changed since 0.2 and needs to be reconsidered based on the 0.3 runtime model and semantics.

oovm avatar Mar 16 '25 04:03 oovm