[JSC][Temporal] Implement Temporal.ZonedDateTime
// 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가 상당히 확장되었습니다.