On Aug 12, 2016, at 2:57 PM, Michael Haupt <michael.ha...@oracle.com> wrote:
> Hi Peter,
> thanks for your feedback! I'm responding to both your messages in one.
>> Am 09.08.2016 um 05:05 schrieb Peter Levart <peter.lev...@gmail.com
>> In the JEP's description you write:
>> "The loadCode method creates a method from the passed bytecode instructions
>> and constants and returns a MethodHandle that can be used to call the
>> method. The implementation of loadCode will take care of verification of the
>> code to load."
>> That's clear.
>> "This method is isolated from any class and behaves largely like a static
>> method. The method handle resulting from a loadCode invocation is of the
>> REF_static kind. It cannot be cracked via
>> So there will be no class hosting this method? Not even the "caller" class
>> of the Lookup instance that loadCode was invoked upon? What will be reported
>> by Reflection.getCallerClass() invoked in a @CallerSensitive method invoked
>> from the isolated method?
That last question is easy: When you create a MH on a @CS method, via the
Lookup API, the caller is permanently bound to the caller class in the Lookup
object. (If you are wondering about security, note that you can't get a MH on
a @CS method without a full-power Lookup object.) After that, it is irrelevant
where and how the MH is eventually invoked, including from an isolated method.
>> Perhaps the following is a hint...
>> "The context for a method defined in this way is determined by the Lookup
>> instance receiving the loadCode call. In case the lookup privileges are not
>> sufficient, an exception will be thrown."
>> The "context" meaning the caller context, including the caller class that
>> appears in the stack trace of a call originating from an isolated method and
>> is important for security decisions?
> In all of this, I think it is important to not let the idea creep in that IMs
> are members of some class. This is not to be the case.
> With that out of the way ;-) let me stress that this is a very good question,
> and there have in fact been discussions about this. The notion of "host" has
> been floating around, and it currently seems that the lookupClass - to which
> you refer as the "caller" - is a meaningful candidate for this.
> Does this answer your question?
In general, we won't duplicate all the class-file infrastructure around the
IM's. So the surrounding class, local-variable tables, etc., etc., won't be
allowed to "creep into" the IM design. This makes some bits tricky, like "what
does it look like on the back trace", and "where are the exception handler
BCI's stored". The general answer will be some combination of "there are
simplified rules for IMs", and "some reflective tasks can be delegated to a
helper object or a BSM-like helper method", and finally "use a full class file
if you want more control".
>> On 08/09/2016 02:05 PM, Peter Levart wrote:
>>> In which case would lookup privileges be insufficient to define an isolated
>>> method? I would expect the privileges of the code in the isolated method to
>>> be checked when such method is executed and not when defining such method -
>>> lazily, like for normal methods.
>> A can see now that defining an isolated method in the context of a lookup
>> class can only be allowed when the Lookup instance contains ALL_MODES in the
>> mode bits as such method would have access to any members that a normal
>> method defined in the lookup class has.
> Not sure. I think this suggestion implies something like class membership,
> when in fact the IM should have the access rights defined by the Lookup,
> without belonging to the lookupClass. I may be misunderstanding your point.
Since access rights are permanently bound into the MH's stored in the isolated
constant pool, there should be little or no reason to ask about access rights
for the IM itself. Access rights are checked during symbolic resolution of
class, method, and field references. (Class object access rights are a tricky
case, since classes are easy to grab.) Inside the IM constant pool, all
references are "live", and previously resolved. There's no reason for the IM
to re-resolve them.
>> In which case it is important which "caller" class the privileges are check
>> against. This would most naturally be the "caller" class of the Lookup
>> instance used to define the method. In all respects the code of such
>> isolated method would appear to be defined in the lookup class except it
>> would not be denotable symbolically - only through a MethodHandle. Analogous
>> to VM-anonymous classes. So why not call such methods "anonymous methods"
>> instead of isolated methods?
> Most aspects of this JEP draft, including the name, are open for discussion.
> I would not want to call an IM "anonymous" because it should be given a name.
> If it is supposed to appear in a stack trace, that would be most helpful. The
> class to be displayed in this case can be the "host", but it should be
> displayed differently than usual to avoid the notion of class membership.
Display issues should be handled by helpers, not by structure baked into the
IM. Ideally, a single helper object should embody the display policy for an
arbitrary number of IMs. (Object-specific policy could be something like,
"constant #2 is always the string to display on back traces".)
With all the access issues pushed into the MH's and all the side details pushed
into a helper object (or BSM), you might wonder what's left to specify in the
IM bytecodes themselves. The answer is that IM bytecodes are suprisingly
simple, compared to bytecodes that must perform symbolic resolution. In
particular, we only need invokestatic, and none of the other invokes or field
instructions. The "new" opcodes are also just sugar for reflective factory
(A final shot: The new/dup/invoke dance does *not*, IMO, belong in IM
bytecodes. In any case, we need to replace that with a factory-based idiom,
like "invokestatic C.<make>(*)C", to support value types. The <init> protocol
would be pushed private to C, inside <make> methods and calls to super.<init>.
So much tech. debt…)
mlvm-dev mailing list