On Tue, 2 Jun 2026 13:19:14 GMT, Maurizio Cimadamore <[email protected]> 
wrote:

>> This PR removes some unnecessary coupling between Lower, Gen and 
>> LocalProxyVarsGen.
>> 
>> It does so by making LocalProxyVarsGen no longer a standalone pass but, 
>> rather, a helper for Gen::normalizeMethod.
>> 
>> The main idea is that we can make things more regular, by having Gen always 
>> inserting variable initializer in the correct place.
>> Then, LocalProxyVarGen will create a blank proxy, and use its visitor to 
>> inspect the rest of the constructor body.
>> Since the visitor _already_ rewires assignments to real fields as 
>> assignments to proxies, this new arrangement has the desired effect of 
>> generating the same code as before, but w/o too much coupling.
>> 
>> Some massaging to `Gen::normalizeMethod` was needed because now we need to 
>> make sure it calls the proxy step for all constructors, not just in case 
>> there's some pending var initializers.
>> 
>> Finally, when cleaning up `Lower` I noticed a likely bug: `freevardefs` was 
>> no longer preserving the `LOCAL_CAPTURE_FIELD` -- sometimes it was replacing 
>> it with `STRICT`. But `LOCAL_CAPTURE_FIELD` is used by LambdaToMethod, so 
>> changing this probably results in bad downstream lowering.
>> I've fixed this by adding both `STRICT` _and_ `LOCAL_CAPTURE_FIELD` to the 
>> captured sym.
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> Maurizio Cimadamore has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Fix issues with LambdaToMethod touching `this` too early

Found another issue in cases like this:


class Outer {
      class Inner {}

      value class V {
          Supplier<Object> s = () -> new Inner();
          V() { super(); }
      }
  }
 ```
Here we will try to emit an instance lambda method that captures `this` (and 
accesses `this.this$0` in its body). This won't fly if we're in early 
construction context.

To workaround this, when we determine lambda captures, if we see `this$0` 
reference and we're inside an early field initializer, we capture `this$0` 
directly (instead of setting `captureThis = true`). This will make the 
generated lambda method static, and will means that the client will pass 
`this$0` explicitly as a capture param. Then `Gen` will see that and patch 
access with access to the synthetic ctor param.

Note: rewriting the lambda as a static lambda works here because the lambda 
should have no direct dependencies on `this` or `super` (as those are forbidden 
by language rules). What's left can be dealt with in the context of a static 
lambda with some extra capture params.

-------------

PR Comment: https://git.openjdk.org/valhalla/pull/2488#issuecomment-4602788516

Reply via email to