On 8/3/20 10:21 PM, Dan Smith wrote:
On Aug 2, 2020, at 10:08 AM, Peter Levart <peter.lev...@gmail.com> wrote:
In either case I think it is a matter of the inline class bytecode and not the
code doing invocation (the call site). So it is safe by itself. Or am I missing
something?
You're describing Option F. Yes, we can have javac generate checks in the
bytecode of inline class method bodies.
Some awkwardness remains whenever default methods or Object methods are
invoked. It would be difficult and expensive to implement any checks in these
method bodies; and while bridge methods generated in the inline class's class
file help, they don't guard against new methods declared after compilation (the
motivating use case for the default methods feature). So we're left with one of:
- Permit superclass/superinterface code to run, only throwing (or at least only
guaranteeing a throw) when one of the declared instance methods of the class
are invoked; or
That would not be so bad, I think. Why? The Object methods that require
access to instance state (equals, hashCode) would be implemented by
inline class and would contain the checks. Other Object methods are
mostly not allowed for inline classes anyway. So this leaves us with
default methods of interfaces implemented by inline class. These are of
two kinds: either they are just functions that don't deal with the
instance state at all and would be better off as static methods anyway,
or they deal with instance state in which case they must invoke at least
one of inline class declared methods and the checks will be triggered.
So I would say that anything important that accesses instance state is
guarded by instrumentation of inline class methods.
But what about accessing fields directly? Even if fields are
encapsulated (private), they can be accessed by code of the inline class
itself or a nestmate when an instance of the inline class is not "this".
In that case, I think the same strategy as for null checking of identity
types is in order: an equivalent of Objects.requireNonNull for inline
types. Forgetting to issue those checks manually can have a surprising
effect though.
- Option G: implement the checks in the JVM, where we can see the entire set of
inherited member methods as the inline class is loaded/linked
Yeah, this could also work for field accesses then.
A hybrid of call-site (or field-access-site) checks and checks embedded
in the instance methods is also possible. Javac could emit a check
before accessing a field from code where embedded check is not performed
(where instance is not "this") and before invoking default interface
method (as determined by static type). This would then cover all places
and still be secure since for security, the checks embedded in the
instance methods can not be bypassed.
Peter