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
