Add a Union Type and simple TaggedRef type
I suggest adding a union<T1, ..., Tn>
type, it would be like a C union { T1 t1; ... }
, you would use it like any other type (you can have SSA variables of it, you can new it and alloca it) but also extend the instruction set:
-
GETFIELDIREF [PTR] <T index> opnd
will get an iref/uptr to the index'th variant of the union opnd (of type T), this would also communicate to the GC thatopnd
should be treated as having a value of type Ti (where Ti is the index'th type in the union T). -
EXTRACTVALUE
andINSERTVALUE
should be extend to work on unions, in the same way as above
The main purpose of having union types is to allocate a structure of known size on the heap, but whose actual type may change throughout it's lifetime. This would allow for example a type like 'union<int<64>, ref` that may be an integer or a reference, and to inform the GC of this whenever you use it (but when the actual type is not known at allocation or compile time).
I also suggest adding a simple tagged reference type (I think? x86-64 allows up to 17 of the highest bit as a tags and aarch64 allows up to 8), that would store a reference and a tag, like tagref64 but more efficient as it would not store floating points or integers (so you can do a simple 'and' instruction to get the tag and/or pointer).
These changes would be particularly useful to @pzakopaylo01 who is trying to implement a Haskell closure, but the layout is not known at the time of creating it (but because Mu is Garbage collected he can't simply cast random bits to/from references and other types). His current solution is utilising tagref64 but that has a few problems:
- It is inefficient, for example it takes 10 instructions on aarch64 to make a tagged pointer tagref, it would take 1 with a simple tagged reference type
- The range of values you can store in it is limited (specifically it is limited to storing a 52-bit integer which limits the precision of Haskell datatypes)
- It is cumbersome to use, and not general enough to support they way it is used
He may be able to better describe his problems than me, but either way I think these two changes would be simple and straightforward to implement in Zebu (though the garbage collector will need a bit of work), and would help extend Mu to be more easily target-able by a wider range of languages (such as ones with dynamic types).