[JSC][Temporal] Implement Temporal.ZonedDateTime
SVG transform mutations now batch and flush once per frame — but the flush fires BEFORE the re-entrancy guard during a higher layout.
// JSTests/stress/temporal-boundary-values.js
{
const maxNs = 8640000000000000000000n;
const zdt = new Temporal.ZonedDateTime(maxNs, "UTC");
shouldBe(zdt.epochNanoseconds, maxNs, "max epoch ns");
}
shouldThrow(() => new Temporal.ZonedDateTime(8640000000000000000001n, "UTC"));
shouldThrow(() => new Temporal.ZonedDateTime(-8640000000000000000001n, "UTC"));
// intl-canonical-iana-time-zone.js — FIXMEs removed:
for (const [legacy, primary] of pairs) {
shouldBeTrue(new Temporal.ZonedDateTime(0n, legacy).equals(new Temporal.ZonedDateTime(0n, primary)));
}
Temporal은 TC39가 제정한 새로운 날짜/시간 API로, 기존 Date 객체를 대체합니다. 그 중 ZonedDateTime은 가장 복잡한 타입입니다. 절대 시각을 BigInt 기반의 epoch 나노초 값(±8.64×10²¹ ns 범위)으로 저장하며, IANA time zone 이름과 선택적 non-ISO calendar를 함께 결합합니다. JSC는 Japanese calendar처럼 비그레고리안 calendar를 지원하기 위해 ICU를 통합합니다. Japanese calendar는 year 외에 era/eraYear 의미 체계를 추가로 갖습니다. DST gap/fold 해소에는 별도의 time zone 인프라를 사용합니다.
이 commit은 constructor와 prototype(모든 getter 및 method 포함)을 구현합니다. Temporal.Now.zonedDateTimeISO도 함께 구현되었으며, ZonedDateTime을 relativeTo로 사용하는 Duration.round/total/compare도 이번 범위에 포함됩니다. 함께 포함된 correctness fix들도 주목할 만합니다. 우선 static_cast<int32_t>(double) 형태의 변환 여러 곳이 clampTo<int32_t>로 교체되었습니다. [INT32_MIN, INT32_MAX] 범위를 벗어난 double을 int32_t로 캐스팅하는 동작은 C++ UB에 해당합니다. 최적화 컴파일러에서는 공격자가 영향을 줄 수 있는 bit pattern이 생성될 가능성이 있습니다. 또한 String 멤버를 소유하는 JSC heap object가 cellHeapCellType에서 destructibleCellHeapCellType으로 변경되었습니다. 이는 destructor가 호출되지 않아 발생하던 StringImpl 누수를 수정한 것입니다. 마지막으로 DurationArithmetic::computeNudgeWindow에서 잘못된 spec shortcut이 수정되었습니다. 기존 코드는 DateDurationSign(startDuration) == 0 대신 r1 == 0을 확인하고 있었습니다.
Significance
UB fix 다수와 GC destructor 누락이 함께 발견된 것은, 기존 Temporal 코드베이스에 잠재적 결함이 존재했음을 시사합니다. 이번에 여러 사례가 확인된 만큼, 아직 발견되지 않은 사례가 더 남아 있을 가능성이 있습니다. 이 commit은 TC39 Temporal proposal 중 가장 복잡한 타입을 도입합니다. BigInt epoch 연산, DST를 고려한 time zone 해소, ICU calendar 통합이 모두 포함됩니다. 결과적으로 어느 페이지에서도 접근 가능한 JSC의 새로운 attack surface가 상당히 확장되었습니다.
Audit directions
- Temporal C++ 내 잔존하는 double-to-integer 직접 캐스팅. year/month/day/hour 필드가 UB 발생 지점이 될 수 있습니다. Temporal 소스에서
static_cast<int32_t>와static_cast<uint8_t>를 검색해야 합니다. - Temporal 서브트리 전반의
destructibleCellHeapCellType누락.TemporalInstant,TemporalPlainDate,TemporalTimeZone등을 점검해야 합니다.String이나 non-trivially-destructible 멤버를 소유하면서cellHeapCellType을 그대로 사용하는 JSC heap object는 누수가 발생합니다. destructor가 type 정보에 의존하는 경우 UAF로 이어질 가능성도 있습니다. CalendarICUBridge의optional<int32_t> year파라미터 변경. 모든 호출 지점의 동작이 묵시적으로 달라집니다. 이전에 year를 의도치 않게 전달하던 호출 측은NonISOResolveFields일관성 검사를 건너뛰게 됩니다. 모든 호출 측이nullopt를 올바르게 전달하는지 확인해야 합니다.ZonedDateTime.prototype.with()와 arithmetic method의 DST fold disambiguation. edge-case 버그가 발생하기 쉬운 영역으로 알려져 있습니다. 새로 추가된temporal-zdt-large-fold-disambiguation테스트는 이미 하나가 발견되었음을 확인해 줍니다. DST gap과 fold, 모호한 transition 시점의 시각으로 fuzz 테스트를 진행해야 합니다.- constructor와 새로운 epoch 값을 생성하는 연산 전반의 BigInt-to-epoch-nanosecond 변환. ±8.64×10²¹ 경계에서의 off-by-one을 점검해야 합니다.