WebAssembly / WebAssembly/component-model

Canonical abi: `union-type`

Open
#325 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
WebAssembly
Stars
1.4k
Forks
130
Avg merge
2d 1h
Merged PRs (30d)
15

Description

Motivation

Runtime Reinterpretation

Many languages have the ability to reinterpret a piece of data at runtime, and this ability can be constrained by the type system.

For example, in C language:

#include <stdio.h>

union MyUnion {
    int i;
    float f;
};

int main() {
    union MyUnion u;

    u.i = 42;
    printf("Value of i: %d\n", u.i);

    u.f = 3.14;
    printf("Value of f: %f\n", u.f);

    return 0;
}

Or in typescript:

interface MyUnion { i: number } | { f: number }

let u: MyUnion;
u = { i: 42 };
console.log("Value of i:", u.i);

u = { f: 3.14 };
console.log("Value of f:", u.f);
Interface merging (interface subtype)

In some type systems, identical types or subtypes can be merged:

type Option<T> = T | null;

Option<Option<T>>  ==>  Option<T>

This is completely different from variants (sum types) in algebraic data types.

ABI change

Add a new union option, which does not take effect by default

This option will require variants to pass data directly without adding additional enumeration parameters.

Changes to reference-type

When reference-type and union-type are enabled at the same time, the following changes will occur

wit type wasm w/o rt + ut wasm w/ rt + ut
option<bool> (i32, i32) (ref null i31)
option<option<bool>> (i32, i32) (ref null i31)
option<char> (i32, i32) (ref null i32)
option<i8> (i32, i32) (ref null i31)
option<i32> (i32, i32) (ref null i32)
option<i64> (i32, i64) (ref null i64)
option<T> (heap type) (i32, SIZE_OF_T) (ref null $t)
option<option<T>> (heap type) (i32, SIZE_OF_T) (ref null $t)
result<A, B> (i32, MAX_SIZE_A_B) anyref
variants (i32, MAX_SIZE) anyref

Each variant item will have an independent type id, which is used for type conversion and distinguishing variant items with the same name.

variant a { // struct a
   aa(i32)  // struct a-aa (field i32)
   ab(i32)  // struct a-ab (field i32)
}
variant b { // struct b
   aa(i32)  // struct b-aa (field i32)
   ab(i32)  // struct b-ab (field i32)
}

This helps to implement features such as abstract classes, interface inheritance, ?. (non-null call), ?? (null merge), etc.

Contributor guide

No contributing guide indexed for this repository

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

The issue names no files, tests, or entry points. Start by reading the proposed ABI changes and reference-type interaction table; done would require an agreed specification for the opt-in union-type behavior and its variant type-conversion rules.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
Issue type
Feature
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.