[bitc-dev] What "non-escaping" means
Jonathan S. Shapiro
shap at eros-os.org
Tue Aug 10 22:08:43 PDT 2010
I'm cleaning up loose ends, and I want to respond to a question Wren posed.
He asked what "non-escaping" meant in the context of by-reference
BitC has two constructs that produce inner references: INNER-REF and BY-REF.
The INNER-REF construct requires a heap-allocated type as its argument.
While it produces an inner structure pointer, and thereby creates some
challenges for GC, it creates no interesting new safety issues. By design,
the size of an inner-ref type is unspecified to allow for a "pointer pair"
BY-REF can be used to construct a reference to an item on the stack. In
consequence, we must ensure that BY-REF values do not outlive the stack
frame that they reference. This is the ultimate source of the no-escape
Today, BY-REF is only allowed at parameters. Because the tuple containing
the parameters is anonymous, and because BY-REF types are implicitly
dereferenced at all use-occurrences, BY-REF cannot be a result type of an
expression and therefore cannot escape.
The current BY-REF definition can be straightforwardly extended to let
bindings: a BY-REF let binding can be bound from any enclosing lexical
context, and cannot escape for the same reason that by-ref parameters cannot
Both of these cases "work" because the BY-REF type is an outermost binding
on the stack. If BY-REF is permitted to appear as a field type, things
become more complicated. In summary, if an aggregate *contains* a by-ref
value, then the *aggregate* cannot be copied outwards, because if it could,
the reference might survive the thing to which it refers, creating a safety
The current language takes a draconian approach to escape prevention: a
by-ref cannot be copied. The extension to new let bindings allows it to be
copied, but only to *inner* lexical contexts. This is sufficient to ensure
non-escape if BY-REF is not allowed as a field type.
The other, richer, approach is to introduce region types, where a by-ref
field takes on the region identifier of its target, and ceases to be
dereferenceable once that region goes out of scope. This allows by-ref types
to be returned, which in turn allows what I have called "generalized
accessors". We need to move here eventually, but I want to put this off
until BitC v2.
So in a practical sense, what I was trying to capture with the notion of
"non-escaping" was that by-ref references should not survive the thing that
they reference. This is a temporary expedience until region types are more
The immediate relevance is tuple types. If we allow by-ref fields of tuple
types, then we must implement the "noescape" restriction more generally,
which is why I don't want to bite off tuple types until we deal with the
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the bitc-dev