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

[Temporal] Part2 Add constructor and simple getters.

Bug: v8:11544

Change-Id: I3206ca3e0c505b14e4497ccb2af25a31940a1c1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2967755Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78518}
parent 5d32b17b
......@@ -1630,6 +1630,7 @@ filegroup(
"src/objects/js-regexp.h",
"src/objects/js-temporal-objects.h",
"src/objects/js-temporal-objects-inl.h",
"src/objects/js-temporal-objects.cc",
"src/objects/js-weak-refs.h",
"src/objects/js-weak-refs-inl.h",
"src/objects/keys.cc",
......@@ -2675,6 +2676,7 @@ filegroup(
"src/builtins/builtins-sharedarraybuffer-gen.cc",
"src/builtins/builtins-string-gen.cc",
"src/builtins/builtins-string-gen.h",
"src/builtins/builtins-temporal-gen.cc",
"src/builtins/builtins-typed-array-gen.cc",
"src/builtins/builtins-typed-array-gen.h",
"src/builtins/builtins-utils-gen.h",
......
......@@ -2339,6 +2339,7 @@ v8_source_set("v8_initializers") {
"src/builtins/builtins-sharedarraybuffer-gen.cc",
"src/builtins/builtins-string-gen.cc",
"src/builtins/builtins-string-gen.h",
"src/builtins/builtins-temporal-gen.cc",
"src/builtins/builtins-typed-array-gen.cc",
"src/builtins/builtins-typed-array-gen.h",
"src/builtins/builtins-utils-gen.h",
......@@ -4257,6 +4258,7 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/js-segment-iterator.cc",
"src/objects/js-segmenter.cc",
"src/objects/js-segments.cc",
"src/objects/js-temporal-objects.cc",
"src/objects/keys.cc",
"src/objects/literal-objects.cc",
"src/objects/lookup-cache.cc",
......
......@@ -1637,7 +1637,10 @@ namespace internal {
/* Temporal #sec-temporal.calendar.prototype.tostring */ \
CPP(TemporalCalendarPrototypeToString) \
/* Temporal #sec-temporal.calendar.prototype.tojson */ \
CPP(TemporalCalendarPrototypeToJSON)
CPP(TemporalCalendarPrototypeToJSON) \
\
/* "Private" (created but not exposed) Bulitins needed by Temporal */ \
TFJ(TemporalInstantFixedArrayFromIterable, kJSArgcReceiverSlots, kIterable)
#define BUILTIN_LIST_BASE(CPP, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE_TIER0(CPP, TFJ, TFC, TFS, TFH, ASM) \
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/objects/js-temporal-objects-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
namespace v8 {
namespace internal {
class TemporalBuiltinsAssembler : public IteratorBuiltinsAssembler {
public:
explicit TemporalBuiltinsAssembler(compiler::CodeAssemblerState* state)
: IteratorBuiltinsAssembler(state) {}
// For the use inside Temporal GetPossibleInstantFor
TNode<FixedArray> TemporalInstantFixedArrayFromIterable(
TNode<Context> context, TNode<Object> iterable);
};
// #sec-iterabletolistoftype
TNode<FixedArray>
TemporalBuiltinsAssembler::TemporalInstantFixedArrayFromIterable(
TNode<Context> context, TNode<Object> iterable) {
GrowableFixedArray list(state());
Label done(this);
// 1. If iterable is undefined, then
// a. Return a new empty List.
GotoIf(IsUndefined(iterable), &done);
// 2. Let iteratorRecord be ? GetIterator(items).
IteratorRecord iterator_record = GetIterator(context, iterable);
// 3. Let list be a new empty List.
Label loop_start(this,
{list.var_array(), list.var_length(), list.var_capacity()});
Goto(&loop_start);
// 4. Let next be true.
// 5. Repeat, while next is not false
Label if_isnottemporalinstant(this, Label::kDeferred),
if_exception(this, Label::kDeferred);
BIND(&loop_start);
{
// a. Set next to ? IteratorStep(iteratorRecord).
TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done);
// b. If next is not false, then
// i. Let nextValue be ? IteratorValue(next).
TNode<Object> next_value = IteratorValue(context, next);
// ii. If Type(nextValue) is not Object or nextValue does not have an
// [[InitializedTemporalInstant]] internal slot
GotoIf(TaggedIsSmi(next_value), &if_isnottemporalinstant);
TNode<Uint16T> next_value_type = LoadInstanceType(CAST(next_value));
GotoIfNot(IsTemporalInstantInstanceType(next_value_type),
&if_isnottemporalinstant);
// iii. Append nextValue to the end of the List list.
list.Push(next_value);
Goto(&loop_start);
// 5.b.ii
BIND(&if_isnottemporalinstant);
{
// 1. Let error be ThrowCompletion(a newly created TypeError object).
TVARIABLE(Object, var_exception);
{
compiler::ScopedExceptionHandler handler(this, &if_exception,
&var_exception);
CallRuntime(Runtime::kThrowTypeError, context,
SmiConstant(MessageTemplate::kIterableYieldedNonString),
next_value);
}
Unreachable();
// 2. Return ? IteratorClose(iteratorRecord, error).
BIND(&if_exception);
IteratorCloseOnException(context, iterator_record);
CallRuntime(Runtime::kReThrow, context, var_exception.value());
Unreachable();
}
}
BIND(&done);
return list.ToFixedArray();
}
TF_BUILTIN(TemporalInstantFixedArrayFromIterable, TemporalBuiltinsAssembler) {
auto context = Parameter<Context>(Descriptor::kContext);
auto iterable = Parameter<Object>(Descriptor::kIterable);
Return(TemporalInstantFixedArrayFromIterable(context, iterable));
}
} // namespace internal
} // namespace v8
This diff is collapsed.
......@@ -6384,6 +6384,11 @@ TNode<BoolT> CodeStubAssembler::IsStringInstanceType(
return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE));
}
TNode<BoolT> CodeStubAssembler::IsTemporalInstantInstanceType(
TNode<Int32T> instance_type) {
return InstanceTypeEqual(instance_type, JS_TEMPORAL_INSTANT_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsOneByteStringInstanceType(
TNode<Int32T> instance_type) {
CSA_DCHECK(this, IsStringInstanceType(instance_type));
......
......@@ -2582,6 +2582,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsSymbolInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsInternalizedStringInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsTemporalInstantInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsUniqueName(TNode<HeapObject> object);
TNode<BoolT> IsUniqueNameNoIndex(TNode<HeapObject> object);
TNode<BoolT> IsUniqueNameNoCachedIndex(TNode<HeapObject> object);
......
......@@ -104,6 +104,7 @@ namespace internal {
T(InstanceofNonobjectProto, \
"Function has non-object prototype '%' in instanceof check") \
T(InvalidArgument, "invalid_argument") \
T(InvalidArgumentForTemporal, "Invalid argument for Temporal %") \
T(InvalidInOperatorUse, "Cannot use 'in' operator to search for '%' in %") \
T(InvalidRegExpExecResult, \
"RegExp exec method returned something other than an Object or null") \
......@@ -345,6 +346,7 @@ namespace internal {
T(Invalid, "Invalid % : %") \
T(InvalidArrayLength, "Invalid array length") \
T(InvalidAtomicAccessIndex, "Invalid atomic access index") \
T(InvalidCalendar, "Invalid calendar specified: %") \
T(InvalidCodePoint, "Invalid code point %") \
T(InvalidCountValue, "Invalid count value") \
T(InvalidDataViewAccessorOffset, \
......@@ -358,6 +360,7 @@ namespace internal {
T(InvalidWeakSetValue, "Invalid value used in weak set") \
T(InvalidStringLength, "Invalid string length") \
T(InvalidTimeValue, "Invalid time value") \
T(InvalidTimeValueForTemporal, "Invalid time value for Temporal %") \
T(InvalidTimeZone, "Invalid time zone specified: %") \
T(InvalidTypedArrayAlignment, "% of % should be a multiple of %") \
T(InvalidTypedArrayIndex, "Invalid typed array index") \
......
......@@ -292,6 +292,8 @@ DEFINE_BOOL(allow_overwriting_for_next_flag, false,
// Flags for language modes and experimental language features.
DEFINE_BOOL(use_strict, false, "enforce strict mode")
DEFINE_BOOL(trace_temporal, false, "trace temporal code")
DEFINE_BOOL(harmony, false, "enable all completed harmony features")
DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
......
......@@ -4587,6 +4587,7 @@ void Genesis::InitializeGlobal_harmony_temporal() {
Handle<JSObject> now = factory()->NewJSObject(isolate_->object_function(),
AllocationType::kOld);
JSObject::AddProperty(isolate_, temporal, "Now", now, DONT_ENUM);
InstallToStringTag(isolate_, now, "Temporal.Now");
// Note: There are NO Temporal.Now.plainTime
// See https://github.com/tc39/proposal-temporal/issues/1540
......@@ -5195,6 +5196,17 @@ void Genesis::InitializeGlobal_harmony_temporal() {
}
#undef INSTALL_TEMPORAL_CTOR_AND_PROTOTYPE
#undef INSTALL_TEMPORAL_FUNC
// The TemporalInsantFixedArrayFromIterable functions is created but not
// exposed, as it is used internally by GetPossibleInstantsFor.
{
Handle<JSFunction> func = SimpleCreateFunction(
isolate_,
factory()->InternalizeUtf8String(
"TemporalInstantFixedArrayFromIterable"),
Builtin::kTemporalInstantFixedArrayFromIterable, 1, false);
native_context()->set_temporal_instant_fixed_array_from_iterable(*func);
}
}
#ifdef V8_INTL_SUPPORT
......
......@@ -168,6 +168,7 @@
V(_, computed_string, "<computed>") \
V(_, configurable_string, "configurable") \
V(_, conjunction_string, "conjunction") \
V(_, constrain_string, "constrain") \
V(_, construct_string, "construct") \
V(_, constructor_string, "constructor") \
V(_, current_string, "current") \
......@@ -229,6 +230,7 @@
V(_, get_string, "get") \
V(_, getOffsetNanosecondsFor_string, "getOffsetNanosecondsFor") \
V(_, getOwnPropertyDescriptor_string, "getOwnPropertyDescriptor") \
V(_, getPossibleInstantsFor_string, "getPossibleInstantsFor") \
V(_, getPrototypeOf_string, "getPrototypeOf") \
V(_, global_string, "global") \
V(_, globalThis_string, "globalThis") \
......@@ -326,6 +328,8 @@
V(_, overflow_string, "overflow") \
V(_, ownKeys_string, "ownKeys") \
V(_, percent_string, "percent") \
V(_, plainDate_string, "plainDate") \
V(_, plainTime_string, "plainTime") \
V(_, position_string, "position") \
V(_, preventExtensions_string, "preventExtensions") \
V(_, private_constructor_string, "#constructor") \
......@@ -343,11 +347,13 @@
V(_, RegExp_string, "RegExp") \
V(_, regexp_to_string, "[object RegExp]") \
V(_, reject_string, "reject") \
V(_, relativeTo_string, "relativeTo") \
V(_, resizable_string, "resizable") \
V(_, ResizableArrayBuffer_string, "ResizableArrayBuffer") \
V(_, resolve_string, "resolve") \
V(_, return_string, "return") \
V(_, revoke_string, "revoke") \
V(_, roundingIncrement_string, "roundingIncrement") \
V(_, RuntimeError_string, "RuntimeError") \
V(_, WebAssemblyException_string, "WebAssembly.Exception") \
V(_, Script_string, "Script") \
......
......@@ -207,6 +207,8 @@ enum ContextLookupFlags {
temporal_time_zone_function) \
V(JS_TEMPORAL_ZONED_DATE_TIME_FUNCTION_INDEX, JSFunction, \
temporal_zoned_date_time_function) \
V(TEMPORAL_INSTANT_FIXED_ARRAY_FROM_ITERABLE_FUNCTION_INDEX, JSFunction, \
temporal_instant_fixed_array_from_iterable) \
/* Context maps */ \
V(NATIVE_CONTEXT_MAP_INDEX, Map, native_context_map) \
V(FUNCTION_CONTEXT_MAP_INDEX, Map, function_context_map) \
......
......@@ -15,6 +15,7 @@
#include "src/api/api-inl.h"
#include "src/base/strings.h"
#include "src/date/date.h"
#include "src/execution/isolate.h"
#include "src/execution/local-isolate.h"
#include "src/handles/global-handles.h"
......@@ -2760,5 +2761,100 @@ std::set<std::string> Intl::SanctionedSimpleUnits() {
"year"});
}
// ecma-402/#sec-isvalidtimezonename
namespace {
bool IsUnicodeStringValidTimeZoneName(const icu::UnicodeString& id) {
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString canonical;
icu::TimeZone::getCanonicalID(id, canonical, status);
return U_SUCCESS(status) &&
canonical != icu::UnicodeString("Etc/Unknown", -1, US_INV);
}
} // namespace
MaybeHandle<String> Intl::CanonicalizeTimeZoneName(Isolate* isolate,
Handle<String> identifier) {
UErrorCode status = U_ZERO_ERROR;
std::string time_zone =
JSDateTimeFormat::CanonicalizeTimeZoneID(identifier->ToCString().get());
icu::UnicodeString time_zone_ustring =
icu::UnicodeString(time_zone.c_str(), -1, US_INV);
icu::UnicodeString canonical;
icu::TimeZone::getCanonicalID(time_zone_ustring, canonical, status);
CHECK(U_SUCCESS(status));
if (canonical == UNICODE_STRING_SIMPLE("Etc/UTC") ||
canonical == UNICODE_STRING_SIMPLE("Etc/GMT")) {
return isolate->factory()->UTC_string();
}
return Intl::ToString(isolate, canonical);
}
bool Intl::IsValidTimeZoneName(Isolate* isolate, Handle<String> id) {
std::string time_zone =
JSDateTimeFormat::CanonicalizeTimeZoneID(id->ToCString().get());
icu::UnicodeString time_zone_ustring =
icu::UnicodeString(time_zone.c_str(), -1, US_INV);
return IsUnicodeStringValidTimeZoneName(time_zone_ustring);
}
bool Intl::IsValidTimeZoneName(const icu::TimeZone& tz) {
icu::UnicodeString id;
tz.getID(id);
return IsUnicodeStringValidTimeZoneName(id);
}
// Function to support Temporal
std::string Intl::TimeZoneIdFromIndex(int32_t index) {
if (index == 0) return "UTC";
std::unique_ptr<icu::StringEnumeration> enumeration(
icu::TimeZone::createEnumeration());
int32_t curr = 0;
const char* id;
UErrorCode status = U_ZERO_ERROR;
while (U_SUCCESS(status) && curr < index &&
((id = enumeration->next(nullptr, status)) != nullptr)) {
CHECK(U_SUCCESS(status));
curr++;
}
CHECK(U_SUCCESS(status));
CHECK(id != nullptr);
return id;
}
Maybe<bool> Intl::GetTimeZoneIndex(Isolate* isolate, Handle<String> identifier,
int32_t* index) {
if (identifier->Equals(*isolate->factory()->UTC_string())) {
*index = 0;
return Just(true);
}
std::string identifier_str(identifier->ToCString().get());
std::unique_ptr<icu::TimeZone> tz(
icu::TimeZone::createTimeZone(identifier_str.c_str()));
if (!IsValidTimeZoneName(*tz)) {
return Just(false);
}
std::unique_ptr<icu::StringEnumeration> enumeration(
icu::TimeZone::createEnumeration());
int32_t curr = 0;
const char* id;
UErrorCode status = U_ZERO_ERROR;
while (U_SUCCESS(status) &&
(id = enumeration->next(nullptr, status)) != nullptr) {
if (identifier_str == id) {
*index = curr + 1;
return Just(true);
}
curr++;
}
CHECK(U_SUCCESS(status));
// We should not reach here, the !IsValidTimeZoneName should return earlier
UNREACHABLE();
}
} // namespace internal
} // namespace v8
......@@ -28,6 +28,7 @@ class BreakIterator;
class Collator;
class FormattedValue;
class StringEnumeration;
class TimeZone;
class UnicodeString;
} // namespace U_ICU_NAMESPACE
......@@ -295,6 +296,22 @@ class Intl {
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> AvailableCalendars(
Isolate* isolate);
V8_WARN_UNUSED_RESULT static bool IsValidTimeZoneName(
const icu::TimeZone& tz);
V8_WARN_UNUSED_RESULT static bool IsValidTimeZoneName(Isolate* isolate,
const std::string& id);
V8_WARN_UNUSED_RESULT static bool IsValidTimeZoneName(Isolate* isolate,
Handle<String> id);
// Function to support Temporal
V8_WARN_UNUSED_RESULT static std::string TimeZoneIdFromIndex(int32_t index);
V8_WARN_UNUSED_RESULT static Maybe<bool> GetTimeZoneIndex(
Isolate* isolate, Handle<String> identifier, int32_t* index);
V8_WARN_UNUSED_RESULT static MaybeHandle<String> CanonicalizeTimeZoneName(
Isolate* isolate, Handle<String> identifier);
};
} // namespace internal
......
......@@ -414,9 +414,11 @@ class SpecialTimeZoneMap {
std::map<std::string, std::string> map_;
};
} // namespace
// Return the time zone id which match ICU's expectation of title casing
// return empty string when error.
std::string CanonicalizeTimeZoneID(const std::string& input) {
std::string JSDateTimeFormat::CanonicalizeTimeZoneID(const std::string& input) {
std::string upper = input;
transform(upper.begin(), upper.end(), upper.begin(),
LocaleIndependentAsciiToUpper);
......@@ -463,6 +465,7 @@ std::string CanonicalizeTimeZoneID(const std::string& input) {
return ToTitleCaseTimezoneLocation(input);
}
namespace {
Handle<String> DateTimeStyleAsString(Isolate* isolate,
JSDateTimeFormat::DateTimeStyle style) {
switch (style) {
......@@ -491,48 +494,9 @@ int FractionalSecondDigitsFromPattern(const std::string& pattern) {
} // namespace
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format) {
Handle<Object> JSDateTimeFormat::TimeZoneId(Isolate* isolate,
const icu::TimeZone& tz) {
Factory* factory = isolate->factory();
// 4. Let options be ! ObjectCreate(%ObjectPrototype%).
Handle<JSObject> options = factory->NewJSObject(isolate->object_function());
Handle<Object> resolved_obj;
Handle<String> locale = Handle<String>(date_time_format->locale(), isolate);
DCHECK(!date_time_format->icu_locale().is_null());
DCHECK_NOT_NULL(date_time_format->icu_locale().raw());
icu::Locale* icu_locale = date_time_format->icu_locale().raw();
icu::SimpleDateFormat* icu_simple_date_format =
date_time_format->icu_simple_date_format().raw();
// calendar
const icu::Calendar* calendar = icu_simple_date_format->getCalendar();
// getType() returns legacy calendar type name instead of LDML/BCP47 calendar
// key values. intl.js maps them to BCP47 values for key "ca".
// TODO(jshin): Consider doing it here, instead.
std::string calendar_str = calendar->getType();
// Maps ICU calendar names to LDML/BCP47 types for key 'ca'.
// See typeMap section in third_party/icu/source/data/misc/keyTypeData.txt
// and
// http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
if (calendar_str == "gregorian") {
if (date_time_format->alt_calendar()) {
calendar_str = "iso8601";
} else {
calendar_str = "gregory";
}
} else if (calendar_str == "ethiopic-amete-alem") {
calendar_str = "ethioaa";
} else if (calendar_str == "islamic") {
if (date_time_format->alt_calendar()) {
calendar_str = "islamic-rgsa";
}
}
const icu::TimeZone& tz = calendar->getTimeZone();
icu::UnicodeString time_zone;
tz.getID(time_zone);
UErrorCode status = U_ZERO_ERROR;
......@@ -550,14 +514,84 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) {
timezone_value = factory->UTC_string();
} else {
ASSIGN_RETURN_ON_EXCEPTION(isolate, timezone_value,
Intl::ToString(isolate, canonical_time_zone),
JSObject);
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, timezone_value, Intl::ToString(isolate, canonical_time_zone),
Handle<Object>());
}
} else {
// Somehow on Windows we will reach here.
timezone_value = factory->undefined_value();
}
return timezone_value;
}
namespace {
Handle<String> GetCalendar(Isolate* isolate,
const icu::SimpleDateFormat& simple_date_format,
bool is_alt_calendar = false) {
// getType() returns legacy calendar type name instead of LDML/BCP47 calendar
// key values. intl.js maps them to BCP47 values for key "ca".
// TODO(jshin): Consider doing it here, instead.
std::string calendar_str = simple_date_format.getCalendar()->getType();
// Maps ICU calendar names to LDML/BCP47 types for key 'ca'.
// See typeMap section in third_party/icu/source/data/misc/keyTypeData.txt
// and
// http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
if (calendar_str == "gregorian") {
if (is_alt_calendar) {
calendar_str = "iso8601";
} else {
calendar_str = "gregory";
}
} else if (calendar_str == "ethiopic-amete-alem") {
calendar_str = "ethioaa";
} else if (calendar_str == "islamic") {
if (is_alt_calendar) {
calendar_str = "islamic-rgsa";
}
}
return isolate->factory()->NewStringFromAsciiChecked(calendar_str.c_str());
}
Handle<Object> GetTimeZone(Isolate* isolate,
const icu::SimpleDateFormat& simple_date_format) {
return JSDateTimeFormat::TimeZoneId(
isolate, simple_date_format.getCalendar()->getTimeZone());
}
} // namespace
Handle<String> JSDateTimeFormat::Calendar(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format) {
return GetCalendar(isolate,
*(date_time_format->icu_simple_date_format().raw()),
date_time_format->alt_calendar());
}
Handle<Object> JSDateTimeFormat::TimeZone(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format) {
return GetTimeZone(isolate,
*(date_time_format->icu_simple_date_format().raw()));
}
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format) {
Factory* factory = isolate->factory();
// 4. Let options be ! ObjectCreate(%ObjectPrototype%).
Handle<JSObject> options = factory->NewJSObject(isolate->object_function());
Handle<Object> resolved_obj;
Handle<String> locale = Handle<String>(date_time_format->locale(), isolate);
DCHECK(!date_time_format->icu_locale().is_null());
DCHECK_NOT_NULL(date_time_format->icu_locale().raw());
icu::Locale* icu_locale = date_time_format->icu_locale().raw();
icu::SimpleDateFormat* icu_simple_date_format =
date_time_format->icu_simple_date_format().raw();
Handle<Object> timezone =
JSDateTimeFormat::TimeZone(isolate, date_time_format);
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
// to assume that for given locale NumberingSystem constructor produces the
......@@ -594,10 +628,10 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
DCHECK(maybe_create_locale.FromJust());
USE(maybe_create_locale);
Handle<String> calendar =
JSDateTimeFormat::Calendar(isolate, date_time_format);
Maybe<bool> maybe_create_calendar = JSReceiver::CreateDataProperty(
isolate, options, factory->calendar_string(),
factory->NewStringFromAsciiChecked(calendar_str.c_str()),
Just(kDontThrow));
isolate, options, factory->calendar_string(), calendar, Just(kDontThrow));
DCHECK(maybe_create_calendar.FromJust());
USE(maybe_create_calendar);
......@@ -610,8 +644,7 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
USE(maybe_create_numbering_system);
}
Maybe<bool> maybe_create_time_zone = JSReceiver::CreateDataProperty(
isolate, options, factory->timeZone_string(), timezone_value,
Just(kDontThrow));
isolate, options, factory->timeZone_string(), timezone, Just(kDontThrow));
DCHECK(maybe_create_time_zone.FromJust());
USE(maybe_create_time_zone);
......@@ -1015,20 +1048,8 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::UnwrapDateTimeFormat(
return Handle<JSDateTimeFormat>::cast(dtf);
}
namespace {
// ecma-402/#sec-isvalidtimezonename
bool IsValidTimeZoneName(const icu::TimeZone& tz) {
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString id;
tz.getID(id);
icu::UnicodeString canonical;
icu::TimeZone::getCanonicalID(id, canonical, status);
return U_SUCCESS(status) &&
canonical != icu::UnicodeString("Etc/Unknown", -1, US_INV);
}
std::unique_ptr<icu::TimeZone> CreateTimeZone(const char* timezone) {
std::unique_ptr<icu::TimeZone> JSDateTimeFormat::CreateTimeZone(
const char* timezone) {
// Create time zone as specified by the user. We have to re-create time zone
// since calendar takes ownership.
if (timezone == nullptr) {
......@@ -1041,10 +1062,12 @@ std::unique_ptr<icu::TimeZone> CreateTimeZone(const char* timezone) {
icu::TimeZone::createTimeZone(canonicalized.c_str()));
// 18.b If the result of IsValidTimeZoneName(timeZone) is false, then
// i. Throw a RangeError exception.
if (!IsValidTimeZoneName(*tz)) return std::unique_ptr<icu::TimeZone>();
if (!Intl::IsValidTimeZoneName(*tz)) return std::unique_ptr<icu::TimeZone>();
return tz;
}
namespace {
class CalendarCache {
public:
icu::Calendar* CreateCalendar(const icu::Locale& locale, icu::TimeZone* tz) {
......@@ -1654,7 +1677,8 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
isolate, options, "timeZone", empty_values, service, &timezone);
MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>());
std::unique_ptr<icu::TimeZone> tz = CreateTimeZone(timezone.get());
std::unique_ptr<icu::TimeZone> tz =
JSDateTimeFormat::CreateTimeZone(timezone.get());
if (tz.get() == nullptr) {
THROW_NEW_ERROR(
isolate,
......
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#define V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#ifndef V8_INTL_SUPPORT
#error Internationalization is expected to be enabled.
#endif // V8_INTL_SUPPORT
#ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#define V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
#include <set>
#include <string>
......@@ -25,6 +25,7 @@ namespace U_ICU_NAMESPACE {
class DateIntervalFormat;
class Locale;
class SimpleDateFormat;
class TimeZone;
} // namespace U_ICU_NAMESPACE
namespace v8 {
......@@ -42,6 +43,12 @@ class JSDateTimeFormat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
V8_WARN_UNUSED_RESULT static Handle<String> Calendar(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
V8_WARN_UNUSED_RESULT static Handle<Object> TimeZone(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
// ecma402/#sec-unwrapdatetimeformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat>
UnwrapDateTimeFormat(Isolate* isolate, Handle<JSReceiver> format_holder);
......@@ -85,6 +92,12 @@ class JSDateTimeFormat
V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();
Handle<Object> static TimeZoneId(Isolate* isolate, const icu::TimeZone& tz);
std::unique_ptr<icu::TimeZone> static CreateTimeZone(const char* timezone);
V8_EXPORT_PRIVATE static std::string CanonicalizeTimeZoneID(
const std::string& input);
Handle<String> HourCycleAsString() const;
// ecma-402/#sec-properties-of-intl-datetimeformat-instances
......
......@@ -37,23 +37,27 @@ namespace internal {
DCHECK_GE(upper, field); \
DCHECK_LE(lower, field); \
int hints = data(); \
/* Mask out unrelated bits */ \
field &= (static_cast<uint32_t>(int32_t{-1})) ^ \
(static_cast<uint32_t>(int32_t{-1}) << B##Bits::kSize); \
hints = B##Bits::update(hints, field); \
set_##data(hints); \
} \
inline int32_t T::field() const { \
int32_t v = B##Bits::decode(data()); \
/* Restore bits for negative values based on the MSB in that field */ \
v |= ((int32_t{1} << (B##Bits::kSize - 1) & v) \
? (static_cast<uint32_t>(int32_t{-1}) << B##Bits::kSize) \
: 0); \
CHECK_GE(upper, v); \
CHECK_LE(lower, v); \
DCHECK_GE(upper, v); \
DCHECK_LE(lower, v); \
return v; \
}
#define TEMPORAL_DATE_INLINE_GETTER_SETTER(T, data) \
TEMPORAL_INLINE_SIGNED_GETTER_SETTER(T, data, iso_year, -32767, 32768, \
IsoYear) \
TEMPORAL_INLINE_GETTER_SETTER(T, data, iso_month, 1, 12, IsoMonth) \
#define TEMPORAL_DATE_INLINE_GETTER_SETTER(T, data) \
TEMPORAL_INLINE_SIGNED_GETTER_SETTER(T, data, iso_year, -271821, 275760, \
IsoYear) \
TEMPORAL_INLINE_GETTER_SETTER(T, data, iso_month, 1, 12, IsoMonth) \
TEMPORAL_INLINE_GETTER_SETTER(T, data, iso_day, 1, 31, IsoDay)
#define TEMPORAL_TIME_INLINE_GETTER_SETTER(T, data1, data2) \
......@@ -91,6 +95,16 @@ BIT_FIELD_ACCESSORS(JSTemporalCalendar, flags, calendar_index,
BOOL_ACCESSORS(JSTemporalTimeZone, flags, is_offset, IsOffsetBit::kShift)
// Special handling of sign
TEMPORAL_INLINE_SIGNED_GETTER_SETTER(JSTemporalTimeZone, flags,
offset_milliseconds, -24 * 60 * 60 * 1000,
24 * 60 * 60 * 1000,
OffsetMillisecondsOrTimeZoneIndex)
TEMPORAL_INLINE_SIGNED_GETTER_SETTER(JSTemporalTimeZone, details,
offset_sub_milliseconds, -1000000, 1000000,
OffsetSubMilliseconds)
BIT_FIELD_ACCESSORS(JSTemporalTimeZone, flags,
offset_milliseconds_or_time_zone_index,
JSTemporalTimeZone::OffsetMillisecondsOrTimeZoneIndexBits)
......
This diff is collapsed.
......@@ -40,9 +40,23 @@ namespace internal {
UNIMPLEMENTED(); \
}
class JSTemporalPlainDate;
class JSTemporalPlainMonthDay;
class JSTemporalPlainYearMonth;
class JSTemporalCalendar
: public TorqueGeneratedJSTemporalCalendar<JSTemporalCalendar, JSObject> {
public:
// #sec-temporal.calendar
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalCalendar> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> identifier);
// #sec-temporal.calendar.prototype.tostring
static MaybeHandle<String> ToString(Isolate* isolate,
Handle<JSTemporalCalendar> calendar,
const char* method);
DECL_PRINTER(JSTemporalCalendar)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_CALENDAR_FLAGS()
......@@ -55,6 +69,23 @@ class JSTemporalCalendar
class JSTemporalDuration
: public TorqueGeneratedJSTemporalDuration<JSTemporalDuration, JSObject> {
public:
// #sec-temporal.duration
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalDuration> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> years,
Handle<Object> months, Handle<Object> weeks, Handle<Object> days,
Handle<Object> hours, Handle<Object> minutes, Handle<Object> seconds,
Handle<Object> milliseconds, Handle<Object> microseconds,
Handle<Object> nanoseconds);
// #sec-get-temporal.duration.prototype.sign
V8_WARN_UNUSED_RESULT static MaybeHandle<Smi> Sign(
Isolate* isolate, Handle<JSTemporalDuration> duration);
// #sec-get-temporal.duration.prototype.blank
V8_WARN_UNUSED_RESULT static MaybeHandle<Oddball> Blank(
Isolate* isolate, Handle<JSTemporalDuration> duration);
DECL_PRINTER(JSTemporalDuration)
TQ_OBJECT_CONSTRUCTORS(JSTemporalDuration)
......@@ -63,6 +94,11 @@ class JSTemporalDuration
class JSTemporalInstant
: public TorqueGeneratedJSTemporalInstant<JSTemporalInstant, JSObject> {
public:
// #sec-temporal-instant-constructor
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalInstant> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> epoch_nanoseconds);
DECL_PRINTER(JSTemporalInstant)
TQ_OBJECT_CONSTRUCTORS(JSTemporalInstant)
......@@ -71,6 +107,17 @@ class JSTemporalInstant
class JSTemporalPlainDate
: public TorqueGeneratedJSTemporalPlainDate<JSTemporalPlainDate, JSObject> {
public:
// #sec-temporal-createtemporaldate
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainDate> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> iso_year,
Handle<Object> iso_month, Handle<Object> iso_day,
Handle<Object> calendar_like);
// #sec-temporal.plaindate.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainDate> plain_date);
DECL_PRINTER(JSTemporalPlainDate)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_YEAR_MONTH_DAY()
......@@ -84,6 +131,19 @@ class JSTemporalPlainDateTime
: public TorqueGeneratedJSTemporalPlainDateTime<JSTemporalPlainDateTime,
JSObject> {
public:
// #sec-temporal-createtemporaldatetime
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainDateTime> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> iso_year,
Handle<Object> iso_month, Handle<Object> iso_day, Handle<Object> hour,
Handle<Object> minute, Handle<Object> second, Handle<Object> millisecond,
Handle<Object> microsecond, Handle<Object> nanosecond,
Handle<Object> calendar_like);
// #sec-temporal.plaindatetime.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainDateTime> date_time);
DECL_PRINTER(JSTemporalPlainDateTime)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_YEAR_MONTH_DAY()
......@@ -100,6 +160,17 @@ class JSTemporalPlainMonthDay
: public TorqueGeneratedJSTemporalPlainMonthDay<JSTemporalPlainMonthDay,
JSObject> {
public:
// ##sec-temporal.plainmonthday
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainMonthDay> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> iso_month,
Handle<Object> iso_day, Handle<Object> calendar_like,
Handle<Object> reference_iso_year);
// #sec-temporal.plainmonthday.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainMonthDay> month_day);
DECL_PRINTER(JSTemporalPlainMonthDay)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_YEAR_MONTH_DAY()
......@@ -112,6 +183,17 @@ class JSTemporalPlainMonthDay
class JSTemporalPlainTime
: public TorqueGeneratedJSTemporalPlainTime<JSTemporalPlainTime, JSObject> {
public:
// #sec-temporal-plaintime-constructor
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainTime> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> hour, Handle<Object> minute,
Handle<Object> second, Handle<Object> millisecond,
Handle<Object> microsecond, Handle<Object> nanosecond);
// #sec-temporal.plaintime.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainTime> plain_time);
DECL_PRINTER(JSTemporalPlainTime)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_HOUR_MINUTE_SECOND()
......@@ -126,6 +208,19 @@ class JSTemporalPlainYearMonth
: public TorqueGeneratedJSTemporalPlainYearMonth<JSTemporalPlainYearMonth,
JSObject> {
public:
// ##sec-temporal.plainyearmonth
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainYearMonth>
Constructor(Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> iso_year,
Handle<Object> iso_month, Handle<Object> calendar_like,
Handle<Object> reference_iso_day);
// #sec-temporal.plainyearmonth.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month);
// Abstract Operations
DECL_PRINTER(JSTemporalPlainYearMonth)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_YEAR_MONTH_DAY()
......@@ -138,13 +233,33 @@ class JSTemporalPlainYearMonth
class JSTemporalTimeZone
: public TorqueGeneratedJSTemporalTimeZone<JSTemporalTimeZone, JSObject> {
public:
// #sec-temporal.timezone
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalTimeZone> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> identifier);
// #sec-temporal.timezone.prototype.tostring
static MaybeHandle<Object> ToString(Isolate* isolate,
Handle<JSTemporalTimeZone> time_zone,
const char* method);
DECL_PRINTER(JSTemporalTimeZone)
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_TIME_ZONE_FLAGS()
DEFINE_TORQUE_GENERATED_JS_TEMPORAL_TIME_ZONE_SUB_MILLISECONDS()
DECL_BOOLEAN_ACCESSORS(is_offset)
DECL_INT_ACCESSORS(offset_milliseconds_or_time_zone_index)
DECLARE_TEMPORAL_INLINE_GETTER_SETTER(offset_milliseconds)
DECLARE_TEMPORAL_INLINE_GETTER_SETTER(offset_sub_milliseconds)
int32_t time_zone_index() const;
int64_t offset_nanoseconds() const;
void set_offset_nanoseconds(int64_t offset_nanoseconds);
MaybeHandle<String> id(Isolate* isolate) const;
TQ_OBJECT_CONSTRUCTORS(JSTemporalTimeZone)
};
......@@ -152,11 +267,28 @@ class JSTemporalZonedDateTime
: public TorqueGeneratedJSTemporalZonedDateTime<JSTemporalZonedDateTime,
JSObject> {
public:
// #sec-temporal.zoneddatetime
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalZonedDateTime> Constructor(
Isolate* isolate, Handle<JSFunction> target,
Handle<HeapObject> new_target, Handle<Object> epoch_nanoseconds,
Handle<Object> time_zone_like, Handle<Object> calendar_like);
// #sec-temporal.zoneddatetime.prototype.getisofields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalZonedDateTime> zoned_date_time);
DECL_PRINTER(JSTemporalZonedDateTime)
TQ_OBJECT_CONSTRUCTORS(JSTemporalZonedDateTime)
};
namespace temporal {
// #sec-temporal-getiso8601calendar
V8_WARN_UNUSED_RESULT MaybeHandle<JSTemporalCalendar> GetISO8601Calendar(
Isolate* isolate);
} // namespace temporal
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
......
......@@ -9,7 +9,7 @@ bitfield struct JSTemporalCalendarFlags extends uint31 {
}
bitfield struct JSTemporalYearMonthDay extends uint31 {
iso_year: int32: 16 bit;
iso_year: int32: 20 bit;
iso_month: int32: 4 bit;
iso_day: int32: 5 bit;
}
......@@ -30,6 +30,9 @@ bitfield struct JSTemporalTimeZoneFlags extends uint31 {
is_offset: bool: 1 bit;
offset_milliseconds_or_time_zone_index: int32: 28 bit;
}
bitfield struct JSTemporalTimeZoneSubMilliseconds extends uint31 {
offset_sub_milliseconds: int32: 21 bit;
}
extern class JSTemporalCalendar extends JSObject {
flags: SmiTagged<JSTemporalCalendarFlags>;
......@@ -80,6 +83,7 @@ extern class JSTemporalPlainYearMonth extends JSObject {
extern class JSTemporalTimeZone extends JSObject {
flags: SmiTagged<JSTemporalTimeZoneFlags>;
details: SmiTagged<JSTemporalTimeZoneSubMilliseconds>;
}
extern class JSTemporalZonedDateTime extends JSObject {
......
......@@ -1187,20 +1187,22 @@ SATISIFY(TemporalDurationString, ParsedISO8601Duration)
} // namespace
#define IMPL_PARSE_METHOD(R, NAME) \
Maybe<R> TemporalParser::Parse##NAME( \
Isolate* isolate, Handle<String> iso_string, bool* valid) { \
Maybe<R> TemporalParser::Parse##NAME(Isolate* isolate, \
Handle<String> iso_string) { \
bool valid; \
R parsed; \
iso_string = String::Flatten(isolate, iso_string); \
{ \
DisallowGarbageCollection no_gc; \
String::FlatContent str_content = iso_string->GetFlatContent(no_gc); \
if (str_content.IsOneByte()) { \
*valid = Satisfy##NAME(str_content.ToOneByteVector(), &parsed); \
valid = Satisfy##NAME(str_content.ToOneByteVector(), &parsed); \
} else { \
*valid = Satisfy##NAME(str_content.ToUC16Vector(), &parsed); \
valid = Satisfy##NAME(str_content.ToUC16Vector(), &parsed); \
} \
} \
return Just(parsed); \
if (valid) return Just(parsed); \
return Nothing<R>(); \
}
IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalDateTimeString)
......
......@@ -123,9 +123,9 @@ struct ParsedISO8601Duration {
*/
class V8_EXPORT_PRIVATE TemporalParser {
public:
#define DEFINE_PARSE_METHOD(R, NAME) \
V8_WARN_UNUSED_RESULT static Maybe<R> Parse##NAME( \
Isolate* isolate, Handle<String> iso_string, bool* satisfy)
#define DEFINE_PARSE_METHOD(R, NAME) \
V8_WARN_UNUSED_RESULT static Maybe<R> Parse##NAME(Isolate* isolate, \
Handle<String> iso_string)
DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalDateString);
DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalDateTimeString);
DEFINE_PARSE_METHOD(ParsedISO8601Result, TemporalTimeString);
......
......@@ -83,7 +83,7 @@ bytecodes: [
/* 48 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(286),
B(Wide), B(LdaSmi), I16(289),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -115,7 +115,7 @@ bytecodes: [
/* 41 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(285),
B(Wide), B(LdaSmi), I16(288),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -147,7 +147,7 @@ bytecodes: [
/* 48 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(286),
B(Wide), B(LdaSmi), I16(289),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -179,7 +179,7 @@ bytecodes: [
/* 41 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(285),
B(Wide), B(LdaSmi), I16(288),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......
......@@ -56,7 +56,7 @@ bytecodes: [
/* 44 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(284),
B(Wide), B(LdaSmi), I16(287),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -89,7 +89,7 @@ bytecodes: [
/* 44 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(284),
B(Wide), B(LdaSmi), I16(287),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......
......@@ -24,7 +24,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -59,13 +59,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(284),
B(Wide), B(LdaSmi), I16(287),
B(Star3),
B(LdaConstant), U8(1),
B(Star4),
......@@ -97,13 +97,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(284),
B(Wide), B(LdaSmi), I16(287),
B(Star3),
B(LdaConstant), U8(1),
B(Star4),
......@@ -143,7 +143,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -165,7 +165,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
......@@ -180,7 +180,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -214,13 +214,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(286),
B(Wide), B(LdaSmi), I16(289),
B(Star3),
B(LdaConstant), U8(1),
B(Star4),
......@@ -251,13 +251,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 58 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(285),
B(Wide), B(LdaSmi), I16(288),
B(Star3),
B(LdaConstant), U8(1),
B(Star4),
......@@ -288,13 +288,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(278),
B(Wide), B(LdaSmi), I16(281),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(286),
B(Wide), B(LdaSmi), I16(289),
B(Star3),
B(LdaConstant), U8(1),
B(Star4),
......@@ -323,7 +323,7 @@ bytecode array length: 19
bytecodes: [
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(LdaKeyedProperty), R(this), U8(0),
B(Wide), B(LdaSmi), I16(285),
B(Wide), B(LdaSmi), I16(288),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
......
This diff is collapsed.
......@@ -43,11 +43,109 @@
##############################################################################
# Temporal tests to be implemented
# https://crbug.com/v8/11544
'temporal/plain*': [FAIL],
'temporal/duration*': [FAIL],
'temporal/calendar*': [FAIL],
'temporal/zoned*': [FAIL],
'temporal/instant*': [FAIL],
'temporal/calendar-date-add': [FAIL],
'temporal/calendar-date-from-fields': [FAIL],
'temporal/calendar-date-until': [FAIL],
'temporal/calendar-day': [FAIL],
'temporal/calendar-day-of-week': [FAIL],
'temporal/calendar-day-of-year': [FAIL],
'temporal/calendar-days-in-month': [FAIL],
'temporal/calendar-days-in-week': [FAIL],
'temporal/calendar-days-in-year': [FAIL],
'temporal/calendar-fields': [FAIL],
'temporal/calendar-from': [FAIL],
'temporal/calendar-in-leap-year': [FAIL],
'temporal/calendar-merge-fields': [FAIL],
'temporal/calendar-month': [FAIL],
'temporal/calendar-month-code': [FAIL],
'temporal/calendar-month-day-from-fields': [FAIL],
'temporal/calendar-months-in-year': [FAIL],
'temporal/calendar-week-of-year': [FAIL],
'temporal/calendar-year': [FAIL],
'temporal/calendar-year-month-from-fields': [FAIL],
'temporal/duration-abs': [FAIL],
'temporal/duration-add': [FAIL],
'temporal/duration-from': [FAIL],
'temporal/duration-negated': [FAIL],
'temporal/duration-to-json': [FAIL],
'temporal/duration-valueOf': [FAIL],
'temporal/duration-with': [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],
'temporal/instant-from-epoch-seconds': [FAIL],
'temporal/instant-subtract': [FAIL],
'temporal/instant-to-json': [FAIL],
'temporal/instant-toJSON': [FAIL],
'temporal/instant-valueOf': [FAIL],
'temporal/plain-date-add': [FAIL],
'temporal/plain-date-compare': [FAIL],
'temporal/plain-date-equals': [FAIL],
'temporal/plain-date-from': [FAIL],
'temporal/plain-date-get-calendar': [FAIL],
'temporal/plain-date-get-day': [FAIL],
'temporal/plain-date-get-dayOfWeek': [FAIL],
'temporal/plain-date-get-dayOfYear': [FAIL],
'temporal/plain-date-get-daysInMonth': [FAIL],
'temporal/plain-date-get-daysInWeek': [FAIL],
'temporal/plain-date-get-daysInYear': [FAIL],
'temporal/plain-date-get-era': [FAIL],
'temporal/plain-date-get-eraYear': [FAIL],
'temporal/plain-date-get-inLeapYear': [FAIL],
'temporal/plain-date-get-month': [FAIL],
'temporal/plain-date-get-monthCode': [FAIL],
'temporal/plain-date-get-monthsInYear': [FAIL],
'temporal/plain-date-get-weekOfYear': [FAIL],
'temporal/plain-date-get-year': [FAIL],
'temporal/plain-date-time-add': [FAIL],
'temporal/plain-date-time-compare': [FAIL],
'temporal/plain-date-time-constructor': [FAIL],
'temporal/plain-date-time-equals': [FAIL],
'temporal/plain-date-time-from': [FAIL],
'temporal/plain-date-time-get-calendar': [FAIL],
'temporal/plain-date-time-get-day': [FAIL],
'temporal/plain-date-time-get-dayOfWeek': [FAIL],
'temporal/plain-date-time-get-dayOfYear': [FAIL],
'temporal/plain-date-time-get-daysInMonth': [FAIL],
'temporal/plain-date-time-get-daysInWeek': [FAIL],
'temporal/plain-date-time-get-daysInYear': [FAIL],
'temporal/plain-date-time-get-era': [FAIL],
'temporal/plain-date-time-get-eraYear': [FAIL],
'temporal/plain-date-time-get-hour': [FAIL],
'temporal/plain-date-time-get-inLeapYear': [FAIL],
'temporal/plain-date-time-get-iso-fields': [FAIL],
'temporal/plain-date-time-get-microsecond': [FAIL],
'temporal/plain-date-time-get-millisecond': [FAIL],
'temporal/plain-date-time-get-minute': [FAIL],
'temporal/plain-date-time-get-month': [FAIL],
'temporal/plain-date-time-get-monthCode': [FAIL],
'temporal/plain-date-time-get-monthsInYear': [FAIL],
'temporal/plain-date-time-get-nanosecond': [FAIL],
'temporal/plain-date-time-get-second': [FAIL],
'temporal/plain-date-time-get-weekOfYear': [FAIL],
'temporal/plain-date-time-get-year': [FAIL],
'temporal/plain-date-time-subtract': [FAIL],
'temporal/plain-date-time-to-json': [FAIL],
'temporal/plain-date-time-to-plain-date': [FAIL],
'temporal/plain-date-time-to-plain-month-day': [FAIL],
'temporal/plain-date-time-to-plain-time': [FAIL],
'temporal/plain-date-time-to-plain-year-month': [FAIL],
'temporal/plain-date-time-valueOf': [FAIL],
'temporal/plain-date-time-with': [FAIL],
'temporal/plain-date-time-with-calendar': [FAIL],
'temporal/plain-date-time-with-plain-date': [FAIL],
'temporal/plain-date-time-with-plain-time': [FAIL],
'temporal/plain-date-to-json': [FAIL],
'temporal/plain-date-to-plain-date-time': [FAIL],
'temporal/plain-date-to-plain-month-day': [FAIL],
'temporal/plain-date-to-plain-year-month': [FAIL],
'temporal/plain-date-valueOf': [FAIL],
'temporal/plain-date-with': [FAIL],
'temporal/plain-date-with-calendar': [FAIL],
##############################################################################
# Open bugs.
......
......@@ -6,14 +6,11 @@
// https://tc39.es/proposal-temporal/#sec-temporal.calendar
// 1. If NewTarget is undefined, then
// a. Throw a TypeError exception.
assertThrows(() => Temporal.Calendar("iso8601"), TypeError,
"Constructor Temporal.Calendar requires 'new'");
assertThrows(() => Temporal.Calendar("iso8601"), TypeError);
assertThrows(() => new Temporal.Calendar(), RangeError,
"Invalid calendar specified: undefined");
assertThrows(() => new Temporal.Calendar(), RangeError);
// Wrong case
assertThrows(() => new Temporal.Calendar("ISO8601"), RangeError,
"Invalid calendar specified: ISO8601");
assertThrows(() => new Temporal.Calendar("ISO8601"), RangeError);
assertEquals("iso8601", (new Temporal.Calendar("iso8601")).id)
......@@ -8,110 +8,100 @@ let cal = new Temporal.Calendar("iso8601")
// Check throw for first arg
assertThrows(() => cal.dateFromFields(),
TypeError,
"Temporal.Calendar.prototype.dateFromFields called on non-object");
TypeError);
[undefined, true, false, 123, 456n, Symbol(), "string",
123.456, NaN, null].forEach(
function(fields) {
assertThrows(() => cal.dateFromFields(fields), TypeError,
"Temporal.Calendar.prototype.dateFromFields called on non-object");
assertThrows(() => cal.dateFromFields(fields, undefined), TypeError,
"Temporal.Calendar.prototype.dateFromFields called on non-object");
assertThrows(() => cal.dateFromFields(fields), TypeError);
assertThrows(() => cal.dateFromFields(fields, undefined), TypeError);
assertThrows(() => cal.dateFromFields(fields, {overflow: "constrain"}),
TypeError,
"Temporal.Calendar.prototype.dateFromFields called on non-object");
TypeError);
assertThrows(() => cal.dateFromFields(fields, {overflow: "reject"}),
TypeError,
"Temporal.Calendar.prototype.dateFromFields called on non-object");
TypeError);
});
assertThrows(() => cal.dateFromFields({month: 1, day: 17}),
TypeError, "invalid_argument");
assertThrows(() => cal.dateFromFields({year: 2021, day: 17}),
TypeError, "invalid_argument");
assertThrows(() => cal.dateFromFields({year: 2021, month: 12}),
TypeError, "invalid_argument");
assertThrows(() => cal.dateFromFields({month: 1, day: 17}), TypeError);
assertThrows(() => cal.dateFromFields({year: 2021, day: 17}), TypeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 12}), TypeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "m1", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "M1", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "m01", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 12, monthCode: "M11",
day: 17}), RangeError, "monthCode value is out of range.");
day: 17}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "M00", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "M19", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "M99", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, monthCode: "M13", day: 17}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: -1, day: 17}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: -Infinity, day: 17}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 7, day: -17}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 7, day: -Infinity}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 12, day: 0},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 12, day: 32},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 1, day: 32},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 2, day: 29},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 6, day: 31},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 9, day: 31},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 0, day: 5},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields({year: 2021, month: 13, day: 5},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M12", day: 0}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M12", day: 32}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M01", day: 32}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M02", day: 29}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M06", day: 31}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M09", day: 31}, {overflow: "reject"}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M00", day: 5}, {overflow: "reject"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, monthCode: "M13", day: 5}, {overflow: "reject"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 12, day: 0}), RangeError, "Invalid time value");
{year: 2021, month: 12, day: 0}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 0, day: 3}), RangeError, "Invalid time value");
{year: 2021, month: 0, day: 3}), RangeError);
// Check throw for the second arg
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 7, day: 13}, {overflow: "invalid"}),
RangeError,
"Value invalid out of range for Temporal.Calendar.prototype.dateFromFields"
+ " options property overflow");
RangeError);
assertEquals("2021-07-15",
cal.dateFromFields({year: 2021, month: 7, day: 15}).toJSON());
......@@ -180,41 +170,28 @@ assertEquals("2021-12-31",
cal.dateFromFields({year: 2021, monthCode: "M12", day: 500}).toJSON());
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 1, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 1, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 2, day: 29}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 2, day: 29}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 3, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 3, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 4, day: 31}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 4, day: 31}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 5, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 5, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 6, day: 31}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 6, day: 31}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 7, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 7, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 8, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 8, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 9, day: 31}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 9, day: 31}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 10, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 10, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 11, day: 31}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 11, day: 31}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 12, day: 32}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 12, day: 32}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.dateFromFields(
{year: 2021, month: 13, day: 5}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 13, day: 5}, {overflow: "reject"}), RangeError);
......@@ -10,9 +10,7 @@ let cal = new Temporal.Calendar("iso8601");
[ "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" ]
.forEach(function(largestUnit) {
assertThrows(() => cal.dateUntil("2021-07-16", "2021-07-17",
{largestUnit}), RangeError,
"Invalid unit argument for Temporal.Calendar.prototype.dateUntil() "+
"'largestUnit'");
{largestUnit}), RangeError);
});
assertEquals("PT0S", cal.dateUntil("2021-07-16", "2021-07-16").toJSON());
......
......@@ -8,16 +8,51 @@ let cal = new Temporal.Calendar("iso8601")
assertEquals("iso8601", cal.id)
const fields = {
let i = 1;
const repeated = {
*[Symbol.iterator]() {
let i = 0;
while (i++ < 1000) {
yield "year";
}
yield "year";
i++;
yield "year";
i++;
}
}
let expected = Array.from(fields);
// For now, we only input it as array
let inpiut = expected;
assertArrayEquals(expected, cal.fields(expected));
assertThrows(() => cal.fields(repeated), RangeError);
assertEquals(2, i);
let repeatedArray = Array.from(repeated);
assertThrows(() => cal.fields(repeatedArray), RangeError);
const week = {
*[Symbol.iterator]() {
yield "week";
}
}
assertThrows(() => cal.fields(week), RangeError);
assertThrows(() => cal.fields(['week']), RangeError);
assertThrows(() => cal.fields(new Set(['week'])), RangeError);
const allValid = {
*[Symbol.iterator]() {
yield "nanosecond";
yield "microsecond";
yield "millisecond";
yield "second";
yield "minute";
yield "hour";
yield "day";
yield "monthCode";
yield "month";
yield "year";
}
}
let allValidArray = Array.from(allValid);
let allValidSet = new Set(allValid);
assertArrayEquals(allValidArray, cal.fields(allValid));
assertArrayEquals(allValidArray, cal.fields(allValidArray));
assertArrayEquals(allValidArray, cal.fields(allValidSet));
// cannot just return the same array
assertTrue(allValidArray != cal.fields(allValidArray));
......@@ -6,8 +6,6 @@
// https://tc39.es/proposal-temporal/#sec-temporal.calendar.from
// 1. If NewTarget is undefined, then
// a. Throw a TypeError exception.
//assertThrows(() => Temporal.Calendar.from("invalid"), TypeError,
// "Constructor Temporal.Calendar requires 'new'");
assertEquals("iso8601",
(Temporal.Calendar.from("iso8601")).id);
......
......@@ -7,16 +7,11 @@
let cal = new Temporal.Calendar("iso8601")
// Test throwing
assertThrows(() => cal.mergeFields(), TypeError,
"Cannot convert undefined or null to object");
assertThrows(() => cal.mergeFields(undefined, {}), TypeError,
"Cannot convert undefined or null to object");
assertThrows(() => cal.mergeFields(null, {}), TypeError,
"Cannot convert undefined or null to object");
assertThrows(() => cal.mergeFields({}, undefined), TypeError,
"Cannot convert undefined or null to object");
assertThrows(() => cal.mergeFields({}, null), TypeError,
"Cannot convert undefined or null to object");
assertThrows(() => cal.mergeFields(), TypeError);
assertThrows(() => cal.mergeFields(undefined, {}), TypeError);
assertThrows(() => cal.mergeFields(null, {}), TypeError);
assertThrows(() => cal.mergeFields({}, undefined), TypeError);
assertThrows(() => cal.mergeFields({}, null), TypeError);
// Test String, number, true, false, NaN, BigInt, Symbol types
// pending on https://github.com/tc39/proposal-temporal/issues/1647
......
......@@ -10,8 +10,7 @@ assertEquals(7, cal.month(new Temporal.PlainDate(2021, 7, 15)));
assertEquals(8, cal.month(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)));
assertEquals(6, cal.month(new Temporal.PlainYearMonth(1999, 6)));
assertEquals(3, cal.month("2019-03-15"));
assertThrows(() => cal.month(new Temporal.PlainMonthDay(3, 16)), TypeError,
"invalid_argument");
assertThrows(() => cal.month(new Temporal.PlainMonthDay(3, 16)), TypeError);
// TODO Test the following later.
//assertEquals(1, cal.month(new Temporal.ZonedDateTime(86400n * 366n * 50n,
......
......@@ -6,73 +6,61 @@
// https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.yearmonthfromfields
let cal = new Temporal.Calendar("iso8601")
let nonObjMsg =
"Temporal.Calendar.prototype.yearMonthFromFields called on non-object");
// Check throw for first arg
assertThrows(() => cal.yearMonthFromFields(),
TypeError, nonObjMsg);
TypeError);
[undefined, true, false, 123, 456n, Symbol(), "string"].forEach(
function(fields) {
assertThrows(() => cal.yearMonthFromFields(fields), TypeError, nonObjMsg);
assertThrows(() => cal.yearMonthFromFields(fields, undefined),
TypeError, nonObjMsg);
assertThrows(() => cal.yearMonthFromFields(fields), TypeError);
assertThrows(() => cal.yearMonthFromFields(fields, undefined), TypeError);
assertThrows(() => cal.yearMonthFromFields(fields,
{overflow: "constrain"}), TypeError, nonObjMsg);
{overflow: "constrain"}), TypeError);
assertThrows(() => cal.yearMonthFromFields(fields,
{overflow: "reject"}), TypeError, nonObjMsg);
{overflow: "reject"}), TypeError);
});
assertThrows(() => cal.yearMonthFromFields({month: 1}),
TypeError, "invalid_argument");
assertThrows(() => cal.yearMonthFromFields({year: 2021}),
TypeError, "invalid_argument");
assertThrows(() => cal.yearMonthFromFields({month: 1}), TypeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021}), TypeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "m1"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "M1"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "m01"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, month: 12,
monthCode: "M11"}),
RangeError, "monthCode value is out of range.");
monthCode: "M11"}), RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "M00"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "M19"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "M99"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, monthCode: "M13"}),
RangeError, "monthCode value is out of range.");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, month: -1}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, month: -Infinity}),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, month: 0, day: 5},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.yearMonthFromFields({year: 2021, month: 13, day: 5},
{overflow: "reject"}), RangeError, "Invalid time value");
{overflow: "reject"}), RangeError);
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, monthCode: "M00"}, {overflow: "reject"}),
RangeError, "monthCode value is out of range.");
{year: 2021, monthCode: "M00"}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, monthCode: "M13"}, {overflow: "reject"}),
RangeError, "monthCode value is out of range.");
{year: 2021, monthCode: "M13"}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, month: 0}), RangeError, "Invalid time value");
{year: 2021, month: 0}), RangeError);
// Check throw for the second arg
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, month: 7}, {overflow: "invalid"}),
RangeError,
"Value invalid out of range for " +
"Temporal.Calendar.prototype.yearMonthFromFields options property " +
"overflow");
{year: 2021, month: 7}, {overflow: "invalid"}), RangeError);
assertEquals("2021-07",
cal.yearMonthFromFields({year: 2021, month: 7}).toJSON());
......@@ -137,8 +125,6 @@ assertEquals("2021-12",
cal.yearMonthFromFields({year: 2021, monthCode: "M12"}).toJSON());
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, month: 13}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 13}, {overflow: "reject"}), RangeError);
assertThrows(() => cal.yearMonthFromFields(
{year: 2021, month: 9995}, {overflow: "reject"}), RangeError,
"Invalid time value");
{year: 2021, month: 9995}, {overflow: "reject"}), RangeError);
......@@ -12,8 +12,10 @@ let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertDuration(d2.abs(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, false);
// Test large number
let d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(d3.abs(), 1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
let d3 = new Temporal.Duration(
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(d3.abs(),
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
// Test negative values
let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
......
......@@ -7,34 +7,44 @@ d8.file.execute('test/mjsunit/temporal/temporal-helpers.js');
let d1 = new Temporal.Duration();
let badDur = {add: d1.add};
assertThrows(() => badDur.add(d1), TypeError,
"Method Temporal.Duration.prototype.add called on incompatible receiver #<Object>");
assertThrows(() => badDur.add(d1), TypeError);
let relativeToOptions = {relativeTo: "2021-08-01"};
let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertThrows(() => d2.add(d1), RangeError, "Invalid time value");
assertThrows(() => d1.add(d2), RangeError, "Invalid time value");
assertThrows(() => d2.add(d2), RangeError, "Invalid time value");
assertDuration(d2.add(d1, relativeToOptions), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, false);
assertDuration(d1.add(d2, relativeToOptions), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, false);
assertDuration(d1.add(d1, relativeToOptions), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
assertDuration(d2.add(d2, relativeToOptions), 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, false);
assertThrows(() => d2.add(d1), RangeError);
assertThrows(() => d1.add(d2), RangeError);
assertThrows(() => d2.add(d2), RangeError);
assertDuration(d2.add(d1, relativeToOptions),
1, 2, 0, 25, 5, 6, 7, 8, 9, 10, 1, false);
assertDuration(d1.add(d2, relativeToOptions),
1, 2, 0, 25, 5, 6, 7, 8, 9, 10, 1, false);
assertDuration(d1.add(d1, relativeToOptions),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
assertDuration(d2.add(d2, relativeToOptions),
2, 5, 0, 19, 10, 12, 14, 16, 18, 20, 1, false);
// Test large number
let d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertThrows(() => d3.add(d3), RangeError, "Invalid time value");
assertDuration(d3.add(d3, relativeToOptions), 2e5, 4e5, 6e5, 8e5, 1e6, 12e5, 14e5, 16e5, 18e5, 2e6, 1, false);
let d3 = new Temporal.Duration(
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertThrows(() => d3.add(d3), RangeError);
//assertDuration(d3.add(d3, relativeToOptions),
// 2e5, 4e5, 6e5, 8e5, 1e6, 12e5, 14e5, 16e5, 18e5, 2e6, 1, false);
// Test negative values
let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
assertThrows(() => d4.add(d0), RangeError, "Invalid time value");
assertThrows(() => d0.add(d4), RangeError, "Invalid time value");
assertThrows(() => d4.add(d4), RangeError, "Invalid time value");
assertThrows(() => d2.add(d4), RangeError, "Invalid time value");
assertThrows(() => d4.add(d2), RangeError, "Invalid time value");
assertDuration(d4.add(d0, relativeToOptions), -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
assertDuration(d0.add(d4, relativeToOptions), -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
assertDuration(d4.add(d4, relativeToOptions), -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -1, false);
assertDuration(d2.add(d4, relativeToOptions), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
assertDuration(d4.add(d2, relativeToOptions), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
assertThrows(() => d4.add(d1), RangeError);
assertThrows(() => d1.add(d4), RangeError);
assertThrows(() => d4.add(d4), RangeError);
assertThrows(() => d2.add(d4), RangeError);
assertThrows(() => d4.add(d2), RangeError);
assertDuration(d4.add(d1, relativeToOptions),
-1, -2, 0, -25, -5, -6, -7, -8, -9, -10, -1, false);
assertDuration(d1.add(d4, relativeToOptions),
-1, -2, 0, -25, -5, -6, -7, -8, -9, -10, -1, false);
assertDuration(d4.add(d4, relativeToOptions),
-2, -5, 0, -19, -10, -12, -14, -16, -18, -20, -1, false);
assertDuration(d2.add(d4, relativeToOptions),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
assertDuration(d4.add(d2, relativeToOptions),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
......@@ -12,82 +12,70 @@ let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertDuration(d2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, false);
// Test large number
let d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(d3, 1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
let d3 = new Temporal.Duration(
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(
d3, 1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
// Test negative values
let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
assertDuration(d4, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
let d4 = new Temporal.Duration(
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
assertDuration(
d4, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
// Test NaN
let d5 = new Temporal.Duration(NaN, NaN, NaN);
assertDuration(d5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
// 1. If NewTarget is undefined, then
// a. Throw a TypeError exception.
assertThrows(() => Temporal.Duration(), TypeError,
"Method invoked on an object that is not Temporal.Duration.");
assertThrows(() => Temporal.Duration(), TypeError);
// 1. Let number be ? ToNumber(argument).
assertDuration(new Temporal.Duration(undefined, 234, true, false, "567"),
0, 234, 1, 0, 567, 0, 0, 0, 0, 0, 1, false);
assertThrows(() => new Temporal.Duration(Symbol(123)), TypeError,
"Cannot convert a Symbol value to a number");
assertThrows(() => new Temporal.Duration(123n), TypeError,
"Cannot convert a BigInt value to a number");
assertThrows(() => new Temporal.Duration(Symbol(123)), TypeError);
assertThrows(() => new Temporal.Duration(123n), TypeError);
// Test Infinity
// 7.5.4 IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
// milliseconds, microseconds, nanoseconds )
// a. If v is not finite, return false.
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, 6, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, 2, 3, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, 2, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, 5, Infinity), RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, 4, Infinity), RangeError);
assertThrows(() => new Temporal.Duration(1, 2, 3, Infinity), RangeError);
assertThrows(() => new Temporal.Duration(1, 2, Infinity), RangeError);
assertThrows(() => new Temporal.Duration(1, Infinity), RangeError);
assertThrows(() => new Temporal.Duration(Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9,
-Infinity), RangeError, "Invalid time value");
-Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8,
-Infinity), RangeError, "Invalid time value");
-Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7,
-Infinity), RangeError, "Invalid time value");
-Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -5, -6, -Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -5, -Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -4, -Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(-1, -2, -3, -Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(-1, -2, -Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(-1, -Infinity),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(-Infinity),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -3, -Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -2, -Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-1, -Infinity), RangeError);
assertThrows(() => new Temporal.Duration(-Infinity), RangeError);
// Sign different
assertThrows(() => new Temporal.Duration(1, -2),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, 0, -2),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(-1, 0, 0, 3),
RangeError, "Invalid time value");
assertThrows(() => new Temporal.Duration(1, -2), RangeError);
assertThrows(() => new Temporal.Duration(1, 0, -2), RangeError);
assertThrows(() => new Temporal.Duration(-1, 0, 0, 3), RangeError);
assertThrows(() => new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 1, -1),
RangeError, "Invalid time value");
RangeError);
assertThrows(() => new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, -1, 1),
RangeError, "Invalid time value");
RangeError);
......@@ -163,50 +163,28 @@ assertDuration(Temporal.Duration.from("PT3,001M"),
assertDuration(Temporal.Duration.from("PT3,006M"),
0, 0, 0, 0, 0, 3, 0, 360, 0, 0, 1, false);
assertThrows(() => Temporal.Duration.from("P2H"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("P2.5M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("P2,5M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("P2S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2.H3M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2,H3M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2.H3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2,H3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2.H0.5M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2,H0,5M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2.H0.5S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2,H0,5S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2H3.2M3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2H3,2M3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2H3.2M0.3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT2H3,2M0,3S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT.1H"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT,1H"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT.1M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT,1M"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT.1S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("PT,1S"), RangeError,
"Invalid time value");
assertThrows(() => Temporal.Duration.from("P2H"), RangeError);
assertThrows(() => Temporal.Duration.from("P2.5M"), RangeError);
assertThrows(() => Temporal.Duration.from("P2,5M"), RangeError);
assertThrows(() => Temporal.Duration.from("P2S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2.H3M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2,H3M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2.H3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2,H3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2.H0.5M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2,H0,5M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2.H0.5S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2,H0,5S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2H3.2M3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2H3,2M3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2H3.2M0.3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT2H3,2M0,3S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT.1H"), RangeError);
assertThrows(() => Temporal.Duration.from("PT,1H"), RangeError);
assertThrows(() => Temporal.Duration.from("PT.1M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT,1M"), RangeError);
assertThrows(() => Temporal.Duration.from("PT.1S"), RangeError);
assertThrows(() => Temporal.Duration.from("PT,1S"), RangeError);
assertDuration(Temporal.Duration.from(
{years: 0, months: 0, weeks: 0, days: 0,
......
......@@ -12,13 +12,17 @@ let d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertDuration(d2.negated(), -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
// Test large number
let d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(d3.negated(), -1e5, -2e5, -3e5, -4e5, -5e5, -6e5, -7e5, -8e5, -9e5, -10e5, -1, false);
let d3 = new Temporal.Duration(
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
assertDuration(d3.negated(),
-1e5, -2e5, -3e5, -4e5, -5e5, -6e5, -7e5, -8e5, -9e5, -10e5, -1, false);
// Test negative values
let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
assertDuration(d4.negated(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, false);
let d5 = new Temporal.Duration(-1e5, -2e5, -3e5, -4e5, -5e5, -6e5, -7e5, -8e5, -9e5, -10e5);
assertDuration(d5.negated(), 1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
let d5 = new Temporal.Duration(
-1e5, -2e5, -3e5, -4e5, -5e5, -6e5, -7e5, -8e5, -9e5, -10e5);
assertDuration(d5.negated(),
1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5, 1, false);
......@@ -4,5 +4,4 @@
// Flags: --harmony-temporal
let d1 = new Temporal.Duration();
assertThrows(() => d1.valueOf(), TypeError,
"Method Temporal.Duration called on a non-object or on a wrong type of object.");
assertThrows(() => d1.valueOf(), TypeError);
......@@ -32,26 +32,16 @@ assertDuration(d2.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 1, false);
assertDuration(d2.with(like7), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10, -1,
false);
// Different sign
assertThrows(() => d2.with({years: -1}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({months: -2}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({weeks: -3}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({days: -4}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({hours: -5}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({minutes: -6}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({seconds: -7}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({milliseconds: -8}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({microseconds: -9}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({nanoseconds: -10}), RangeError,
"Invalid time value");
assertThrows(() => d2.with({years: -1}), RangeError);
assertThrows(() => d2.with({months: -2}), RangeError);
assertThrows(() => d2.with({weeks: -3}), RangeError);
assertThrows(() => d2.with({days: -4}), RangeError);
assertThrows(() => d2.with({hours: -5}), RangeError);
assertThrows(() => d2.with({minutes: -6}), RangeError);
assertThrows(() => d2.with({seconds: -7}), RangeError);
assertThrows(() => d2.with({milliseconds: -8}), RangeError);
assertThrows(() => d2.with({microseconds: -9}), RangeError);
assertThrows(() => d2.with({nanoseconds: -10}), RangeError);
// Test large number
......@@ -68,45 +58,25 @@ let d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
assertDuration(d4, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, false);
assertDuration(d4.with(like1), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 1, false);
// Throw when sign flip
assertThrows(() => d4.with({years: 1}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({months: 2}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({weeks: 3}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({days: 4}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({hours: 5}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({minutes: 6}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({seconds: 7}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({milliseconds: 8}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({microseconds: 9}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({nanoseconds: 10}), RangeError,
"Invalid time value");
assertThrows(() => d4.with({years: 1}), RangeError);
assertThrows(() => d4.with({months: 2}), RangeError);
assertThrows(() => d4.with({weeks: 3}), RangeError);
assertThrows(() => d4.with({days: 4}), RangeError);
assertThrows(() => d4.with({hours: 5}), RangeError);
assertThrows(() => d4.with({minutes: 6}), RangeError);
assertThrows(() => d4.with({seconds: 7}), RangeError);
assertThrows(() => d4.with({milliseconds: 8}), RangeError);
assertThrows(() => d4.with({microseconds: 9}), RangeError);
assertThrows(() => d4.with({nanoseconds: 10}), RangeError);
// singular throw
assertThrows(() => d1.with({year:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({month:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({week:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({day:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({hour:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({minute:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({second:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({millisecond:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({microsecond:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({nanosecond:1}), TypeError,
"invalid_argument");
assertThrows(() => d1.with({year:1}), TypeError);
assertThrows(() => d1.with({month:1}), TypeError);
assertThrows(() => d1.with({week:1}), TypeError);
assertThrows(() => d1.with({day:1}), TypeError);
assertThrows(() => d1.with({hour:1}), TypeError);
assertThrows(() => d1.with({minute:1}), TypeError);
assertThrows(() => d1.with({second:1}), TypeError);
assertThrows(() => d1.with({millisecond:1}), TypeError);
assertThrows(() => d1.with({microsecond:1}), TypeError);
assertThrows(() => d1.with({nanosecond:1}), TypeError);
......@@ -18,7 +18,7 @@ assertPlainDate(d.subtract("-P12D"), 2021, 8, 1);
let goodDate = new Temporal.PlainDate(2021, 7, 20);
let badDate = {add: goodDate.add};
assertThrows(() => badDateTime.add("P1D"), TypeError);
assertThrows(() => badDate.add("P1D"), TypeError);
// Throw in ToLimitedTemporalDuration
assertThrows(() => (new Temporal.PlainDate(2021, 7, 20)).add("bad duration"),
......
......@@ -98,4 +98,4 @@ assertThrows(() => Temporal.PlainDateTime.from(
assertThrows(() => Temporal.PlainDateTime.from(
{year:9, month: 12, day:31, nanosecond: 1000}, {overflow: "reject"}),
RangeError
RangeError);
......@@ -6,18 +6,18 @@
function assertDuration(duration, years, months, weeks, days, hours,
minutes, seconds, milliseconds, microseconds, nanoseconds, sign, blank) {
assertEquals(years, duration.years, duration);
assertEquals(months, duration.months, duration);
assertEquals(weeks, duration.weeks, duration);
assertEquals(days, duration.days, duration);
assertEquals(hours, duration.hours, duration);
assertEquals(minutes, duration.minutes, duration);
assertEquals(seconds, duration.seconds, duration);
assertEquals(milliseconds, duration.milliseconds, duration);
assertEquals(microseconds, duration.microseconds, duration);
assertEquals(nanoseconds, duration.nanoseconds, duration);
assertEquals(sign, duration.sign, duration);
assertEquals(blank, duration.blank, duration);
assertEquals(years, duration.years, "years");
assertEquals(months, duration.months, "months");
assertEquals(weeks, duration.weeks, "weeks");
assertEquals(days, duration.days, "days");
assertEquals(hours, duration.hours, "hours");
assertEquals(minutes, duration.minutes, "minutes");
assertEquals(seconds, duration.seconds, "seconds");
assertEquals(milliseconds, duration.milliseconds, "milliseconds");
assertEquals(microseconds, duration.microseconds, "microseconds");
assertEquals(nanoseconds, duration.nanoseconds, "nanoseconds");
assertEquals(sign, duration.sign, "sign");
assertEquals(blank, duration.blank, "blank");
}
function assertPlainDate(time, year, month, day) {
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-temporal
// 1. If NewTarget is undefined, then
// a. Throw a TypeError exception.
assertThrows(() => Temporal.TimeZone("UTC"), TypeError);
assertThrows(() => new Temporal.TimeZone(), RangeError);
assertEquals("UTC", (new Temporal.TimeZone("utc")).id)
This diff is collapsed.
......@@ -59,6 +59,7 @@ FEATURE_FLAGS = {
'Object.hasOwn': '--harmony-object-has-own',
'class-static-block': '--harmony-class-static-blocks',
'resizable-arraybuffer': '--harmony-rab-gsab',
'Temporal': '--harmony-temporal',
'array-find-from-last': '--harmony_array_find_last',
}
......
......@@ -365,75 +365,75 @@ KNOWN_MAPS = {
("read_only_space", 0x03371): (131, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x033b5): (147, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x034b5): (160, "InterceptorInfoMap"),
("read_only_space", 0x05d29): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05d51): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05d79): (134, "CallableTaskMap"),
("read_only_space", 0x05da1): (135, "CallbackTaskMap"),
("read_only_space", 0x05dc9): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05df1): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x05e19): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x05e41): (141, "AccessCheckInfoMap"),
("read_only_space", 0x05e69): (142, "AccessorInfoMap"),
("read_only_space", 0x05e91): (143, "AccessorPairMap"),
("read_only_space", 0x05eb9): (144, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05ee1): (145, "AllocationMementoMap"),
("read_only_space", 0x05f09): (148, "AsmWasmDataMap"),
("read_only_space", 0x05f31): (149, "AsyncGeneratorRequestMap"),
("read_only_space", 0x05f59): (150, "BreakPointMap"),
("read_only_space", 0x05f81): (151, "BreakPointInfoMap"),
("read_only_space", 0x05fa9): (152, "CachedTemplateObjectMap"),
("read_only_space", 0x05fd1): (154, "CallSiteInfoMap"),
("read_only_space", 0x05ff9): (155, "ClassPositionsMap"),
("read_only_space", 0x06021): (156, "DebugInfoMap"),
("read_only_space", 0x06049): (159, "FunctionTemplateRareDataMap"),
("read_only_space", 0x06071): (161, "InterpreterDataMap"),
("read_only_space", 0x06099): (162, "ModuleRequestMap"),
("read_only_space", 0x060c1): (163, "PromiseCapabilityMap"),
("read_only_space", 0x060e9): (164, "PromiseReactionMap"),
("read_only_space", 0x06111): (165, "PropertyDescriptorObjectMap"),
("read_only_space", 0x06139): (166, "PrototypeInfoMap"),
("read_only_space", 0x06161): (167, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x06189): (168, "ScriptMap"),
("read_only_space", 0x061b1): (169, "ScriptOrModuleMap"),
("read_only_space", 0x061d9): (170, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x06201): (171, "StackFrameInfoMap"),
("read_only_space", 0x06229): (172, "TemplateObjectDescriptionMap"),
("read_only_space", 0x06251): (173, "Tuple2Map"),
("read_only_space", 0x06279): (174, "WasmContinuationObjectMap"),
("read_only_space", 0x062a1): (175, "WasmExceptionTagMap"),
("read_only_space", 0x062c9): (176, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x062f1): (194, "SloppyArgumentsElementsMap"),
("read_only_space", 0x06319): (229, "DescriptorArrayMap"),
("read_only_space", 0x06341): (202, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x06369): (200, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x06391): (203, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x063b9): (201, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x063e1): (248, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x06409): (195, "TurbofanBitsetTypeMap"),
("read_only_space", 0x06431): (199, "TurbofanUnionTypeMap"),
("read_only_space", 0x06459): (198, "TurbofanRangeTypeMap"),
("read_only_space", 0x06481): (196, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x064a9): (197, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x064d1): (244, "InternalClassMap"),
("read_only_space", 0x064f9): (255, "SmiPairMap"),
("read_only_space", 0x06521): (254, "SmiBoxMap"),
("read_only_space", 0x06549): (221, "ExportedSubClassBaseMap"),
("read_only_space", 0x06571): (222, "ExportedSubClassMap"),
("read_only_space", 0x06599): (227, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x065c1): (228, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x065e9): (193, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x06611): (245, "InternalClassWithStructElementsMap"),
("read_only_space", 0x06639): (223, "ExportedSubClass2Map"),
("read_only_space", 0x06661): (256, "SortStateMap"),
("read_only_space", 0x06689): (146, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x066b1): (146, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x066d9): (137, "LoadHandler1Map"),
("read_only_space", 0x06701): (137, "LoadHandler2Map"),
("read_only_space", 0x06729): (137, "LoadHandler3Map"),
("read_only_space", 0x06751): (138, "StoreHandler0Map"),
("read_only_space", 0x06779): (138, "StoreHandler1Map"),
("read_only_space", 0x067a1): (138, "StoreHandler2Map"),
("read_only_space", 0x067c9): (138, "StoreHandler3Map"),
("read_only_space", 0x05dcd): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05df5): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05e1d): (134, "CallableTaskMap"),
("read_only_space", 0x05e45): (135, "CallbackTaskMap"),
("read_only_space", 0x05e6d): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05e95): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x05ebd): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x05ee5): (141, "AccessCheckInfoMap"),
("read_only_space", 0x05f0d): (142, "AccessorInfoMap"),
("read_only_space", 0x05f35): (143, "AccessorPairMap"),
("read_only_space", 0x05f5d): (144, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05f85): (145, "AllocationMementoMap"),
("read_only_space", 0x05fad): (148, "AsmWasmDataMap"),
("read_only_space", 0x05fd5): (149, "AsyncGeneratorRequestMap"),
("read_only_space", 0x05ffd): (150, "BreakPointMap"),
("read_only_space", 0x06025): (151, "BreakPointInfoMap"),
("read_only_space", 0x0604d): (152, "CachedTemplateObjectMap"),
("read_only_space", 0x06075): (154, "CallSiteInfoMap"),
("read_only_space", 0x0609d): (155, "ClassPositionsMap"),
("read_only_space", 0x060c5): (156, "DebugInfoMap"),
("read_only_space", 0x060ed): (159, "FunctionTemplateRareDataMap"),
("read_only_space", 0x06115): (161, "InterpreterDataMap"),
("read_only_space", 0x0613d): (162, "ModuleRequestMap"),
("read_only_space", 0x06165): (163, "PromiseCapabilityMap"),
("read_only_space", 0x0618d): (164, "PromiseReactionMap"),
("read_only_space", 0x061b5): (165, "PropertyDescriptorObjectMap"),
("read_only_space", 0x061dd): (166, "PrototypeInfoMap"),
("read_only_space", 0x06205): (167, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x0622d): (168, "ScriptMap"),
("read_only_space", 0x06255): (169, "ScriptOrModuleMap"),
("read_only_space", 0x0627d): (170, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x062a5): (171, "StackFrameInfoMap"),
("read_only_space", 0x062cd): (172, "TemplateObjectDescriptionMap"),
("read_only_space", 0x062f5): (173, "Tuple2Map"),
("read_only_space", 0x0631d): (174, "WasmContinuationObjectMap"),
("read_only_space", 0x06345): (175, "WasmExceptionTagMap"),
("read_only_space", 0x0636d): (176, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x06395): (194, "SloppyArgumentsElementsMap"),
("read_only_space", 0x063bd): (229, "DescriptorArrayMap"),
("read_only_space", 0x063e5): (202, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x0640d): (200, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x06435): (203, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x0645d): (201, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x06485): (248, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x064ad): (195, "TurbofanBitsetTypeMap"),
("read_only_space", 0x064d5): (199, "TurbofanUnionTypeMap"),
("read_only_space", 0x064fd): (198, "TurbofanRangeTypeMap"),
("read_only_space", 0x06525): (196, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x0654d): (197, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x06575): (244, "InternalClassMap"),
("read_only_space", 0x0659d): (255, "SmiPairMap"),
("read_only_space", 0x065c5): (254, "SmiBoxMap"),
("read_only_space", 0x065ed): (221, "ExportedSubClassBaseMap"),
("read_only_space", 0x06615): (222, "ExportedSubClassMap"),
("read_only_space", 0x0663d): (227, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x06665): (228, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x0668d): (193, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x066b5): (245, "InternalClassWithStructElementsMap"),
("read_only_space", 0x066dd): (223, "ExportedSubClass2Map"),
("read_only_space", 0x06705): (256, "SortStateMap"),
("read_only_space", 0x0672d): (146, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x06755): (146, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x0677d): (137, "LoadHandler1Map"),
("read_only_space", 0x067a5): (137, "LoadHandler2Map"),
("read_only_space", 0x067cd): (137, "LoadHandler3Map"),
("read_only_space", 0x067f5): (138, "StoreHandler0Map"),
("read_only_space", 0x0681d): (138, "StoreHandler1Map"),
("read_only_space", 0x06845): (138, "StoreHandler2Map"),
("read_only_space", 0x0686d): (138, "StoreHandler3Map"),
("map_space", 0x02131): (1057, "ExternalMap"),
("map_space", 0x02159): (2114, "JSMessageObjectMap"),
}
......
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