diff options
author | Linus Groh <mail@linusgroh.de> | 2021-09-01 00:19:03 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-09-01 15:11:35 +0100 |
commit | 38bef3e28ea6aa417dba7f6dbbf0d686d8241c87 (patch) | |
tree | 81a94f9b9a25ec8537f0c550175b6496ef9721fc /Userland/Libraries/LibJS | |
parent | fd0011989aee950de25079836bb19c015b8f1afb (diff) | |
download | serenity-38bef3e28ea6aa417dba7f6dbbf0d686d8241c87.zip |
LibJS: Handle undefined, NaN, and Infinity in ToTemporalDurationRecord
This is a normative change in the Temporal spec.
See: https://github.com/tc39/proposal-temporal/commit/d4b9bcf
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp index c41ac82d44..b951843052 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -95,35 +95,38 @@ TemporalDuration to_temporal_duration_record(GlobalObject& global_object, Object if (vm.exception()) return {}; - // c. If val is not undefined, then - if (!value.is_undefined()) { + // c. If val is undefined, then + if (value.is_undefined()) { + // i. Set result's internal slot whose name is the Internal Slot value of the current row to 0. + result.*internal_slot = 0; + } + // d. Else, + else { // i. Set any to true. any = true; - } - // TODO: This is not in the spec but it seems to be implied, and is also what the polyfill does. - // I think the steps d, e, and f should be conditional based on c - otherwise we call ToNumber(undefined), - // get NaN and immediately fail the floor(val) ≠ val check, making the `any` flag pointless. See: - // - https://github.com/tc39/proposal-temporal/blob/4b4dbd427d4b0468a3b064ca7082f25b209923bc/polyfill/lib/ecmascript.mjs#L556-L607 - // - https://github.com/tc39/proposal-temporal/blob/4b4dbd427d4b0468a3b064ca7082f25b209923bc/polyfill/lib/ecmascript.mjs#L876-L893 - else { - continue; - } + // ii. Let val be ? ToNumber(val). + value = value.to_number(global_object); + if (vm.exception()) + return {}; - // d. Let val be ? ToNumber(val). - value = value.to_number(global_object); - if (vm.exception()) - return {}; + // iii. If val is NaN, +∞ or -∞, then + if (value.is_nan() || value.is_infinity()) { + // 1. Throw a RangeError exception. + vm.throw_exception<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonIntegral, property.as_string(), value.to_string_without_side_effects()); + return {}; + } - // e. If floor(val) ≠ val, then - if (floor(value.as_double()) != value.as_double()) { - // i. Throw a RangeError exception. - vm.throw_exception<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonIntegral, property.as_string(), value.to_string_without_side_effects()); - return {}; - } + // iv. If floor(val) ≠ val, then + if (floor(value.as_double()) != value.as_double()) { + // 1. Throw a RangeError exception. + vm.throw_exception<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonIntegral, property.as_string(), value.to_string_without_side_effects()); + return {}; + } - // f. Set result's internal slot whose name is the Internal Slot value of the current row to val. - result.*internal_slot = value.as_double(); + // v. Set result's internal slot whose name is the Internal Slot value of the current row to val. + result.*internal_slot = value.as_double(); + } } // 6. If any is false, then |