1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 19:15:08 +00:00
Commit graph

3168 commits

Author SHA1 Message Date
Timothy Flynn
643992904c LibJS: Clip parsed IS0 8601 strings to +/- 8.64e15 2022-01-14 22:39:06 +01:00
Timothy Flynn
aea4f79b57 LibJS: Implement Date.parse using AK::Time and LibTimeZone
Fixes #4651
2022-01-14 22:39:06 +01:00
Timothy Flynn
7d2834344a LibJS: Implement the localTZA AO for isUTC=false 2022-01-14 22:39:06 +01:00
Nico Weber
db869a0402 LibJS: Add an else in StringPrototype::substr
No behavior change, but makes the code look more like the spec test for
this function.
2022-01-14 11:12:24 +01:00
Nico Weber
1b944b4c41 LibJS: Fix substr() with negative arguments larger than string length
length_in_code_units() returns a size_t, which is 64-bit unsigned
in i686 builds. `size + (i32)int_length` hence produced a 64-bit
unsigned result, so a negative value would wrap around and become
a very large number.

As fix, just omit the cast -- we assign the result of max() to
a double anyways.

With this, all test262 tests in annexB/built-ins/String/prototype pass.
2022-01-14 11:12:24 +01:00
Nico Weber
23cde7685c LibJS: Correcly handle surrogates in escape()
Fixes test/annexB/built-ins/escape/escape-above{,-astral}.js in
test262. All tests in test/annexB/built-ins/escape pass now.
2022-01-14 10:59:46 +01:00
Ali Mohammad Pur
9de33629da AK+Everywhere: Make Variant::visit() respect the Variant's constness
...and fix all the instances of visit() taking non-const arguments.
2022-01-14 11:35:40 +03:30
Timothy Flynn
c7dbe27781 LibJS: Handle the [[LanguageDisplay]] tag when localizing languages 2022-01-13 23:05:31 +01:00
Linus Groh
64f125fe34 LibJS: Mark CreateTemporalTimeZone("UTC") as infallible
This is an editorial change in the Temporal spec.

See: ea25cfa
2022-01-13 19:25:56 +01:00
Timothy Flynn
4875ec26dd LibJS: Implement per-locale display of calendars and date-time fields 2022-01-13 13:43:57 +01:00
Timothy Flynn
adb762ee48 LibJS: Add FIXME regarding [[LanguageDisplay]] internal slot handling
This is supposed to work as follows (grabbed from SpiderMonkey):

    > opt = { type: "language", languageDisplay: "dialect" };
    > new Intl.DisplayNames([], opt).of("en-US");
    "American English"

    > opt = { type: "language", languageDisplay: "standard" };
    > new Intl.DisplayNames([], opt).of("en-US");
    "English (United States)"

We currently display the "dialect" variant. We will need to figure out
how to display the "standard" variant. I think the way it works is that
we take the display names of "en" (language) and "US" (region) and
format them according to this pattern in localeDisplayNames.json:

    "localeDisplayNames": {
        "localeDisplayPattern": {
            "localePattern": "{0} ({1})",
        },
    },

But I'd like to confirm this before implementing it.
2022-01-13 13:43:57 +01:00
Timothy Flynn
8126cb2545 LibJS+LibUnicode: Remove unnecessary locale currency mapping wrapper
Before LibUnicode generated methods were weakly linked, we had a public
method (get_locale_currency_mapping) for retrieving currency mappings.
That method invoked one of several style-specific methods that only
existed in the generated UnicodeLocale.

One caveat of weakly linked functions is that every such function must
have a public declaration. The result is that each of those styled
methods are declared publicly, which makes the wrapper redundant
because it is just as easy to invoke the method for the desired style.
2022-01-13 13:43:57 +01:00
Timothy Flynn
1a3e6e8a7b LibJS: Add [[LanguageDisplay]] to Intl.DisplayNames's resolvedOptions 2022-01-13 13:43:57 +01:00
Timothy Flynn
71f7e67a20 LibJS: Parse new Intl.DisplayNames "type" and "languageDisplay" options
Intl.DisplayNames v2 adds "calendar" and "dateTimeField" types, as well
as a "languageDisplay" option for the "language" type. This just adds
these options to the constructor.
2022-01-13 13:43:57 +01:00
Timothy Flynn
853ccab9af LibJS: Remove unnecessary braces in Intl.DisplayNames
Just caught my eye as I was modifying this code.
2022-01-13 13:43:57 +01:00
Linus Groh
b9093dd0ab LibJS: Don't validate time zone name when parsing Instant string
This is normative change in the Temporal spec.

See: 2a81fbc
2022-01-13 10:08:34 +01:00
Linus Groh
cf6ceb956f LibJS: Avoid js_string() allocation in parse_time_zone_offset_string()
No need to take the spec literally here since we know the input values
are guaranteed to be integral numbers. Use AK string to number parsing
functionality instead and save a couple of PrimitiveString allocations.

This matches what we already do in parse_temporal_time_zone_string().
2022-01-12 21:24:12 +01:00
Linus Groh
392f5bfebd LibJS: Fix fraction substring range in parse_temporal_time_zone_string()
Two issues:

- The intended range was 9 characters starting from index 1. Since the
  second argument to String::substring() is the length, 10 is
  potentially reading further than the string's length (when only
  providing one fraction digit), causing an assertion failure crash.
- The spec's intention to skip the decimal separator by starting at
  index 1 is incorrect, no decimal separator is present in the result of
  parsing TimeZoneUTCOffsetFractionalPart. I filed a spec fix for this,
  see: https://github.com/tc39/proposal-temporal/pull/1999
2022-01-12 21:24:12 +01:00
Linus Groh
027e4bd439 LibJS: Fix calculation overflow in parse_temporal_time_zone_string()
As all variables and numeric literals in the expression have an integral
data type, it would evaluate to an int and could easily overflow as
we're multiplying seconds with 10^9.

Introduce a floating point literal into the expression to make it result
in a double.
2022-01-12 21:24:12 +01:00
Linus Groh
323e1e17cf LibJS: Fix sign data type in parse_temporal_time_zone_string()
A sign that's either the value 1 or -1 should obviously not have an
unsigned data type :^)

This would cause it to become 255 for the negative offset case, which
would then completely screw up the offset_nanoseconds calculation as it
serves as a multiplier.
2022-01-12 21:24:12 +01:00
Timothy Flynn
a121c913c0 LibJS: Add some Intl.DateTimeFormat tests for specific time zones
Now that we can use time zones, let's adds tests for them.
2022-01-12 15:43:12 +01:00
Timothy Flynn
d64ea13565 LibJS: Respect the user-provided time zone in Intl.DateTimeFormat
Also update some DateTimeFormat tests to explicitly set the time zone
(usually to UTC). This was already done for most tests, but some were
missed.
2022-01-12 15:43:12 +01:00
Timothy Flynn
8987deb984 LibJS: Partially implement the LocalTZA AO
Intl.DateTimeFormat will invoke this AO with isUTC=true, so this only
implements that branch in LocalTZA.
2022-01-12 15:43:12 +01:00
Timothy Flynn
f6786881aa LibJS: Implement the ECMA-402 definition of DefaultTimeZone
Simply defer to LibTimeZone to retrieve the system's current time zone.
Also update some Temporal tests to explicitly set the time zone to UTC.
2022-01-12 15:43:12 +01:00
Timothy Flynn
c1a1370c2a LibJS: Use new LibUnicode API to format time zone names 2022-01-11 23:56:35 +01:00
Timothy Flynn
cc5e9f0579 LibJS+LibUnicode: Move replacement of number system digits to LibUnicode
There are a few algorithms in TR-35 that need to replace digits before
returning any results to callers. For example, when formatting time zone
offsets, a string like "GMT+12:34" must have its digits replaced with
the default numbering system for the desired locale.
2022-01-11 23:56:35 +01:00
Linus Groh
355fbcb702 LibJS: Actually implement get_iana_time_zone_offset_nanoseconds()
Instead of hard-coding an UTC offset of zero seconds, which worked for
the sole UTC time zone, we can now get the proper offset from the TZDB!
2022-01-11 22:17:39 +01:00
Linus Groh
d527eb62da LibJS: Support non-UTC time zones in Temporal :^)
We can now recognize & normalize all time zones from the IANA time zone
database and not just 'UTC', which makes the LibJS Temporal
implementation a lot more useful! Thanks to the newly added LibTimeZone,
this was incredibly easy to implement :^)

This already includes these recent editorial changes in the Temporal
spec: 27bffe1
2022-01-11 22:17:39 +01:00
Linus Groh
f1276144ba LibJS: Check if input was exhausted after parsing UTC offset fraction
Previously parse_time_zone_numeric_utc_offset_syntax() would return true
to indicate success when parsing a string with an invalid number of
digits in the fractional seconds part (e.g. 23:59:59.9999999999).
We need to check if the lexer has any characters remaining, and return
false if that's the case.
2022-01-11 21:16:33 +01:00
Linus Groh
de07312cc7 LibJS/Tests: Add Temporal.TimeZone() tests for numeric UTC offset
This works now, let's test it :^)
2022-01-11 21:16:33 +01:00
Timothy Flynn
05de9b82b8 LibJS: Include hour-cycle in DateTimeFormat options
This is a normative change to the Intl spec:
20e5c26

Note that this doesn't actually affect us. Its purpose is to provide the
hour-cycle to BestFitFormatMatcher. This AO is implementation defined,
and ours just invokes BasicFormatMatcher, which doesn't use this field.
We could now have LibUnicode generate this field and use it to find a
better format pattern, though.
2022-01-10 16:18:05 +01:00
Linus Groh
09a11fa6ea LibJS: Implement proper Iterator records
Instead of using plain objects as Iterator records, causes confusion
about the object itself actually being its [[Iterator]] slot, and
requires non-standard type conversion shenanigans fpr the [[NextValue]]
and [[Done]] internal slots,  implement a proper Iterator record struct
and use it throughout.

Also annotate the remaining Iterator AOs with spec comments while we're
here.
2022-01-09 22:02:43 +01:00
Linus Groh
e141f1e976 LibJS: Use Optional<Value> for potentially missing value in Iterator AOs
Given we're already moving away from using the empty Value elsewhere,
and I'm about to update most of this code, let's do this small tweak
now.
2022-01-09 22:02:43 +01:00
Linus Groh
963b0f76cf LibJS: Remove now unused VM::{set_,}last_value()
This was effectively replaced by correct use of completions, including
UpdateEmpty semantics.
2022-01-08 23:43:03 +01:00
Linus Groh
eb60d16549 LibJS: Convert Interpreter::run() to ThrowCompletionOr<Value>
Instead of making it a void function, checking for an exception, and
then receiving the relevant result via VM::last_value(), we can
consolidate all of this by using completions.

This allows us to remove more uses of VM::exception(), and all uses of
VM::last_value().
2022-01-08 23:43:03 +01:00
Linus Groh
3301b0b33d LibJS: Remove duplicate assignment step from parse_iso_date_time()
This is an editorial change in the Temporal spec.

See: eb68de2
2022-01-08 00:31:28 +01:00
mjz19910
10ec98dd38 Everywhere: Fix spelling mistakes 2022-01-07 15:44:42 +01:00
mjz19910
3102d8e160 Everywhere: Fix many spelling errors 2022-01-07 10:56:59 +01:00
Linus Groh
3bd7f5b89e LibJS: Fully parse the TimeZoneIANAName production
Currently does nothing as we'll declare everything other than UTC as
invalid, but it's a first step towards supporting named time zones :^)
2022-01-06 22:40:09 +01:00
Linus Groh
d42336312c LibJS: Include time zone name in TemporalInvalidTimeZoneName error 2022-01-06 21:49:50 +01:00
Linus Groh
81492b3cee LibJS: Remove the now unused custom VM unwind mechanism
Goodbye VM::m_unwind_until, you served us well :^)
2022-01-06 12:36:23 +01:00
Linus Groh
9d0d3affd4 LibJS: Replace the custom unwind mechanism with completions :^)
This includes:

- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
2022-01-06 12:36:23 +01:00
Linus Groh
eed764e1dd LibJS: Implement the LoopContinues AO 2022-01-06 12:36:23 +01:00
Linus Groh
fc474966bc LibJS: Implement LabelledStatement & LabelledEvaluation semantics
Instead of slapping 0..N labels on a statement like the current
LabelableStatement does, we need the spec's LabelledStatement for a
proper implementation of control flow using only completions - it always
has one label and one labelled statement - what appears to be 'multiple
labels' on the same statement is actually nested LabelledStatements.

Note that this is unused yet and will fully replace LabelableStatement
in the next commit.
2022-01-06 12:36:23 +01:00
Luke Wilde
3e0c19d6ea LibJS: Add tests for all the unscopable Array prototype properties
When I was writing for tests for groupBy and groupByToMap, I noticed
there were no tests for these.
2022-01-05 20:31:25 +01:00
Timothy Flynn
260d2099da LibJS: Implement Date.UTC according to the spec
This fixes all failing Date.UTC test262 tests, which failed due to not
handling invalid input and evaluating inputs out of order. But this also
avoids using timegm(), which doesn't work on macOS for years before 1900
(they simply return -1 for those years).

Partially addresses #4651. Date.parse.js still fails.
2022-01-05 20:05:12 +01:00
Timothy Flynn
7a0830bb24 LibJS: Use AK::Time to implement the MakeDay AO
We currently use Core::DateTime create, which internally uses mktime().
This has the issues pointed out by the (now removed) FIXME, but also has
an issue on macOS where years before 1900 are not supported.
2022-01-05 20:05:12 +01:00
Timothy Flynn
e8f860048e LibJS: Set the length of Date.UTC to 7
This is a bit unusual because there is only 1 required argument, but the
spec dictates that the length is 7.
2022-01-05 20:05:12 +01:00
Andreas Kling
c7ac0c2c80 LibJS: Use HashMap::remove_all_matching() in WeakMap 2022-01-05 18:57:14 +01:00
Andreas Kling
e08d325124 LibJS: Use HashTable::remove_all_matching() in WeakSet :^) 2022-01-05 18:57:14 +01:00