Commit 8a14d953 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

[Temporal] Sync to PR1953 and PR1917 to fix bugs.

https://github.com/tc39/proposal-temporal/pull/1917
https://github.com/tc39/proposal-temporal/pull/1953

Bug: v8:11544
Change-Id: I667980e312248ccbaf826d4e3104fb1ddabef890
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3721464
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81453}
parent 4f49b8a2
......@@ -220,10 +220,6 @@ Maybe<TimeRecord> ParseTemporalTimeString(Isolate* isolate,
V8_WARN_UNUSED_RESULT Maybe<DurationRecord> ParseTemporalDurationString(
Isolate* isolate, Handle<String> iso_string);
// #sec-temporal-parsetemporaltimezone
V8_WARN_UNUSED_RESULT MaybeHandle<String> ParseTemporalTimeZone(
Isolate* isolate, Handle<String> string);
// #sec-temporal-parsetemporaltimezonestring
V8_WARN_UNUSED_RESULT Maybe<TimeZoneRecord> ParseTemporalTimeZoneString(
Isolate* isolate, Handle<String> iso_string);
......@@ -1068,6 +1064,7 @@ MaybeHandle<JSTemporalTimeZone> CreateTemporalTimeZone(
Isolate* isolate, Handle<JSFunction> target, Handle<HeapObject> new_target,
Handle<String> identifier) {
TEMPORAL_ENTER_FUNC();
// 1. If newTarget is not present, set it to %Temporal.TimeZone%.
// 2. Let object be ? OrdinaryCreateFromConstructor(newTarget,
// "%Temporal.TimeZone.prototype%", « [[InitializedTemporalTimeZone]],
......@@ -2797,13 +2794,53 @@ MaybeHandle<JSReceiver> ToTemporalTimeZone(
ASSIGN_RETURN_ON_EXCEPTION(isolate, identifier,
Object::ToString(isolate, temporal_time_zone_like),
JSReceiver);
// 3. Let result be ? ParseTemporalTimeZone(identifier).
Handle<String> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, ParseTemporalTimeZone(isolate, identifier), JSReceiver);
// 4. Return ? CreateTemporalTimeZone(result).
return temporal::CreateTemporalTimeZone(isolate, result);
// 3. Let parseResult be ? ParseTemporalTimeZoneString(identifier).
TimeZoneRecord parse_result;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, parse_result, ParseTemporalTimeZoneString(isolate, identifier),
Handle<JSReceiver>());
// 4. If parseResult.[[Name]] is not undefined, then
if (parse_result.name->length() > 0) {
// a. Let name be parseResult.[[Name]].
Handle<String> name = parse_result.name;
// b. If ParseText(StringToCodePoints(name, TimeZoneNumericUTCOffset)) is
// not a List of errors, then
base::Optional<ParsedISO8601Result> parsed_offset =
TemporalParser::ParseTimeZoneNumericUTCOffset(isolate, name);
if (parsed_offset.has_value()) {
// i. If parseResult.[[OffsetString]] is not undefined, and !
// ParseTimeZoneOffsetString(parseResult.[[OffsetString]]) ≠ !
// ParseTimeZoneOffsetString(name), throw a RangeError exception.
if (parse_result.offset_string->length() > 0 &&
ParseTimeZoneOffsetString(isolate, parse_result.offset_string)
.ToChecked() !=
ParseTimeZoneOffsetString(isolate, name).ToChecked()) {
THROW_NEW_ERROR(isolate, NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR(),
JSReceiver);
}
// c. Else,
} else {
// i. If ! IsValidTimeZoneName(name) is false, throw a RangeError
// exception.
if (!IsValidTimeZoneName(isolate, name)) {
THROW_NEW_ERROR(isolate, NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR(),
JSReceiver);
}
// ii. Set name to ! CanonicalizeTimeZoneName(name).
name = CanonicalizeTimeZoneName(isolate, name);
// d. Return ! CreateTemporalTimeZone(name).
return temporal::CreateTemporalTimeZone(isolate, name);
}
}
// 5. If parseResult.[[Z]] is true, return ! CreateTemporalTimeZone("UTC").
if (parse_result.z) {
return CreateTemporalTimeZoneUTC(isolate);
}
// 6. Return ! CreateTemporalTimeZone(parseResult.[[OffsetString]]).
return temporal::CreateTemporalTimeZone(isolate, parse_result.offset_string);
}
} // namespace temporal
......@@ -3611,121 +3648,36 @@ Maybe<TimeZoneRecord> ParseTemporalTimeZoneString(Isolate* isolate,
// TimeZoneUTCOffsetSign, TimeZoneUTCOffsetHour, TimeZoneUTCOffsetMinute,
// TimeZoneUTCOffsetSecond, TimeZoneUTCOffsetFraction, and TimeZoneIANAName
// productions, or undefined if not present.
// 4. If z is not undefined, then
if (parsed->utc_designator) {
// a. Return the Record { [[Z]]: true, [[OffsetString]]: undefined,
// [[Name]]: name }.
if (parsed->tzi_name_length > 0) {
Handle<String> name = isolate->factory()->NewSubString(
iso_string, parsed->tzi_name_start,
parsed->tzi_name_start + parsed->tzi_name_length);
TimeZoneRecord ret({true, isolate->factory()->empty_string(), name});
return Just(ret);
}
TimeZoneRecord ret({true, isolate->factory()->empty_string(),
isolate->factory()->empty_string()});
return Just(ret);
}
// 5. If hours is undefined, then
// a. Let offsetString be undefined.
// 6. Else,
Handle<String> offset_string;
bool offset_string_is_defined = false;
if (!parsed->tzuo_hour_is_undefined()) {
// a. Assert: sign is not undefined.
DCHECK(!parsed->tzuo_sign_is_undefined());
// b. Set hours to ! ToIntegerOrInfinity(hours).
int64_t hours = parsed->tzuo_hour;
// c. If sign is the code unit 0x002D (HYPHEN-MINUS) or the code unit 0x2212
// (MINUS SIGN), then i. Set sign to −1. d. Else, i. Set sign to 1.
int64_t sign = parsed->tzuo_sign;
// e. Set minutes to ! ToIntegerOrInfinity(minutes).
int64_t minutes =
parsed->tzuo_minute_is_undefined() ? 0 : parsed->tzuo_minute;
// f. Set seconds to ! ToIntegerOrInfinity(seconds).
int64_t seconds =
parsed->tzuo_second_is_undefined() ? 0 : parsed->tzuo_second;
// g. If fraction is not undefined, then
int64_t nanoseconds;
if (!parsed->tzuo_nanosecond_is_undefined()) {
// i. Set fraction to the string-concatenation of the previous value of
// fraction and the string "000000000".
// ii. Let nanoseconds be the String value equal to the substring of
// fraction from 0 to 9. iii. Set nanoseconds to !
// ToIntegerOrInfinity(nanoseconds).
nanoseconds = parsed->tzuo_nanosecond;
// h. Else,
} else {
// i. Let nanoseconds be 0.
nanoseconds = 0;
}
// i. Let offsetNanoseconds be sign × (((hours × 60 + minutes) × 60 +
// seconds) × 10^9 + nanoseconds).
int64_t offset_nanoseconds =
sign *
(((hours * 60 + minutes) * 60 + seconds) * 1000000000 + nanoseconds);
// j. Let offsetString be ! FormatTimeZoneOffsetString(offsetNanoseconds).
offset_string = FormatTimeZoneOffsetString(isolate, offset_nanoseconds);
offset_string_is_defined = true;
}
// 7. If name is not undefined, then
Handle<String> name;
// 4. If name is empty, then
// a. Set name to undefined.
Handle<String> name = isolate->factory()->empty_string();
// 5. Else,
// a. Set name to CodePointsToString(name).
if (parsed->tzi_name_length > 0) {
name = isolate->factory()->NewSubString(
iso_string, parsed->tzi_name_start,
parsed->tzi_name_start + parsed->tzi_name_length);
// a. If ! IsValidTimeZoneName(name) is false, throw a RangeError exception.
if (!IsValidTimeZoneName(isolate, name)) {
THROW_NEW_ERROR_RETURN_VALUE(isolate,
NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR(),
Nothing<TimeZoneRecord>());
}
// b. Set name to ! CanonicalizeTimeZoneName(name).
name = CanonicalizeTimeZoneName(isolate, name);
// 8. Return the Record { [[Z]]: false, [[OffsetString]]: offsetString,
}
// 6. If z is not undefined, then
if (parsed->utc_designator) {
// a. Return the Record { [[Z]]: true, [[OffsetString]]: undefined,
// [[Name]]: name }.
TimeZoneRecord ret({false,
offset_string_is_defined
? offset_string
: isolate->factory()->empty_string(),
name});
return Just(ret);
}
// 8. Return the Record { [[Z]]: false, [[OffsetString]]: offsetString,
return Just(
TimeZoneRecord({true, isolate->factory()->empty_string(), name}));
}
// 7. If offsetString is empty, then
// a. Set offsetString to undefined.
Handle<String> offset_string = isolate->factory()->empty_string();
// 8. Else,
// a. Set offsetString to CodePointsToString(offsetString).
if (parsed->offset_string_length > 0) {
offset_string = isolate->factory()->NewSubString(
iso_string, parsed->offset_string_start,
parsed->offset_string_start + parsed->offset_string_length);
}
// 9. Return the Record { [[Z]]: false, [[OffsetString]]: offsetString,
// [[Name]]: name }.
TimeZoneRecord ret({false,
offset_string_is_defined
? offset_string
: isolate->factory()->empty_string(),
isolate->factory()->empty_string()});
return Just(ret);
}
// #sec-temporal-parsetemporaltimezone
MaybeHandle<String> ParseTemporalTimeZone(Isolate* isolate,
Handle<String> string) {
TEMPORAL_ENTER_FUNC();
// 2. Let result be ? ParseTemporalTimeZoneString(string).
TimeZoneRecord result;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, result, ParseTemporalTimeZoneString(isolate, string),
Handle<String>());
// 3. If result.[[Name]] is not undefined, return result.[[Name]].
if (result.name->length() > 0) {
return result.name;
}
// 4. If result.[[Z]] is true, return "UTC".
if (result.z) {
return isolate->factory()->UTC_string();
}
// 5. Return result.[[OffsetString]].
return result.offset_string;
return Just(TimeZoneRecord({false, offset_string, name}));
}
Maybe<int64_t> ParseTimeZoneOffsetString(Isolate* isolate,
......
......@@ -418,6 +418,8 @@ int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s,
// TZUOSign TZUOHour
r->tzuo_sign = sign;
r->tzuo_hour = hour;
r->offset_string_start = s;
r->offset_string_length = cur - s;
return cur - s;
}
if (str[cur] == ':') {
......@@ -429,6 +431,8 @@ int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s,
r->tzuo_sign = sign;
r->tzuo_hour = hour;
r->tzuo_minute = minute;
r->offset_string_start = s;
r->offset_string_length = cur - s;
return cur - s;
}
cur++;
......@@ -438,6 +442,8 @@ int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s,
// TZUOSign TZUOHour
r->tzuo_sign = sign;
r->tzuo_hour = hour;
r->offset_string_start = s;
r->offset_string_length = cur - s;
return cur - s;
}
cur += len;
......@@ -446,6 +452,8 @@ int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s,
r->tzuo_sign = sign;
r->tzuo_hour = hour;
r->tzuo_minute = minute;
r->offset_string_start = s;
r->offset_string_length = cur - s;
return cur - s;
}
}
......@@ -456,6 +464,8 @@ int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s,
r->tzuo_minute = minute;
r->tzuo_second = second;
if (len > 0) r->tzuo_nanosecond = nanosecond;
r->offset_string_start = s;
r->offset_string_length = cur + len - s;
return cur + len - s;
}
......@@ -608,6 +618,9 @@ int32_t ScanTimeZoneBracketedName(base::Vector<Char> str, int32_t s,
r->tzi_name_start = s;
r->tzi_name_length = len;
return len;
} else {
r->tzi_name_start = 0;
r->tzi_name_length = 0;
}
return ScanTimeZoneUTCOffsetName(str, s);
}
......@@ -620,6 +633,9 @@ int32_t ScanTimeZoneBracketedAnnotation(base::Vector<Char> str, int32_t s,
int32_t cur = s + 1;
cur += ScanTimeZoneBracketedName(str, cur, r);
if ((cur - s == 1) || str.length() < (cur + 1) || (str[cur++] != ']')) {
// Reset value setted by ScanTimeZoneBracketedName
r->tzi_name_start = 0;
r->tzi_name_length = 0;
return 0;
}
return cur - s;
......
......@@ -43,6 +43,10 @@ struct ParsedISO8601Result {
int32_t calendar_name_start; // Starting offset of CalendarName production in
// the input string.
int32_t calendar_name_length; // Length of CalendarName production.
int32_t offset_string_start; // Starting offset of TimeZoneNumericUTCOffset
// in the input string.
int32_t
offset_string_length; // Length of TimeZoneNumericUTCOffset production
ParsedISO8601Result()
: date_year(kMinInt31),
......@@ -61,7 +65,9 @@ struct ParsedISO8601Result {
tzi_name_start(0),
tzi_name_length(0),
calendar_name_start(0),
calendar_name_length(0) {}
calendar_name_length(0),
offset_string_start(0),
offset_string_length(0) {}
bool date_year_is_undefined() const { return date_year == kMinInt31; }
bool date_month_is_undefined() const { return date_month == kMinInt31; }
......
......@@ -538,10 +538,6 @@
'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/instant-string': [FAIL],
'built-ins/Temporal/Instant/from/instant-string': [FAIL],
'built-ins/Temporal/Instant/from/timezone-custom': [FAIL],
'built-ins/Temporal/Instant/prototype/equals/instant-string': [FAIL],
'built-ins/Temporal/Instant/prototype/round/subclassing-ignored': [FAIL],
'built-ins/Temporal/Instant/prototype/since/argument-zoneddatetime': [FAIL],
'built-ins/Temporal/Instant/prototype/since/branding': [FAIL],
......@@ -947,7 +943,6 @@
'built-ins/Temporal/TimeZone/prototype/getInstantFor/disambiguation-undefined': [FAIL],
'built-ins/Temporal/TimeZone/prototype/getInstantFor/options-undefined': [FAIL],
'built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/balance-negative-time-units': [FAIL],
'built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/instant-string': [FAIL],
'built-ins/Temporal/TimeZone/prototype/getPossibleInstantsFor/argument-zoneddatetime-balance-negative-time-units': [FAIL],
'built-ins/Temporal/ZonedDateTime/compare/zoneddatetime-string': [FAIL],
'built-ins/Temporal/ZonedDateTime/compare/zoneddatetime-string-multiple-offsets': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment