[code-reflection] RFR: Issue errors when quotable constructs are found inside inner classes
Maurizio Cimadamore
mcimadamore at openjdk.org
Tue Jul 8 10:20:02 UTC 2025
On Mon, 7 Jul 2025 21:53:00 GMT, Paul Sandoz <psandoz at openjdk.org> wrote:
> In this respect do we need to stick closely to the bytecode that javac generates?
>
> Interpreting or generating bytecode and executing would require the user passing the contextual arguments. (More broadly when generating bytecode and executing we have to also supply access control context and set things up appropriately. I seem to recall some difficulties around that, but the details escape me right now.)
The main issue I see with this is that when you generate bytecode, now you have to:
1. emit synthetic fields storing `this$0` and, possibly captured values
2. remove all the synthetic parameters from the model
3. replace access to the now-removed synthetic parameters with access to the synthetic fields
IMHO all the steps above are fairly tricky. Even computing the full set of synthetic field an inner class has is probably going to be tricky, as you will have to look at _all_ the instance method of the class, and look at all the synthetic parameters, and come up with some kind of "set of captures". Not sure how you compare captures from different instance methods. Not even sure how you can tell something *is* a synthetic parameter. To make this more feasible, I think some kind of parameter metadata is the bare minimum.
But even if we had that metadata, (2) and (3) are still a lot of work.
I think it would be somehow better if we could model the array of captures as a single entity -- say we have a fictional class called `CapturedValues` (this might be a core type?). Then, the above would become:
func @"f" (%0 : CapturedValues, %1 : java.type:"TestInner::Inner")java.type:"void" -> {
%2: load %0 CapturedValue::encl_this
invoke %2 @java.ref:"TestInner::m():void";
invoke %2 @java.ref:"TestInner::m():void";
return @loc="16:9";
};
And, a constructor of an inner class is a constructor that accepts captured parameters, and writes them into the leading `CapturedValues` object (also passed as parameter).
Adjusting this code is still tricky, as you still need to do (2) and (3) -- but since access to all captured state is mediated by "imaginary" fields in the `CapturedValues` "class", it is easier for a processor to understand which is which?
-------------
PR Comment: https://git.openjdk.org/babylon/pull/486#issuecomment-3048280706
More information about the babylon-dev
mailing list