diff --git a/polyfill/lib/date.mjs b/polyfill/lib/date.mjs index 55f9265c18..19bfaa6120 100644 --- a/polyfill/lib/date.mjs +++ b/polyfill/lib/date.mjs @@ -195,9 +195,11 @@ export class Date { } static compare(one, two) { if (!ES.IsTemporalDate(one) || !ES.IsTemporalDate(two)) throw new TypeError('invalid Date object'); - if (one.year !== two.year) return ES.ComparisonResult(one.year - two.year); - if (one.month !== two.month) return ES.ComparisonResult(one.month - two.month); - if (one.day !== two.day) return ES.ComparisonResult(one.day - two.day); + for (const slot of [YEAR, MONTH, DAY]) { + const val1 = GetSlot(one, slot); + const val2 = GetSlot(two, slot); + if (val1 !== val2) return ES.ComparisonResult(val1 - val2); + } return ES.ComparisonResult(0); } } diff --git a/polyfill/lib/datetime.mjs b/polyfill/lib/datetime.mjs index 6d177223ee..a285d753f8 100644 --- a/polyfill/lib/datetime.mjs +++ b/polyfill/lib/datetime.mjs @@ -387,15 +387,11 @@ export class DateTime { } static compare(one, two) { if (!ES.IsTemporalDateTime(one) || !ES.IsTemporalDateTime(two)) throw new TypeError('invalid DateTime object'); - if (one.year !== two.year) return ES.ComparisonResult(one.year - two.year); - if (one.month !== two.month) return ES.ComparisonResult(one.month - two.month); - if (one.day !== two.day) return ES.ComparisonResult(one.day - two.day); - if (one.hour !== two.hour) return ES.ComparisonResult(one.hour - two.hour); - if (one.minute !== two.minute) return ES.ComparisonResult(one.minute - two.minute); - if (one.second !== two.second) return ES.ComparisonResult(one.second - two.second); - if (one.millisecond !== two.millisecond) return ES.ComparisonResult(one.millisecond - two.millisecond); - if (one.microsecond !== two.microsecond) return ES.ComparisonResult(one.microsecond - two.microsecond); - if (one.nanosecond !== two.nanosecond) return ES.ComparisonResult(one.nanosecond - two.nanosecond); + for (const slot of [YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, MICROSECOND, NANOSECOND]) { + const val1 = GetSlot(one, slot); + const val2 = GetSlot(two, slot); + if (val1 !== val2) return ES.ComparisonResult(val1 - val2); + } return ES.ComparisonResult(0); } } diff --git a/polyfill/lib/time.mjs b/polyfill/lib/time.mjs index 010ae76132..b211cef673 100644 --- a/polyfill/lib/time.mjs +++ b/polyfill/lib/time.mjs @@ -277,12 +277,11 @@ export class Time { } static compare(one, two) { if (!ES.IsTemporalTime(one) || !ES.IsTemporalTime(two)) throw new TypeError('invalid Time object'); - if (one.hour !== two.hour) return ES.ComparisonResult(one.hour - two.hour); - if (one.minute !== two.minute) return ES.ComparisonResult(one.minute - two.minute); - if (one.second !== two.second) return ES.ComparisonResult(one.second - two.second); - if (one.millisecond !== two.millisecond) return ES.ComparisonResult(one.millisecond - two.millisecond); - if (one.microsecond !== two.microsecond) return ES.ComparisonResult(one.microsecond - two.microsecond); - if (one.nanosecond !== two.nanosecond) return ES.ComparisonResult(one.nanosecond - two.nanosecond); + for (const slot of [HOUR, MINUTE, SECOND, MILLISECOND, MICROSECOND, NANOSECOND]) { + const val1 = GetSlot(one, slot); + const val2 = GetSlot(two, slot); + if (val1 !== val2) return ES.ComparisonResult(val1 - val2); + } return ES.ComparisonResult(0); } } diff --git a/polyfill/lib/yearmonth.mjs b/polyfill/lib/yearmonth.mjs index 91a7846e5a..fd37f97804 100644 --- a/polyfill/lib/yearmonth.mjs +++ b/polyfill/lib/yearmonth.mjs @@ -156,8 +156,11 @@ export class YearMonth { } static compare(one, two) { if (!ES.IsTemporalYearMonth(one) || !ES.IsTemporalYearMonth(two)) throw new TypeError('invalid YearMonth object'); - if (one.year !== two.year) return ES.ComparisonResult(one.year - two.year); - if (one.month !== two.month) return ES.ComparisonResult(one.month - two.month); + for (const slot of [YEAR, MONTH]) { + const val1 = GetSlot(one, slot); + const val2 = GetSlot(two, slot); + if (val1 !== val2) return ES.ComparisonResult(val1 - val2); + } return ES.ComparisonResult(0); } } diff --git a/polyfill/test/Date/constructor/compare/use-internal-slots.js b/polyfill/test/Date/constructor/compare/use-internal-slots.js new file mode 100644 index 0000000000..9eb81663f6 --- /dev/null +++ b/polyfill/test/Date/constructor/compare/use-internal-slots.js @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-comparetemporaldate +---*/ + +function CustomError() {} + +class AvoidGettersDate extends Temporal.Date { + get year() { + throw new CustomError(); + } + get month() { + throw new CustomError(); + } + get day() { + throw new CustomError(); + } +} + +const one = new AvoidGettersDate(2000, 5, 2); +const two = new AvoidGettersDate(2006, 3, 25); +assert.sameValue(Temporal.Date.compare(one, two), -1); diff --git a/polyfill/test/DateTime/constructor/compare/use-internal-slots.js b/polyfill/test/DateTime/constructor/compare/use-internal-slots.js new file mode 100644 index 0000000000..0770faccf3 --- /dev/null +++ b/polyfill/test/DateTime/constructor/compare/use-internal-slots.js @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-comparetemporaldatetime +---*/ + +function CustomError() {} + +class AvoidGettersDateTime extends Temporal.DateTime { + get year() { + throw new CustomError(); + } + get month() { + throw new CustomError(); + } + get day() { + throw new CustomError(); + } + get hour() { + throw new CustomError(); + } + get minute() { + throw new CustomError(); + } + get second() { + throw new CustomError(); + } + get millisecond() { + throw new CustomError(); + } + get microsecond() { + throw new CustomError(); + } + get nanosecond() { + throw new CustomError(); + } +} + +const one = new AvoidGettersDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321); +const two = new AvoidGettersDateTime(2006, 3, 25, 6, 54, 32, 123, 456, 789); +assert.sameValue(Temporal.DateTime.compare(one, two), -1); diff --git a/polyfill/test/Time/constructor/compare/use-internal-slots.js b/polyfill/test/Time/constructor/compare/use-internal-slots.js new file mode 100644 index 0000000000..2ea5a1ddd5 --- /dev/null +++ b/polyfill/test/Time/constructor/compare/use-internal-slots.js @@ -0,0 +1,33 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-comparetemporaltime +---*/ + +function CustomError() {} + +class AvoidGettersTime extends Temporal.Time { + get hour() { + throw new CustomError(); + } + get minute() { + throw new CustomError(); + } + get second() { + throw new CustomError(); + } + get millisecond() { + throw new CustomError(); + } + get microsecond() { + throw new CustomError(); + } + get nanosecond() { + throw new CustomError(); + } +} + +const one = new AvoidGettersTime(12, 34, 56, 987, 654, 321); +const two = new AvoidGettersTime(6, 54, 32, 123, 456, 789); +assert.sameValue(Temporal.Time.compare(one, two), 1); diff --git a/polyfill/test/YearMonth/constructor/compare/use-internal-slots.js b/polyfill/test/YearMonth/constructor/compare/use-internal-slots.js new file mode 100644 index 0000000000..e7b29f380e --- /dev/null +++ b/polyfill/test/YearMonth/constructor/compare/use-internal-slots.js @@ -0,0 +1,21 @@ +// Copyright (C) 2020 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-comparetemporalyearmonth +---*/ + +function CustomError() {} + +class AvoidGettersYearMonth extends Temporal.YearMonth { + get year() { + throw new CustomError(); + } + get month() { + throw new CustomError(); + } +} + +const one = new AvoidGettersYearMonth(2000, 5); +const two = new AvoidGettersYearMonth(2006, 3); +assert.sameValue(Temporal.YearMonth.compare(one, two), -1);