3-3. Test262 100% 달성기
기간: 2026년 3월 19~20일 (2일) 커밋: 261개 (138 + 123) 세션: 19개 (3/19: 5개, 3/20: 14개!) 핵심: Test262 13.7% → 65.6% → 100% (50,504건 전체 통과)
3/19 아침: "ZTS 백로그 이어서 진행해줘"
3월 19일 첫 세션(01:45 UTC)의 요청은 명확했다:
"ZTS 백로그 이어서 진행해줘. Test262 파서 통과율 개선부터"
파서 통과율 13.7% → 65.6%
이 하나의 커밋 뒤에는 수십 가지 수정이 들어있었다. 하지만 곧바로 /simplify 리뷰 요구가 따라왔다:
"네 끊고 올리고 다음에 해야할 숙제 메모리에 저장 후 /simplify하고 머지 하고 ㄱㄱ" "리베이스 머지가 규칙이에요" — PR 머지 방식에 대한 명확한 규칙 설정
이 세션에서 확립된 중요한 워크플로우:
"아니 멈추고 PR 올리고 /simplify 진행하고 계속 이어서 가시죠" — 기능 구현 → PR → /simplify → 머지의 사이클
그리고 계속 /simplify 실행 여부를 확인했다:
"/simplify 한거야?" "/simplify 진행 하셧어요?" "/simplify 했어?"
Semantic Analysis 설계 (D038) — 의사결정의 전형
두 번째 세션(03:29 UTC):
"semantic analysis 의사결정(D038) 진행하고 구현 시작해줘"
여기서 의사결정 프로세스의 전형적인 패턴이 드러난다. 5개의 하위 결정에 대해:
"51. B / 52. B / 53. 은 추천대로 / 54. A / 55. A 로 갈건데 나머지 옵션이나 이런것도 일단 진행전에 다 장단점 좀 더 자세히 설명해줘"
각 옵션에 대해 깊이 파고들었다:
"A는 세밀한 통계를 볼 수 있는거야?" "근데 그게 좋을까?" "러스트 장점이 컴파일러가 친절하다는거였는데, 이런거랑은 맥락이 다른가?"
결정 후에도 지속적으로 방향 확인:
"그리고 코드 작성하면서 기존 계획이 무너지거나 엣지 케이스가 생긴건 없나요?" "처음 설계대로 안간게 문제가 있을까요?" "구현 목표에 영향이 가는게 없죠?"
Context 비트플래그 리팩터링과 "oxc를 따르라" 원칙
세 번째 세션(08:15 UTC):
"Context bitflags 리팩터링 시작해줘"
파서의 Context를 개별 bool에서 packed struct(u8)로 통합:
이 세션에서 프로젝트의 핵심 원칙이 확립됐다:
"그리고 구현 방법이 여러가지라면 왠만하면 oxc 따라줘 그리고 병렬로 해줘" — 3/19 세션
이 한 마디가 이후 프로젝트의 모든 의사결정에 적용되는 기본 원칙이 됐다.
네 번째 세션 — dstr rest-init + RegExp 설계 결정
"그룹 1 (dstr rest-init, ~279건)부터 시작해줘 그리고 메모리에 정해져있는 우선순위대로 계속 진행"
이 세션에서 중요한 구조적 결정들이 이루어졌다:
Cover Grammar 방식 결정:
"추후 유지보수를 위해선 저 방법 중 뭐가 더 나은데? 다른 방법은 또 없어?" — 4가지 방법을 비교 "방법 2로 가자 그럼 계속"
RegExp validator 설계 — 풀 파서(C) 선택:
세 가지 선택지가 있었다:
- A: 플래그만 검증 (빠르지만 불완전)
- B: 중간 수준 검증
- C: 풀 regexp parser
각각의 성능과 안정성을 상세히 비교한 후:
"C 성능은 어때?" "A,B,C 중 뭐가 젤 안정성 있는데?" "그럼 상위버전에서 풀파서면 하위버전으로 내려갈떄 C는 영향 없지?" "C로 가자 이런건 좀 크더라도 유지보수나 안정성을 생각해야해"
이 결정은 "안정성 우선" 원칙의 대표적 사례다. 단기적으로는 A가 빠르지만, 장기적 유지보수와 스펙 변경 대응을 위해 가장 완전한 방식을 선택했다.
comptime 모드 분리도 이때 결정됐다:
"근데 나중에 할거라면 B 미리 해둬도 상관없는건지? 아니면 미리 안하는게 더 안좋은지?" "네 그럼 그거 문서에 꼭 적어주시고 B로 가시죠"
미래에 필요한 확장성은 문서에 기록하되, 현재는 필요한 것만 구현하는 실용적 접근.
"cover grammar로 우리도 전면 리팩토링 하자"
세션 말미에 중요한 결정:
"어떤것들 해야하죠 이제?" (엣지 케이스 설명을 듣고) "어느게 구조적 설계에 영향을 미치는 놈들일까요?" "cover grammar로 우리도 전면 리팩토링 하자"
이것이 3/20의 Cover Grammar 리팩터링으로 이어진다.
3/20: 14개 세션 — 프로젝트 최다 세션
3월 20일은 프로젝트에서 가장 집약적인 날이었다. 하루에 14개 세션, 123개 커밋.
Cover Grammar 리팩터링 (02:41 UTC)
ECMAScript에서 (a, b) = [1, 2]를 만났을 때, 파서는 처음에 이것을 "괄호로 묶인 표현식"으로 파싱한다. 그러다 =을 만나면 "아, 이건 destructuring 패턴이었구나"라고 재해석해야 한다.
ZTS의 24바이트 고정 노드 설계가 여기서 빛났다. 표현식 노드를 패턴 노드로 변환할 때, 새 노드를 할당하지 않고 setTag로 태그만 바꾸면 됐다. 7개의 assignment target 태그가 이 목적으로 추가됐다.
RegExp 풀 파서 구현 (03:18 UTC)
4개의 연속 PR로 구현:
각 PR 후에 /simplify 리뷰:
"네 계속 이 패턴으로 가주세요" — /simplify → 수정 → PR → 머지 사이클 확인
Semantic Early Error Checker (05:04 UTC)
"semantic 검증은 어떻게 구현하는게 좋을까요?" "그리고 oxc, swc, esbuild, babel 등은 어떻게 하는지?" "완전 분리라는게 B?" "네 그러시죠 B로 갑시다"
별도 checker.zig 모듈로 분리:
Parser 구조 리팩터링 (06:34 UTC)
Test262가 98.0%(470건 실패)에 도달한 시점에서, parser.zig가 너무 커져 구조 분리가 필요했다:
100% 달성 직전의 극단적 엣지 케이스들
마지막 34건은 가장 까다로운 케이스들이었다:
in_static_initializer컨텍스트가 화살표 함수 본문에서 복원되지 않는 문제- 중첩 클래스에서
has_super_class리셋 누락 - computed property key에서 private name 해석 시 escape sequence 고려 누락
delete private_field금지 (ECMAScript)- constructor가 getter/setter/generator/async 불가
100% 달성 후 — "한번 더 점검하고 싶어" (12:43 UTC)
"좋아 이제 Test262 달성하긴 했는데 한번 더 점검하고 싶어" "좋아 다 가자"
100%를 달성했지만 바로 다음으로 넘어가지 않았다:
"CI 다돌면 머지좀" — CI 통과 확인 후에만 머지
"이제 해야할 작업이 무엇일까요?" (14:57 UTC)
Test262 100%와 구조 리팩터링을 마치고:
"이제 해야할 작업이 무엇일까요?" "페이즈 2, 1 아직 안된거야?? 어느부분이 부족? 언제하는게 낫지?"
이 세션에서 Diagnostic 통합, 예약어 검증, @panic("OOM") 교체 등의 인프라 작업이 진행됐다:
"갑자기 왜이리 많은 부분을 고친거야??" — /simplify가 한번에 많은 이슈를 발견 "그리고 스킵한 이유는 뭐야??" "아니 잘 고쳤는데 이유가 궁금해" "나머지 스킵한 항목들도 언젠간해야되는건지? 걍유지해도 되는지 궁금해" "하면 좋은건 하자"
Phase 6 선행 작업 + Arena Allocator (17:38~18:08 UTC)
"페이즈 6 들어가기전에 선행해야할거 또 뭐 있을까?"
Arena Allocator를 도입:
@panic("OOM") 90개 이상을 에러 전파로 교체하는 대규모 리팩터링도 이때 진행됐다.
이 시기의 핵심 교훈
- Test262는 최고의 안전망: 50,504개의 테스트가 모든 리팩터링의 안전을 보장했다.
- "oxc를 따르라": 구현 방법이 여러 가지일 때의 기본 선택으로 의사결정 시간을 크게 줄였다.
- 안정성 우선: RegExp 풀 파서(C) 선택, 구조적 수정 우선 — 단기 비용보다 장기 안정성.
- comptime의 위력: RegExp 파서를 검증/AST 이중 모드로, 런타임 비용 없이 하나의 코드로.
- 끊임없는 /simplify: 매 PR마다 리뷰를 빠뜨리지 않는 규율이 코드 품질을 유지.