[Temporal] Add Instant.(compare|prototype.equals)

Also implement AO: CompareEpochNanoseconds
Spec Text:
https://tc39.es/proposal-temporal/#sec-temporal.instant.compare
https://tc39.es/proposal-temporal/#sec-temporal.instant.prototype.equals

Bug: v8:11544
Change-Id: I953a890250ff0bf29cd24e4638bf17ceb5f9bb2f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3382057
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80959}
This commit is contained in:
Frank Tang 2022-06-06 10:02:57 -07:00
parent 8436df4b68
commit 6d33cb89a4
5 changed files with 89 additions and 29 deletions

View File

@ -104,8 +104,6 @@ TO_BE_IMPLEMENTED(TemporalDurationPrototypeToLocaleString)
TO_BE_IMPLEMENTED(TemporalDurationPrototypeToString)
/* Temporal.Instant */
/* Temporal #sec-temporal.instant.compare */
TO_BE_IMPLEMENTED(TemporalInstantCompare)
/* Temporal #sec-temporal.instant.prototype.add */
TO_BE_IMPLEMENTED(TemporalInstantPrototypeAdd)
/* Temporal #sec-temporal.instant.prototype.subtract */
@ -116,8 +114,6 @@ TO_BE_IMPLEMENTED(TemporalInstantPrototypeUntil)
TO_BE_IMPLEMENTED(TemporalInstantPrototypeSince)
/* Temporal #sec-temporal.instant.prototype.round */
TO_BE_IMPLEMENTED(TemporalInstantPrototypeRound)
/* Temporal #sec-temporal.instant.prototype.equals */
TO_BE_IMPLEMENTED(TemporalInstantPrototypeEquals)
/* Temporal #sec-temporal.instant.prototype.tolocalestring */
TO_BE_IMPLEMENTED(TemporalInstantPrototypeToLocaleString)
/* Temporal #sec-temporal.instant.prototype.tostring */
@ -244,6 +240,15 @@ TO_BE_IMPLEMENTED(TemporalZonedDateTimePrototypeToLocaleString)
JSTemporal##T ::METHOD(isolate, args.atOrUndefined(isolate, 1))); \
}
#define TEMPORAL_METHOD2(T, METHOD) \
BUILTIN(Temporal##T##METHOD) { \
HandleScope scope(isolate); \
RETURN_RESULT_OR_FAILURE( \
isolate, \
JSTemporal##T ::METHOD(isolate, args.atOrUndefined(isolate, 1), \
args.atOrUndefined(isolate, 2))); \
}
#define TEMPORAL_GET(T, METHOD, field) \
BUILTIN(Temporal##T##Prototype##METHOD) { \
HandleScope scope(isolate); \
@ -645,6 +650,8 @@ TEMPORAL_METHOD1(Instant, FromEpochMilliseconds)
TEMPORAL_METHOD1(Instant, FromEpochMicroseconds)
TEMPORAL_METHOD1(Instant, FromEpochNanoseconds)
TEMPORAL_METHOD1(Instant, From)
TEMPORAL_METHOD2(Instant, Compare)
TEMPORAL_PROTOTYPE_METHOD1(Instant, Equals, equals)
TEMPORAL_VALUE_OF(Instant)
TEMPORAL_GET(Instant, EpochNanoseconds, nanoseconds)
TEMPORAL_GET_NUMBER_AFTER_DIVID(Instant, EpochSeconds, nanoseconds, 1000000000,

View File

@ -2816,10 +2816,18 @@ MaybeHandle<JSTemporalZonedDateTime> SystemZonedDateTime(
return CreateTemporalZonedDateTime(isolate, ns, time_zone, calendar);
}
#define COMPARE_RESULT_TO_SIGN(r) \
((r) == ComparisonResult::kEqual \
? 0 \
: ((r) == ComparisonResult::kLessThan ? -1 : 1))
int CompareResultToSign(ComparisonResult r) {
switch (r) {
case ComparisonResult::kEqual:
return 0;
case ComparisonResult::kLessThan:
return -1;
case ComparisonResult::kGreaterThan:
return 1;
case ComparisonResult::kUndefined:
UNREACHABLE();
}
}
// #sec-temporal-formattimezoneoffsetstring
Handle<String> FormatTimeZoneOffsetString(Isolate* isolate,
@ -5027,7 +5035,7 @@ Maybe<NanosecondsToDaysResult> NanosecondsToDays(Isolate* isolate,
// 3. Let sign be ! (Sign(𝔽(nanoseconds))).
ComparisonResult compare_result =
BigInt::CompareToBigInt(nanoseconds, BigInt::FromInt64(isolate, 0));
double sign = COMPARE_RESULT_TO_SIGN(compare_result);
double sign = CompareResultToSign(compare_result);
// 4. Let dayLengthNs be 8.64 × 10^13.
Handle<BigInt> day_length_ns = BigInt::FromInt64(isolate, 86400000000000LLU);
// 5. If sign is 0, then
@ -5197,7 +5205,7 @@ Maybe<NanosecondsToDaysResult> NanosecondsToDays(Isolate* isolate,
// c. If (nanoseconds dayLengthNs) × sign ≥ 0, then
compare_result = BigInt::CompareToBigInt(nanoseconds, day_length_ns);
if (sign * COMPARE_RESULT_TO_SIGN(compare_result) >= 0) {
if (sign * CompareResultToSign(compare_result) >= 0) {
// i. Set nanoseconds to nanoseconds dayLengthNs.
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, nanoseconds,
@ -10612,8 +10620,6 @@ MaybeHandle<JSTemporalPlainDateTime> JSTemporalPlainTime::ToPlainDateTime(
namespace {
enum class Arithmetic { kAdd, kSubtract };
// #sec-temporal-adddurationtoorsubtractdurationfromplaintime
MaybeHandle<JSTemporalPlainTime> AddDurationToOrSubtractDurationFromPlainTime(
Isolate* isolate, Arithmetic operation,
@ -11081,6 +11087,19 @@ Maybe<StringPrecision> ToSecondsStringPrecision(
}
}
// #sec-temporal-compareepochnanoseconds
MaybeHandle<Smi> CompareEpochNanoseconds(Isolate* isolate, Handle<BigInt> one,
Handle<BigInt> two) {
TEMPORAL_ENTER_FUNC();
// 1. If epochNanosecondsOne > epochNanosecondsTwo, return 1.
// 2. If epochNanosecondsOne < epochNanosecondsTwo, return -1.
// 3. Return 0.
return handle(
Smi::FromInt(CompareResultToSign(BigInt::CompareToBigInt(one, two))),
isolate);
}
} // namespace
// #sec-temporal.plaintime.prototype.tostring
@ -11764,14 +11783,13 @@ MaybeHandle<JSTemporalInstant> JSTemporalInstant::Constructor(
Isolate* isolate, Handle<JSFunction> target, Handle<HeapObject> new_target,
Handle<Object> epoch_nanoseconds_obj) {
TEMPORAL_ENTER_FUNC();
const char* method_name = "Temporal.Instant";
// 1. If NewTarget is undefined, then
if (new_target->IsUndefined()) {
// a. Throw a TypeError exception.
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
isolate->factory()->NewStringFromAsciiChecked(
method_name)),
"Temporal.Instant")),
JSTemporalInstant);
}
// 2. Let epochNanoseconds be ? ToBigInt(epochNanoseconds).
@ -11877,6 +11895,46 @@ MaybeHandle<JSTemporalInstant> JSTemporalInstant::FromEpochNanoseconds(
return ScaleToNanosecondsVerifyAndMake(isolate, epoch_nanoseconds, 1);
}
// #sec-temporal.instant.compare
MaybeHandle<Smi> JSTemporalInstant::Compare(Isolate* isolate,
Handle<Object> one_obj,
Handle<Object> two_obj) {
TEMPORAL_ENTER_FUNC();
const char* method_name = "Temporal.Instant.compare";
// 1. Set one to ? ToTemporalInstant(one).
Handle<JSTemporalInstant> one;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, one, ToTemporalInstant(isolate, one_obj, method_name), Smi);
// 2. Set two to ? ToTemporalInstant(two).
Handle<JSTemporalInstant> two;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, two, ToTemporalInstant(isolate, two_obj, method_name), Smi);
// 3. Return 𝔽(! CompareEpochNanoseconds(one.[[Nanoseconds]],
// two.[[Nanoseconds]])).
return CompareEpochNanoseconds(isolate, handle(one->nanoseconds(), isolate),
handle(two->nanoseconds(), isolate));
}
// #sec-temporal.instant.prototype.equals
MaybeHandle<Oddball> JSTemporalInstant::Equals(Isolate* isolate,
Handle<JSTemporalInstant> handle,
Handle<Object> other_obj) {
TEMPORAL_ENTER_FUNC();
// 1. Let instant be the this value.
// 2. Perform ? RequireInternalSlot(instant, [[InitializedTemporalInstant]]).
// 3. Set other to ? ToTemporalInstant(other).
Handle<JSTemporalInstant> other;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, other,
ToTemporalInstant(isolate, other_obj,
"Temporal.Instant.prototype.equals"),
Oddball);
// 4. If instant.[[Nanoseconds]] ≠ other.[[Nanoseconds]], return false.
// 5. Return true.
return isolate->factory()->ToBoolean(
BigInt::EqualToBigInt(handle->nanoseconds(), other->nanoseconds()));
}
// #sec-temporal.instant.from
MaybeHandle<JSTemporalInstant> JSTemporalInstant::From(Isolate* isolate,
Handle<Object> item) {

View File

@ -246,6 +246,16 @@ class JSTemporalInstant
ToZonedDateTimeISO(Isolate* isolate, Handle<JSTemporalInstant> instant,
Handle<Object> item);
// #sec-temporal.instant.compare
V8_WARN_UNUSED_RESULT static MaybeHandle<Smi> Compare(Isolate* isolate,
Handle<Object> one,
Handle<Object> two);
// #sec-temporal.instant.prototype.equals
V8_WARN_UNUSED_RESULT static MaybeHandle<Oddball> Equals(
Isolate* isolate, Handle<JSTemporalInstant> instant,
Handle<Object> other);
DECL_PRINTER(JSTemporalInstant)
TQ_OBJECT_CONSTRUCTORS(JSTemporalInstant)

View File

@ -49,9 +49,7 @@
'temporal/duration-add': [FAIL],
'temporal/duration-to-json': [FAIL],
'temporal/instant-add': [FAIL],
'temporal/instant-compare': [FAIL],
'temporal/instant-constructor': [FAIL],
'temporal/instant-equals': [FAIL],
'temporal/instant-from-epoch-microseconds': [FAIL],
'temporal/instant-from-epoch-milliseconds': [FAIL],
'temporal/instant-from-epoch-nanoseconds': [FAIL],

View File

@ -347,8 +347,6 @@
'built-ins/Temporal/Duration/prototype/round/timezone-getpossibleinstantsfor-iterable': [FAIL],
'built-ins/Temporal/Duration/prototype/total/timezone-getpossibleinstantsfor-iterable': [FAIL],
'built-ins/Temporal/Instant/from/instant-string-multiple-offsets': [SKIP],
# https://github.com/tc39/test262/issues/3262
'built-ins/Temporal/Duration/prototype/add/calendar-dateadd-called-with-options-undefined': [FAIL],
'built-ins/Temporal/Duration/prototype/subtract/calendar-dateadd-called-with-options-undefined': [FAIL],
@ -541,9 +539,7 @@
'built-ins/Temporal/Duration/prototype/total/unit-plurals-accepted-string': [FAIL],
'built-ins/Temporal/Duration/prototype/total/unit-string-shorthand-string': [FAIL],
'built-ins/Temporal/Duration/prototype/total/unit-wrong-type': [FAIL],
'built-ins/Temporal/Instant/compare/argument-zoneddatetime': [FAIL],
'built-ins/Temporal/Instant/compare/instant-string': [FAIL],
'built-ins/Temporal/Instant/compare/instant-string-multiple-offsets': [FAIL],
'built-ins/Temporal/Instant/from/instant-string': [FAIL],
'built-ins/Temporal/Instant/from/timezone-custom': [FAIL],
'built-ins/Temporal/Instant/prototype/add/argument-string': [FAIL],
@ -556,10 +552,7 @@
'built-ins/Temporal/Instant/prototype/add/result-out-of-range': [FAIL],
'built-ins/Temporal/Instant/prototype/add/subclassing-ignored': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/argument-wrong-type': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/argument-zoneddatetime': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/branding': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/instant-string': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/instant-string-multiple-offsets': [FAIL],
'built-ins/Temporal/Instant/prototype/round/branding': [FAIL],
'built-ins/Temporal/Instant/prototype/round/options-wrong-type': [FAIL],
'built-ins/Temporal/Instant/prototype/round/roundingincrement-nan': [FAIL],
@ -1470,9 +1463,7 @@
'built-ins/Temporal/Duration/prototype/toString/fractionalseconddigits-exact-number-of-digits': [FAIL],
'built-ins/Temporal/Duration/prototype/total/calendar-possibly-required': [FAIL],
'built-ins/Temporal/Duration/prototype/total/year-zero': [FAIL],
'built-ins/Temporal/Instant/compare/year-zero': [FAIL],
'built-ins/Temporal/Instant/prototype/add/argument-string-fractional-units-rounding-mode': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/year-zero': [FAIL],
'built-ins/Temporal/Instant/prototype/since/largestunit-smallestunit-mismatch': [FAIL],
'built-ins/Temporal/Instant/prototype/since/year-zero': [FAIL],
'built-ins/Temporal/Instant/prototype/subtract/argument-string-fractional-units-rounding-mode': [FAIL],
@ -1857,12 +1848,8 @@
'built-ins/Temporal/Duration/prototype/total/relativeto-propertybag-calendar-wrong-type': [FAIL],
'built-ins/Temporal/Duration/prototype/total/relativeto-wrong-type': [FAIL],
'built-ins/Temporal/Duration/prototype/total/timezone-wrong-type': [FAIL],
'built-ins/Temporal/Instant/compare/argument-object-tostring': [FAIL],
'built-ins/Temporal/Instant/compare/argument-wrong-type': [FAIL],
'built-ins/Temporal/Instant/compare/instant-string-sub-minute-offset': [FAIL],
'built-ins/Temporal/Instant/from/argument-wrong-type': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/argument-object-tostring': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/instant-string-sub-minute-offset': [FAIL],
'built-ins/Temporal/Instant/prototype/since/argument-object-tostring': [FAIL],
'built-ins/Temporal/Instant/prototype/since/argument-wrong-type': [FAIL],
'built-ins/Temporal/Instant/prototype/since/instant-string-sub-minute-offset': [FAIL],