• You’re sort of on the right track with your “cryptographic checking” comment, except it’s not cryptographic, and it is deterministic.

    The key is that the sidecar and capability are substantially redundant. In the in_array case (the most interesting one), they share 80 bits - the kind, the ptr itself, and the type. The capability has the upper and the sidecar has the lower.

    In an isoheaped environment (or in a GC’d environment - Fil-C could be GC’d if I wanted), you simply cannot have two in-bounds pointers to the same memory location unless you agree on what the memory is in the capability associated with that pointer.

    So, after loading both the sidecar and capability in the in_array case, we just check that:

    • sidecar.kind == in_array && capability.kind == in_array
    • sidecar.ptr == capability.ptr
    • sidecar.type == capability.type

    If that all matches, you can use the lower bound from the sidecar. Otherwise you infer it from ptr/upper/type in the capability.

    The story is a bit different for the other three kinds (at_lower just ignores the sidecar while flex_base and oob have different rules, but based on the same principle).

    One way to convince yourself that it’s right is try to find a way to create two pointers that share ptr and type and both are known in bounds such that if you take the lower from one of them and the upper from the other, you get a bug. I cannot think of a way to do it.


    score 2 · canonical