Skip to content

Commit 253cd0e

Browse files
authored
[rustjava-2026-09-17-link-lambdametafactory-boxing-adapter-adopt-p0] feat: 람다 링커에 int↔Integer 어댑터 — 한 쌍만 (#103)
[rustjava-2026-09-17-link-lambdametafactory-boxing-adapter-adopt-p0] feat: 람다 링커에 int↔Integer 어댑터 — 한 쌍만
2 parents fdc24a5 + a908bd1 commit 253cd0e

21 files changed

Lines changed: 414 additions & 62 deletions

‎classfile/src/opcode.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ pub struct LambdaCallSite {
3535
/// `samMethodType`) — that is the one callers invoke through the interface.
3636
pub method_name: Arc<String>,
3737
pub method_descriptor: Arc<String>,
38+
/// The same method with its generic type arguments filled in (the bootstrap's
39+
/// `instantiatedMethodType`). Read only where an adapter converts a value: it is what says an
40+
/// erased `Object` parameter is an `Integer` to unbox rather than, say, a `Short`.
41+
pub instantiated_method_descriptor: Arc<String>,
3842
/// The method the interface method delegates to (the bootstrap's `implMethod`).
3943
pub implementation: MethodHandleRef,
4044
}

‎docs/next.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ for f in sorted(glob.glob('docs/worklog/*.json')):
1919
print(*[r for r in refs if r not in done],sep='\n')"
2020
```
2121

22-
1. **선행 사슬**: `2026-09-17-link-lambdametafactory#p0`(어댑터 · ★지금 착수 가능 — `#p1` 은 2026-09-26 「현 상태 유지」로 닫혔고 등록 방식이 안 바뀌므로 선행 조건 없음 · `docs/lambda-class-reflection-visibility.md`) → `java.lang.invoke` 패키지(카드 없음 · 근거 = `rustjava-runtime/src/classes/java/lang/invoke` **부재**) → `2026-09-17-string-concat-recipe-arity#p1`.
22+
1. **선행 사슬**: `java.lang.invoke` 패키지(카드 없음 · 근거 = `rustjava-runtime/src/classes/java/lang/invoke` **부재** · ★다음 칸) → `2026-09-17-string-concat-recipe-arity#p1`. 앞 칸 `2026-09-17-link-lambdametafactory#p0`(어댑터)은 2026-09-27 에 `int`↔`Integer` 한 쌍으로 닫혔다(`docs/worklog/2026-09-27-lambda-int-integer-adapter.md`). 다른 쌍은 이 사슬의 칸이 아니다. 필요한 게스트가 생기면 한 쌍씩 새 카드로 연다.
2323
2. **카드 밖**: 없음. PR #81 은 2026-09-26 에 닫혔다 — #83(`750d30d4`)과 같은 변경이었다(`docs/worklog/2026-09-26-pr81-closed-duplicate-of-pr83.md`).
2424

2525
지난 판(⓪-사료·①~⑤)은 동결된 `STATE.md` `## 다음` 아래에 그대로 있다.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"date": "2026-09-27",
3+
"taskId": "rustjava-2026-09-17-link-lambdametafactory-boxing-adapter-adopt-p0",
4+
"summary": "LambdaMetafactory linker inserts the int <-> Integer adapter; every other conversion pair stays refused.",
5+
"proposals": [],
6+
"adoptedProposals": ["2026-09-17-link-lambdametafactory#p0"]
7+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## [2026-09-27] 람다 링커에 int↔Integer 어댑터 — 한 쌍만 (rustjava-2026-09-17-link-lambdametafactory-boxing-adapter-adopt-p0)
2+
- 무엇을: `jvm-bytecode/src/lambda.rs` 의 통과 전용 술어 `adapts` 를 위치별 계획 `plan` 으로 바꿨다. 통과(pass-through)는 종전 술어 `passes` 를 그대로 먼저 묻고, 그 밖에는 `int`↔`Integer` 한 쌍만 삽입한다 — 나갈 때 `Integer.valueOf`, 들어올 때 `Integer` 검사 후 `intValue`(null → NPE · 다른 타입 → CCE, 실제 팩토리와 같은 예외). 링크 여부와 실행 시 변환이 **같은 함수**에서 나온다. 부트스트랩 셋째 인자 `instantiatedMethodType` 을 `LambdaCallSite` 에 실었다 — 지워진 `Object` 가 `Integer` 인지 `Short` 인지는 그것만 말한다.
3+
- 왜: `2026-09-17-link-lambdametafactory#p0` 채택. `Supplier<Integer>`·`Function<T,Integer>` 모양이 원시값 구현에 닿는 자리가 전부 거부되고 있었다. 한 쌍으로 좁힌 이유 = 카드의 tradeoff(잘못 허용한 쌍은 거부를 틀린 답으로 바꾼다).
4+
- 사용자 영향: 박싱이 필요한 람다·메서드 참조가 로드·실행된다(OpenJDK 26.0.2.1 과 출력 일치). 그 밖의 쌍(`long` 박싱 · 언박싱 후 확장 · `Number` 로 박싱)은 여전히 거부된다.
5+
6+
### 실측
7+
| 무엇 | 결과 |
8+
|---|---|
9+
| `LambdaBoxing`(종전 거부 픽스처) | 수정 전 거부 → 수정 후 `3`(OpenJDK 와 동일) |
10+
| `LambdaBoxingKinds`(신규 · 위치 5 + 예외 3) | `4 / 42 / 7 / obj:5 / integer:6 / npe in / cce / npe out` — OpenJDK 26.0.2.1 출력과 줄 단위 일치 |
11+
| `LambdaBoxingLong`·`LambdaUnboxingShort`(신규 · 거부 유지) | 둘 다 `UnsupportedOperationException … invokedynamic` (OpenJDK 는 `5000000000`·`42`) |
12+
| 통과 경우 기존 시험(`Lambda`·`LambdaKinds`·`LambdaCapturingThis`) | 불변 green |
13+
| `verify-javac-fixtures.sh`(javac 26.0.2.1) | 33/33 재현 |
14+
15+
### 되돌리면 red (변이 6종 · 전부 1건 red)
16+
| 변이 | red 가 된 시험 |
17+
|---|---|
18+
| M1 인자 박싱 제거 | int↔Integer 시험 |
19+
| M1b 반환 박싱 제거 | int↔Integer 시험 (`LambdaBoxing`) |
20+
| M2 언박싱에서 instantiated 가 `Integer` 인지 안 봄 | 거부 시험 (`LambdaUnboxingShort` 가 링크된다) |
21+
| M3 `long` 도 박싱 허용 | 거부 시험 (`LambdaBoxingLong`) |
22+
| M4 언박싱 전 `Integer` 검사 제거 | int↔Integer 시험 (`cce` 줄) |
23+
| M5 반환 언박싱 제거 | int↔Integer 시험 |
24+
25+
### 범위 밖(카드 없음)
26+
- 다른 쌍은 쌍마다 따로 추가한다. 지금은 필요로 하는 게스트가 없다. wie 게스트 jar 는 major 47 이라 `invokedynamic` 에 닿지 않는다(`2026-09-26-lambda-class-reflection-visibility`). 그래서 제안 카드를 만들지 않았다.
27+
- 캡처 값은 어댑트하지 않는다(통과가 아니면 거부). javac 는 구현 타입 그대로 캡처한다.

0 commit comments

Comments
 (0)