There seems to be a need for an extensible datatype:
data Thing = Link {next :: Pointer}
| Ageable {Link | age :: Int}
| ObjectHeader {Ageable | id :: Int}
etc...
You could then pattern match to get a specific type:
case thing of
Link x ->
Ageable x ->
ObjectHeader x ->
but given any "thing" you could always do:
thing.next := deref(thing.next)
etc...
Keean.
Keean.
On 26 February 2015 at 14:37, Jonathan S. Shapiro <[email protected]> wrote:
> So it might be helpful to this discussion to talk about a use case.
> Ironically, the cases that are presently very important to me do not
> involve existential encapsulation at all, and do not need to involve a
> vTable, because no method override occurs.
>
> ILLUSTRATION 1
>
> In Coyotos, there are several kinds of objects at the API level. All are
> named by capabilities and have OIDs. It is intentionally unspecified
> whether the OID space is partitioned by type. In some versions of the
> kernel objects have been tracked in a unified hash table.
>
> In C, the idiom for this is to have an ObjectHeader struct as the first
> element of (e.g.) the Process struct, and do ad-hoc downcasting. That idiom
> cannot be done in a safe language.
>
> In C++, the idiom would be to have Process derive from ObjectHeader, and
> perhaps use RTTI to do a checked downcast. That idiom *can* be done in a
> safe language.
>
> In BitC v0, neither idiom is possible, because one structure definition
> cannot extend another.
>
> It turns out that this "checked downcast" approach is being used
> pervasively in Coyotos, because the object identity between the
> ObjectHeader and its associated (e.g.) Process is actually important. It
> simply would not work to separate the two parts into structures that are
> mutually cross-pointed. If nothing else, the additional storage used for
> those pointers would exhaust the available kernel *virtual* memory range.
> Yes, kernels really *are* that tight, and no, 64-bit address spaces *don't*
> help.
>
> The ObjectHeader contains a type code for the object, and there are a very
> few procedures associated with these objects that dispatch on the type
> code, but no virtual overrides occur in this scenario.
>
> I really do not see a solution to this **other than** allowing one struct
> to extend another and introducing the capacity for dynamic downcast. The
> problem here combines "is a kind of" with "is identically a", and it is
> driven by data layout concerns rather than any need for existential
> encapsulation.
>
> ILLUSTRATION 2
>
> This is an essentially similar problem, though with heavier use of
> dispatch on that type code.
>
> There are a few objects in Coyotos that can cause hardware mapping entries
> to be produced. How dependencies and information necessary for invalidation
> are tracked depends on the object type. We end up with a structural
> hierarchy that looks like:
>
> Link -- double link pointers
> Ageable -- adds pointer to per-type agelist head
> ObjectHeader -- object type code, locks, various common metadata
> MemHeader -- used to track HW maps derived from this object
> GPT -- state of Guarded Page Table
> Page -- phys addr and size
>
> Here again both layout and final size of the object are tightly
> constrained. It truly is an "extends" relationship, but the need for
> dynamic downcast makes it a bit interesting.
>
> It's the dynamic downcast that has me thinking in terms of inheritance
> here. Structure extension per se isn't difficult, though even that
> introduces a nominal subtyping relation.
>
> shap
>
> _______________________________________________
> bitc-dev mailing list
> [email protected]
> http://www.coyotos.org/mailman/listinfo/bitc-dev
>
>
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev