Classifying capabilities #23463
Replies: 4 comments
-
What this mans for the implementation
|
Beta Was this translation helpful? Give feedback.
-
This looks like a lot of machinery to typecheck |
Beta Was this translation helpful? Give feedback.
-
One possible generalization would be to have besides |
Beta Was this translation helpful? Give feedback.
-
One possible simplification is to specialize the treatment to control capabilites:
This would make sense if we can convince ourselves that the only capability masking operations we envision mask specifically control capabilities. Can we? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
The motivation for this is to come up with a type for
Try.apply
orFuture.apply
that reflects the capability structure.Try.apply
would have a type like this one:The
???
should capture all control capabilities ofbody
(such asLabel
s orCanThrow
s). After theapply
exits, the capabilities owned by body are spent, except for those control capabilities. These are retained in the failure part of aTry
since they will be re-thrown when theTry
is accessed by aget
or a pattern match.The problem is we are lacking a way to express those control capability slices, nor do we have a way to reason about them (i.e. know which ones subsume which other ones, or which ones can be discarded).
The idea is to add a new kind of capability acting as a filter. If
c
is a capability, thenc.as[C]
would stand for all capabilities implied byc
that have a type deriving from classC
. Specialized to control, we could introduce a new traitthat is a base class of control capability classes such as
Label
,CanThrow
, orAsync
. (The@classifier
annotation can be ignored for now, it will be further explained below). With that structure in place, we could give the following signature to
Try.apply
:c.as[C]
is called a filtered capability. Generally,c.as[C]
is a new capability qualifier, alongsidec.rd
andc*
. If multiple qualifiers are given then.as
comes after*
but before.rd
, i.e.c*.as[C].rd
would be in the correct order. There can only be a singleas
-qualifier on a capability.We now need to develop subsumption rules for filtered-capabilities. We clearly should have
What about the other combinations? When is
c <: c.as[C]
? We do want this to hold sometimes. For instance ifasync: Async
whereAsync
derives fromControl
then it would be nice to be able to conclude thatasync <: async.as[Control]
.Another issue is how to detect disjointness. For instance, a particular operation
op
might capture a Labellbl
and a mutable matrixm
.What is the type of
Try.apply(op())
? Consulting the signature ofTry.apply
we getReplacing
op
with the actual argument, we get{lbl.as[Control], m.as[Control]}
as the capture set of the result.lbl.as[Control]
should simplify tolbl
by the reasoning we outlined before.m.as[Control]
should ideally simplify to nothing, since a mutable matrix would not expected to capture a control capability. So, ideallyTo get there, we introduce classifier capability classes. These are subclasses of capability with the added annotation
@classifier
. In particular we would have:A class can not directly or indirectly extend two unrelated classifier capability classes.
Now, looking at subsumption rules, we first need this one:
if
D
is a classifier capability class andc
is classified asD
.Definition
A capability
c
is classified as a classifier capability classD
if thetransitive capture set of
c
only contains capabilities that derive fromD
.Definition The transitive capture set
tcs(c)
of an object capabilityc
consists ofc
itself plus the transitive capture sets of all capabilities captured by the type ofc
. The transitive capture set of a root capabilityc
is just{c}
. The transitivecapture set of
c.rd
is{x.rd | x in tcs(c)}
Definition A capability
c
derives from a classifier classD
if one of the following applies:c
is an object capability of typeT
andT <: D
(alternatively,T
hasD
in its parent classes),c
is a root capabilitycap
which originated from a typeC^{cap, ...}
whereC <: D
.c
is a read capabilityc1.rd
andc1
derives fromD
.c
is a capture set variableX
and all elements in the alias or upper bound ofX
derive fromD
.To make this sound, we have to restrict possible values of
FreshCap
capabilities. If aFreshCap
starts life in the capture set of a classC
that extends a classifier classD
then theFreshCap
instance can subsume only capabilities classified asD
. So FreshCap instances now carry restrictions for disjointness (in separation checking), levels, as well as classifiers.Example
because the
tcs(lbl) = {lbl, cap}
where thecap
is a root capability associated withLabel
which is a subclass of the classifier classControl
.Furthermore, we have
if
D
is a classifier capability class andtcs(c)
only contains capabilities that derive from classifier classes unrelated toC
.So
because
m
is classified asMutable
, which is unrelated toControl
.Beta Was this translation helpful? Give feedback.
All reactions