Skip to content

Commit

Permalink
[JSC] Remove obsoleted Temporal.Instant API
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=278285

Reviewed by NOBODY (OOPS!).

At the TC39 meeting on 2024-06, it was decied to obsolete several Temporal APIs[1][2].

This patch removes the following for Temporal.Instant:

- Temporal.Instant.fromEpochSeconds
- Temporal.Instant.fromEpochMicroseconds
- Temporal.Instant.prototype.epochSeconds
- Temporal.Instant.prototype.epochMicroseconds

[1]: https://github.com/tc39/notes/blob/main/meetings/2024-06/june-12.md#temporal-stage-3-update-and-scope-reduction
[2]: tc39/proposal-temporal#2895

* JSTests/stress/date-to-temporal-instant.js:
(shouldBe):
* JSTests/stress/temporal-instant.js:
(shouldBe):
(instants.forEach):
* Source/JavaScriptCore/runtime/ISO8601.h:
* Source/JavaScriptCore/runtime/TemporalInstant.cpp:
* Source/JavaScriptCore/runtime/TemporalInstant.h:
* Source/JavaScriptCore/runtime/TemporalInstantConstructor.cpp:
* Source/JavaScriptCore/runtime/TemporalInstantPrototype.cpp:
  • Loading branch information
sosukesuzuki committed Aug 18, 2024
1 parent bae3341 commit a20048e
Show file tree
Hide file tree
Showing 7 changed files with 0 additions and 185 deletions.
10 changes: 0 additions & 10 deletions JSTests/stress/date-to-temporal-instant.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ function shouldThrow(func, errorType, message) {
shouldBe(epochDateInstant.toString(), epochInstant.toString());
shouldBe(epochDateInstant.epochNanoseconds, epochInstant.epochNanoseconds);

shouldBe(epochDateInstant.epochSeconds, 0);
shouldBe(epochDateInstant.epochMilliseconds, 0);
shouldBe(epochDateInstant.epochMicroseconds, 0n);
shouldBe(epochDateInstant.epochNanoseconds, 0n);

}
Expand All @@ -54,9 +52,7 @@ function shouldThrow(func, errorType, message) {
shouldBe(dateToInstant.toString(), temporalInstant.toString());
shouldBe(dateToInstant.epochNanoseconds, temporalInstant.epochNanoseconds);

shouldBe(dateToInstant.epochSeconds, 1_000_000_000);
shouldBe(dateToInstant.epochMilliseconds, 1_000_000_000_000);
shouldBe(dateToInstant.epochMicroseconds, 1_000_000_000_000_000n);
shouldBe(dateToInstant.epochNanoseconds, 1_000_000_000_000_000_000n);
}

Expand All @@ -67,9 +63,7 @@ function shouldThrow(func, errorType, message) {
shouldBe(dateToInstant.toString(), temporalInstant.toString());
shouldBe(dateToInstant.epochNanoseconds, temporalInstant.epochNanoseconds);

shouldBe(dateToInstant.epochSeconds, -1_000_000_000);
shouldBe(dateToInstant.epochMilliseconds, -1_000_000_000_000);
shouldBe(dateToInstant.epochMicroseconds, -1_000_000_000_000_000n);
shouldBe(dateToInstant.epochNanoseconds, -1_000_000_000_000_000_000n);
}

Expand All @@ -80,9 +74,7 @@ function shouldThrow(func, errorType, message) {
shouldBe(dateToInstant.toString(), temporalInstant.toString());
shouldBe(dateToInstant.epochNanoseconds, temporalInstant.epochNanoseconds);

shouldBe(dateToInstant.epochSeconds, 86400_0000_0000);
shouldBe(dateToInstant.epochMilliseconds, 86400_0000_0000_000);
shouldBe(dateToInstant.epochMicroseconds, 86400_0000_0000_000_000n);
shouldBe(dateToInstant.epochNanoseconds, 86400_0000_0000_000_000_000n);
}

Expand All @@ -93,8 +85,6 @@ function shouldThrow(func, errorType, message) {
shouldBe(dateToInstant.toString(), temporalInstant.toString());
shouldBe(dateToInstant.epochNanoseconds, temporalInstant.epochNanoseconds);

shouldBe(dateToInstant.epochSeconds, -86400_0000_0000);
shouldBe(dateToInstant.epochMilliseconds, -86400_0000_0000_000);
shouldBe(dateToInstant.epochMicroseconds, -86400_0000_0000_000_000n);
shouldBe(dateToInstant.epochNanoseconds, -86400_0000_0000_000_000_000n);
}
43 changes: 0 additions & 43 deletions JSTests/stress/temporal-instant.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@ function shouldThrow(func, errorType, message) {
{
const instants = [
new Temporal.Instant(0n),
Temporal.Instant.fromEpochSeconds(0),
Temporal.Instant.fromEpochMilliseconds(0),
Temporal.Instant.fromEpochMicroseconds(0n),
Temporal.Instant.fromEpochNanoseconds(0n),
Temporal.Instant.from('1970-01-01T00:00:00Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, 0);
shouldBe(instant.epochMilliseconds, 0);
shouldBe(instant.epochMicroseconds, 0n);
shouldBe(instant.epochNanoseconds, 0n);
shouldBe(instant.toString(), '1970-01-01T00:00:00Z');
shouldBe(instant.toJSON(), '1970-01-01T00:00:00Z');
Expand All @@ -54,16 +50,12 @@ function shouldThrow(func, errorType, message) {
{
const instants = [
new Temporal.Instant(1_000_000_000_000_000_000n),
Temporal.Instant.fromEpochSeconds(1_000_000_000),
Temporal.Instant.fromEpochMilliseconds(1_000_000_000_000),
Temporal.Instant.fromEpochMicroseconds(1_000_000_000_000_000n),
Temporal.Instant.fromEpochNanoseconds(1_000_000_000_000_000_000n),
Temporal.Instant.from('2001-09-09T01:46:40Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, 1_000_000_000);
shouldBe(instant.epochMilliseconds, 1_000_000_000_000);
shouldBe(instant.epochMicroseconds, 1_000_000_000_000_000n);
shouldBe(instant.epochNanoseconds, 1_000_000_000_000_000_000n);
shouldBe(instant.toString(), '2001-09-09T01:46:40Z');
shouldBe(instant.toJSON(), '2001-09-09T01:46:40Z');
Expand All @@ -74,16 +66,12 @@ function shouldThrow(func, errorType, message) {
{
const instants = [
new Temporal.Instant(-1_000_000_000_000_000_000n),
Temporal.Instant.fromEpochSeconds(-1_000_000_000),
Temporal.Instant.fromEpochMilliseconds(-1_000_000_000_000),
Temporal.Instant.fromEpochMicroseconds(-1_000_000_000_000_000n),
Temporal.Instant.fromEpochNanoseconds(-1_000_000_000_000_000_000n),
Temporal.Instant.from('1938-04-24T22:13:20Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, -1_000_000_000);
shouldBe(instant.epochMilliseconds, -1_000_000_000_000);
shouldBe(instant.epochMicroseconds, -1_000_000_000_000_000n);
shouldBe(instant.epochNanoseconds, -1_000_000_000_000_000_000n);
shouldBe(instant.toString(), '1938-04-24T22:13:20Z');
shouldBe(instant.toJSON(), '1938-04-24T22:13:20Z');
Expand All @@ -98,9 +86,7 @@ function shouldThrow(func, errorType, message) {
Temporal.Instant.from('2262-04-11T23:47:16.854775807Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, 9223372036);
shouldBe(instant.epochMilliseconds, 9223372036854);
shouldBe(instant.epochMicroseconds, 9223372036854775n);
shouldBe(instant.epochNanoseconds, 9223372036854775807n);
shouldBe(instant.toString(), '2262-04-11T23:47:16.854775807Z');
shouldBe(instant.toJSON(), '2262-04-11T23:47:16.854775807Z');
Expand All @@ -115,9 +101,7 @@ function shouldThrow(func, errorType, message) {
Temporal.Instant.from('1677-09-21T00:12:43.145224192Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, -9223372036);
shouldBe(instant.epochMilliseconds, -9223372036854);
shouldBe(instant.epochMicroseconds, -9223372036854775n);
shouldBe(instant.epochNanoseconds, -9223372036854775808n);
shouldBe(instant.toString(), '1677-09-21T00:12:43.145224192Z');
shouldBe(instant.toJSON(), '1677-09-21T00:12:43.145224192Z');
Expand All @@ -128,16 +112,12 @@ function shouldThrow(func, errorType, message) {
{
const instants = [
new Temporal.Instant(86400_0000_0000_000_000_000n),
Temporal.Instant.fromEpochSeconds(86400_0000_0000),
Temporal.Instant.fromEpochMilliseconds(86400_0000_0000_000),
Temporal.Instant.fromEpochMicroseconds(86400_0000_0000_000_000n),
Temporal.Instant.fromEpochNanoseconds(86400_0000_0000_000_000_000n),
Temporal.Instant.from('+275760-09-13T00:00:00Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, 86400_0000_0000);
shouldBe(instant.epochMilliseconds, 86400_0000_0000_000);
shouldBe(instant.epochMicroseconds, 86400_0000_0000_000_000n);
shouldBe(instant.epochNanoseconds, 86400_0000_0000_000_000_000n);
shouldBe(instant.toString(), '+275760-09-13T00:00:00Z');
shouldBe(instant.toJSON(), '+275760-09-13T00:00:00Z');
Expand All @@ -148,16 +128,12 @@ function shouldThrow(func, errorType, message) {
{
const instants = [
new Temporal.Instant(-86400_0000_0000_000_000_000n),
Temporal.Instant.fromEpochSeconds(-86400_0000_0000),
Temporal.Instant.fromEpochMilliseconds(-86400_0000_0000_000),
Temporal.Instant.fromEpochMicroseconds(-86400_0000_0000_000_000n),
Temporal.Instant.fromEpochNanoseconds(-86400_0000_0000_000_000_000n),
Temporal.Instant.from('-271821-04-20T00:00:00Z'),
];
instants.forEach((instant) => {
shouldBe(instant.epochSeconds, -86400_0000_0000);
shouldBe(instant.epochMilliseconds, -86400_0000_0000_000);
shouldBe(instant.epochMicroseconds, -86400_0000_0000_000_000n);
shouldBe(instant.epochNanoseconds, -86400_0000_0000_000_000_000n);
shouldBe(instant.toString(), '-271821-04-20T00:00:00Z');
shouldBe(instant.toJSON(), '-271821-04-20T00:00:00Z');
Expand All @@ -182,25 +158,6 @@ function shouldThrow(func, errorType, message) {
shouldThrow(() => Temporal.Instant.fromEpochNanoseconds(ns), RangeError, messageMatch);
});

[
// too large
[86400_0000_0000_000_001n, /\b8640000000000000001\b/],
// too small
[-86400_0000_0000_000_001n, /-8640000000000000001\b/],
// test maxuint64 specifically
[1n << 64n, /\b18446744073709551616\b/],
// test maxuint128 specifically
[1n << 128n, /\b340282366920938463463374607431768211456\b/],
// much larger than maxint128
[1n << 129n, /\b680564733841876926926749214863536422912\b/],
// smaller than minint128
[-1n << 129n, /-680564733841876926926749214863536422912\b/],
// behaves sensibly even when the bigint is really long
[BigInt('9'.repeat(1000))],
].forEach(([µs, messageMatch = undefined]) => {
shouldThrow(() => Temporal.Instant.fromEpochMicroseconds(µs), RangeError, messageMatch);
});

// constructs from string
shouldBe(new Temporal.Instant('0').epochNanoseconds, 0n);
// throws on number
Expand Down
16 changes: 0 additions & 16 deletions Source/JavaScriptCore/runtime/ISO8601.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,32 +100,16 @@ class ExactTime {
constexpr ExactTime(const ExactTime&) = default;
constexpr explicit ExactTime(Int128 epochNanoseconds) : m_epochNanoseconds(epochNanoseconds) { }

static constexpr ExactTime fromEpochSeconds(int64_t epochSeconds)
{
return ExactTime(Int128 { epochSeconds } * ExactTime::nsPerSecond);
}
static constexpr ExactTime fromEpochMilliseconds(int64_t epochMilliseconds)
{
return ExactTime(Int128 { epochMilliseconds } * ExactTime::nsPerMillisecond);
}
static constexpr ExactTime fromEpochMicroseconds(int64_t epochMicroseconds)
{
return ExactTime(Int128 { epochMicroseconds } * ExactTime::nsPerMicrosecond);
}
static ExactTime fromISOPartsAndOffset(int32_t y, uint8_t mon, uint8_t d, unsigned h, unsigned min, unsigned s, unsigned ms, unsigned micros, unsigned ns, int64_t offset);

int64_t epochSeconds() const
{
return static_cast<int64_t>(m_epochNanoseconds / ExactTime::nsPerSecond);
}
int64_t epochMilliseconds() const
{
return static_cast<int64_t>(m_epochNanoseconds / ExactTime::nsPerMillisecond);
}
int64_t epochMicroseconds() const
{
return static_cast<int64_t>(m_epochNanoseconds / ExactTime::nsPerMicrosecond);
}
constexpr Int128 epochNanoseconds() const
{
return m_epochNanoseconds;
Expand Down
72 changes: 0 additions & 72 deletions Source/JavaScriptCore/runtime/TemporalInstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,26 +180,6 @@ TemporalInstant* TemporalInstant::from(JSGlobalObject* globalObject, JSValue ite
return toInstant(globalObject, itemValue);
}

// Temporal.Instant.fromEpochSeconds ( epochSeconds )
// https://tc39.es/proposal-temporal/#sec-temporal.instant.fromepochseconds
TemporalInstant* TemporalInstant::fromEpochSeconds(JSGlobalObject* globalObject, JSValue epochSecondsValue)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

double epochSeconds = epochSecondsValue.toNumber(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);

// NumberToBigInt step 1
if (!isInteger(epochSeconds)) {
throwRangeError(globalObject, scope, makeString(epochSeconds, " is not a valid integer number of epoch seconds"_s));
return nullptr;
}

ISO8601::ExactTime exactTime = ISO8601::ExactTime::fromEpochSeconds(epochSeconds);
RELEASE_AND_RETURN(scope, tryCreateIfValid(globalObject, exactTime));
}

// Temporal.Instant.fromEpochMilliseconds ( epochMilliseconds )
// https://tc39.es/proposal-temporal/#sec-temporal.instant.fromepochmilliseconds
TemporalInstant* TemporalInstant::fromEpochMilliseconds(JSGlobalObject* globalObject, JSValue epochMillisecondsValue)
Expand All @@ -220,58 +200,6 @@ TemporalInstant* TemporalInstant::fromEpochMilliseconds(JSGlobalObject* globalOb
RELEASE_AND_RETURN(scope, tryCreateIfValid(globalObject, exactTime));
}

// Temporal.Instant.fromEpochMicroseconds ( epochMicroseconds )
// https://tc39.es/proposal-temporal/#sec-temporal.instant.fromepochmicroseconds
TemporalInstant* TemporalInstant::fromEpochMicroseconds(JSGlobalObject* globalObject, JSValue epochMicrosecondsValue)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

JSValue epochMicroseconds = epochMicrosecondsValue.toBigInt(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);

#if USE(BIGINT32)
if (epochMicroseconds.isBigInt32()) {
int32_t microseconds = epochMicroseconds.bigInt32AsInt32();
auto exactTime = ISO8601::ExactTime::fromEpochMicroseconds(microseconds);
ASSERT(exactTime.isValid());
return create(vm, globalObject->instantStructure(), exactTime);
}
#endif

JSBigInt* bigint = asHeapBigInt(epochMicroseconds);
bool bigIntTooLong;
if constexpr (sizeof(JSBigInt::Digit) == 4) {
bigIntTooLong = bigint->length() > 2;
// Handle maxint64 < abs(bigint) <= maxuint64 explicitly, otherwise the
// cast to int64 below is undefined
if (bigint->length() == 2 && (bigint->digit(1) & 0x8000'0000))
bigIntTooLong = true;
} else {
ASSERT(sizeof(JSBigInt::Digit) == 8);
bigIntTooLong = bigint->length() > 1;
// Handle maxint64 < abs(bigint) <= maxuint64 explicitly, otherwise the
// cast to int64 below is undefined
if (bigint->length() == 1 && (bigint->digit(0) & 0x8000'0000'0000'0000))
bigIntTooLong = true;
}
int64_t microseconds = bigIntTooLong ? 0 : JSBigInt::toBigInt64(bigint);
auto exactTime = ISO8601::ExactTime::fromEpochMicroseconds(microseconds);

if (bigIntTooLong || !exactTime.isValid()) {
String argAsString = bigint->toString(globalObject, 10);
if (scope.exception()) {
scope.clearException();
argAsString = "The given number of"_s;
}

throwRangeError(globalObject, scope, makeString(ellipsizeAt(100, argAsString), " epoch microseconds is outside of supported range for Temporal.Instant"_s));
return nullptr;
}

return create(vm, globalObject->instantStructure(), exactTime);
}

// Temporal.Instant.fromEpochNanoseconds ( epochNanoseconds )
// https://tc39.es/proposal-temporal/#sec-temporal.instant.fromepochnanoseconds
TemporalInstant* TemporalInstant::fromEpochNanoseconds(JSGlobalObject* globalObject, JSValue epochNanosecondsValue)
Expand Down
2 changes: 0 additions & 2 deletions Source/JavaScriptCore/runtime/TemporalInstant.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ class TemporalInstant final : public JSNonFinalObject {

static TemporalInstant* toInstant(JSGlobalObject*, JSValue);
static TemporalInstant* from(JSGlobalObject*, JSValue);
static TemporalInstant* fromEpochSeconds(JSGlobalObject*, JSValue);
static TemporalInstant* fromEpochMilliseconds(JSGlobalObject*, JSValue);
static TemporalInstant* fromEpochMicroseconds(JSGlobalObject*, JSValue);
static TemporalInstant* fromEpochNanoseconds(JSGlobalObject*, JSValue);
static JSValue compare(JSGlobalObject*, JSValue, JSValue);

Expand Down
14 changes: 0 additions & 14 deletions Source/JavaScriptCore/runtime/TemporalInstantConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ namespace JSC {
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(TemporalInstantConstructor);

static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncFrom);
static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochSeconds);
static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochMilliseconds);
static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochMicroseconds);
static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochNanoseconds);
static JSC_DECLARE_HOST_FUNCTION(temporalInstantConstructorFuncCompare);

Expand All @@ -53,9 +51,7 @@ const ClassInfo TemporalInstantConstructor::s_info = { "Function"_s, &Base::s_in
/* Source for TemporalInstantConstructor.lut.h
@begin temporalInstantConstructorTable
from temporalInstantConstructorFuncFrom DontEnum|Function 1
fromEpochSeconds temporalInstantConstructorFuncFromEpochSeconds DontEnum|Function 1
fromEpochMilliseconds temporalInstantConstructorFuncFromEpochMilliseconds DontEnum|Function 1
fromEpochMicroseconds temporalInstantConstructorFuncFromEpochMicroseconds DontEnum|Function 1
fromEpochNanoseconds temporalInstantConstructorFuncFromEpochNanoseconds DontEnum|Function 1
compare temporalInstantConstructorFuncCompare DontEnum|Function 2
@end
Expand Down Expand Up @@ -116,21 +112,11 @@ JSC_DEFINE_HOST_FUNCTION(temporalInstantConstructorFuncFrom, (JSGlobalObject* gl
return JSValue::encode(TemporalInstant::from(globalObject, callFrame->argument(0)));
}

JSC_DEFINE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochSeconds, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
return JSValue::encode(TemporalInstant::fromEpochSeconds(globalObject, callFrame->argument(0)));
}

JSC_DEFINE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochMilliseconds, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
return JSValue::encode(TemporalInstant::fromEpochMilliseconds(globalObject, callFrame->argument(0)));
}

JSC_DEFINE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochMicroseconds, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
return JSValue::encode(TemporalInstant::fromEpochMicroseconds(globalObject, callFrame->argument(0)));
}

JSC_DEFINE_HOST_FUNCTION(temporalInstantConstructorFuncFromEpochNanoseconds, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
return JSValue::encode(TemporalInstant::fromEpochNanoseconds(globalObject, callFrame->argument(0)));
Expand Down
Loading

0 comments on commit a20048e

Please sign in to comment.