This commit effectively just does a bulk update of this function to the
spec. Since there have been so many spec changes, no specific change was
made in mind, and many FIXMEs have been left for where we are still out
of date.
These changes also appear to include a normative change to the temporal
spec which was previously resulting in timeouts for some tests, and is
now resulting in a timeout.
Furthermore, this also resolves some crashes by protecting against
division by zero, instead throwing a RangeError. This can only happen
when a custom calender is provided which returns funky values. See:
https://github.com/tc39/proposal-temporal/commit/ed85e9
Diff Tests:
+8 ✅ -4 💀 -4 💥️
The spec has moved along quite a bit since this was originally
implemented. Catch up on at least some of these changes, and leave
FIXMEs for what is missing.
No change to test262.
Previously, constructing a `UnsignedBigInteger::from_base()` could
produce an incorrect result if the input string contained a valid
Base36 digit that was out of range of the given base. The same method
would also crash if the input string contained an invalid Base36 digit.
An error is now returned in both these cases.
Constructing a BigFraction from string is now also fallible, so that we
can handle the case where we are given an input string with invalid
digits.
`JsonValue::to_byte_string` has peculiar type-erasure semantics which is
not usually intended. Unfortunately, it also has a very stereotypical
name which does not warn about unexpected behavior. So let's prefix it
with `deprecated_` to make new code use `as_string` if it just wants to
get string value or `serialized<StringBuilder>` if it needs to do proper
serialization.
This is a normative change in the ECMA-262 spec. See:
22de374
The issue noted here has been fixed in the same way that we previously
worked around it. Update the spec notes to match.
Without a key function, the vtable for this class can be emitted into
every shared object or executable that needs it. This can cause bugs and
bad behavior when trying to access the vtable or RTTI for the class.
This is most easily seen when trying to call ``is<JS::Date>``, which
currently will do a dynamic_cast. Based on compiler, linker and loader
choices about ordering, it's possible that the code checking the RTTI
and the code that created the object could have a different vtable and
type_info in mind, causing false negatives for the ``is`` check.
There was recently a normative change to this AO in ECMA-262. See:
5eaee2f
It turns out we already implemented this to align with web-reality
before it was codified in the spec. This was a bit difficult to reason
without spec text and with a somewhat ad-hoc implementation. So this
patch aligns our implementation with the spec. There should not be any
behavior change.
JS::modulo was yielding a result of '0' for the input:
```
modulo(1., 18446744073709551616.)
```
Instead of the expected '1'.
As far as I can tell the reason for this is that the repeated calls to
fmod is losing precision in the calculation, leading to the wrong
result. Fix this by only calling fmod once, and preserving the negative
value behaviour by an 'if' check.
Without this, the LibWeb text test:
`/Streams/ReadableByteStream-enqueue-respond.html`
Would hang forever after using this function in the IDL conversion of a
u64 in ConvertToInt.
This should also be more efficient :^)
Instead of returning HeapBlock memory to the kernel (or a non-type
specific shared cache), we now keep a BlockAllocator per CellAllocator
and implement "deallocation" by basically informing the kernel that we
don't need the physical memory right now.
This is done with MADV_FREE or MADV_DONTNEED if available, but for other
platforms (including SerenityOS) we munmap and then re-mmap the memory
to achieve the same effect. It's definitely clunky, so I've added a
FIXME about implementing the madvise options on SerenityOS too.
The important outcome of this change is that GC types that use a
type-specific allocator become immune to use-after-free type confusion
attacks, since their virtual addresses will only ever be re-used for
the same exact type again and again.
Fixes#22274
When resolving a rope, we've already taken care to resolve it to
a UTF-8 byte stream. There's no need to do a separate pass just for
validating the data again.
This was noticeable in some profiles. I made a simple microbenchmark
that gets a 30% speed-up:
("x" + "y".repeat(100_000_000)).trimStart()
Instead of using a StringBuilder, add a String::repeated(String, N)
overload that takes advantage of knowing it's already all UTF-8.
This makes the following microbenchmark go 4x faster:
"foo".repeat(100_000_000)
And for single character strings, we can even go 10x faster:
"x".repeat(100_000_000)
We can now implement steps related to resizable ArrayBuffer objects. We
can also implement a couple of missing SharedArrayBuffer checks.
The original implementation of this proposal did not have any tests, so
tests are added here for the whole implementation.
In: https://tc39.es/ecma262/#sec-%typedarray%-intrinsic-object
The spec says:
> is a constructor function object that all of the TypedArray
> constructor objects inherit from.
From what I understand from this, it effectively just means is that the
prototype for the constructor should simply be set to
TypedArrayConstructor. We _were_ doing that, but also inheriting from
it in C++.
This meant we were invoking TypedArrayConstructor::initialize for each
of the typed arrays. This is not actually what we want, since it means
that the 'of' and 'from' functions were being defined as native
properties in both the concrete typed array (e.g Uint8Array), and the
abstract TypedArray. Instead, the properties should only be defined and
inherited from the abstract TypedArray class.
Diff Tests:
+4 ✅ -4 ❌
Co-Authored-By: Andreas Kling <kling@serenityos.org>
This is (part of) a normative change in the ECMA-262 spec. See:
a9ae96e
This implements just support for resizing ArrayBuffer objects. This does
not implement the SharedArrayBuffer changes, as we do not have enough
support to do so.
The IsValidIntegerIndex AO performs the checks we are interested in. The
manual implementation we currently have will no longer compile once the
resizable ArrayBuffer spec is implemented. The AO will be updated with
the spec implementation, so let's use it now to avoid breakage.
This renames IntegerIndexedElementGet to TypedArrayGetElement, and
IntegerIndexedElementSet to TypedArraySetElement.
This also renames the indexedPosition variable inside these method
definitions to byteIndexInBuffer.
These are part of a couple editorial changes in the ECMA-262 spec. See:
03e4410a1a4d48
The remainder of the changes in those commits apply to the resizable
ArrayBuffer spec, which is not implemented in LibJS as of this commit.
After the resizable ArrayBuffer proposal was merged, a bunch of methods
had their spec numbers/headers changed. This patch just updates existing
methods to make future patches easier to grok.
This was a normative change in the Array.fromAsync spec which we already
implemented :^). See:
https://github.com/tc39/proposal-array-from-async/commit/689d0d
I've left an existing FIXME in there for some other bug which we have
which is causing some test262 test cases to fail.
Due to a `requires` mistake, we were always using the fallback
size-based cell allocators.
Also, now that we start using them, make them NeverDestroyed so
we don't try to deallocate them on program exit.
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:
```
Optional<I> opt;
if constexpr (IsSigned<I>)
opt = view.to_int<I>();
else
opt = view.to_uint<I>();
```
For us.
The main goal here however is to have a single generic number conversion
API between all of the String classes.
When calling `running_execution_context` from other VM APIs, and the
execution context stack is empty, the verification message is inlined
from AK::Vector. Add a specific VERIFY to `running_execution_context` to
help diagnose this issue better.
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
$ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
Meta Ports Ladybird Tests Kernel)
$ perl -pie 's/\bDeprecatedString\b/ByteString/g;
s/deprecated_string/byte_string/g' $xs
$ clang-format --style=file -i \
$(git diff --name-only | grep \.cpp\|\.h)
$ gn format $(git ls-files '*.gn' '*.gni')
This is similar to "unique" shapes, which were removed in commit
3d92c26445.
The key difference is that dictionary shapes don't have a serial number,
but instead have a "cacheable" flag.
Shapes become dictionaries after 64 transitions have occurred, at which
point no further transitions occur.
As long as properties are only added to a dictionary shape, it remains
cacheable. (Since if we've cached the shape pointer in an IC somewhere,
we know the IC is still valid.)
Deleting a property from a dictionary shape causes it to become an
uncacheable dictionary.
Note that deleting a property from a non-dictionary shape still performs
a delete transition.
This fixes an issue on Discord where Object.freeze() would eventually
OOM us, since they add more than 16000 properties to a single object
before freezing it.
It also yields a 15% speedup on Octane/pdfjs.js :^)