1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 18:25:06 +00:00
Commit graph

3776 commits

Author SHA1 Message Date
Timothy Flynn
834ced9ef8 LibJS: Change error message for values that must be a SharedArrayBuffer
This error will be used in contexts that apply to more than TypedArrays.
2023-12-29 09:25:41 +01:00
Timothy Flynn
f1e01a681e LibJS: Implement missing conditional when creating a TypedArray subarray 2023-12-28 08:19:02 -05:00
Timothy Flynn
916cb256de LibJS: Ensure enlarged ArrayBuffers are filled with zeros
Otherwise, the newly allocated bytes are uninitialized, causing UB when
reading from the buffer immediately after an enlarging resize.
2023-12-27 19:30:39 +01:00
Shannon Booth
5d0fb4bac3 LibJS: Do not inherit TypedArray constructors from TypedArrayConstructor
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>
2023-12-27 10:57:16 -05:00
Timothy Flynn
bf8107b247 LibJS: Update spec numbers for the Promise.withResolvers proposal
This proposal has been merged into the main ECMA-262 spec. See:
11cbf72
2023-12-26 12:07:50 -05:00
Timothy Flynn
edbc2a1031 LibJS: Update spec numbers for the Array Grouping proposal
This proposal has been merged into the main ECMA-262 spec. See:
3a9c9dc
2023-12-26 12:07:50 -05:00
Timothy Flynn
9258d7b98a LibJS+LibWeb: Implement resizable ArrayBuffer support for TypedArray
This is (part of) a normative change in the ECMA-262 spec. See:
a9ae96e
2023-12-26 11:16:10 +01:00
Timothy Flynn
c7fec9424c LibJS+LibWeb: Implement resizable ArrayBuffer support for DataView
This is (part of) a normative change in the ECMA-262 spec. See:
a9ae96e
2023-12-26 11:16:10 +01:00
Timothy Flynn
29ac6e3689 LibJS: Partially implement resizable ArrayBuffer objects
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.
2023-12-26 11:16:10 +01:00
Timothy Flynn
98cdf36fb0 LibJS: Rename TypedArray element get and set methods
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:
03e4410
a1a4d48

The remainder of the changes in those commits apply to the resizable
ArrayBuffer spec, which is not implemented in LibJS as of this commit.
2023-12-26 11:16:10 +01:00
Timothy Flynn
4f32392426 LibJS: Update spec headers of ArrayBuffer, TypedArray, DataView, Atomics
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.
2023-12-26 11:16:10 +01:00
Shannon Booth
95e9c89a15 LibJS: Update spec comments in Array.fromAsync
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.
2023-12-23 20:22:42 -05:00
Andreas Kling
f4fa37afd2 LibJS+LibWeb: Add missing JS_DEFINE_ALLOCATOR() for a bunch of classes 2023-12-23 23:02:10 +01:00
Shannon Booth
e2e7c4d574 Everywhere: Use to_number<T> instead of to_{int,uint,float,double}
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.
2023-12-23 20:41:07 +01:00
Andrew Kaster
82ec1ea75e LibJS: Provide better assertion for empty execution context stack
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.
2023-12-19 21:08:05 +01:00
Andrew Kaster
d361221657 LibJS+LibWeb: Add JS::Value constructor for `JS::Handle<T>`
Similar to the constructors for ``JS::{Nonnull}GCPtr<T>``, this helper
avoids unnecessary .ptr() clutter when we want to construct Values.
2023-12-19 09:21:55 -07:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
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')
2023-12-17 18:25:10 +03:30
Andreas Kling
1e90379008 LibJS: Introduce "dictionary" mode for object shapes
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 :^)
2023-12-16 14:25:58 +01:00
Aliaksandr Kalenik
b108d51c5b LibJS: Only consider VM-accessible execution contexts as strong roots
Partially reverts 3dc5f467a8 to fix
GC memory leak that happens because we treated all execution contexts
as strong roots.
2023-12-13 11:19:13 +01:00
Andreas Kling
ed1bee222b LibJS: Give Shape::TransitionType an underlying 8-bit type
This shrinks Shape by 8 bytes. :^)
2023-12-12 15:26:46 +01:00
Andreas Kling
8eacb81eba LibJS: Skip redundant marking of Shape property table keys
All the keys in a property table are guaranteed to be marked via
Shape::m_property_key in each step of the transition chain that leads
up to the Shape.
2023-12-11 20:36:15 +01:00
Andreas Kling
3d92c26445 LibJS: Stop making shapes unique
We previously had a concept of unique shapes, which meant that they
couldn't be shared between multiple objects.

Object shapes became unique in three situations:

- They were the shape of the global object.
- They had more than 100 properties added to them.
- They had one or more properties deleted from them.

Unfortunately, unique shapes presented an annoying problem for inline
caches, and we added a "unique shape serial number" for being able to
tell that a unique shape had been mutated.

This patch gets rid of the concept of unique shapes, simplifying all
the caching code, since inline caches can now simply perform a shape
check and then we're good.

To make this possible, we now have the concept of delete transitions,
which occur when a property is deleted from a shape.

Note that this patch by itself introduces a performance regression in
some situtations, since we now create a lot more shapes, and marking
their property keys can be very heavy. This will be addressed in a
subsequent patch.
2023-12-11 20:36:15 +01:00
Andreas Kling
ef86cf4646 LibJS: Mark forward shape transition keys
These should really be weakly held by the Shape, but we don't have a
mechanism for weak hashmap keys at the moment, so let's just mark
these for now so they don't go stale.
2023-12-11 20:36:15 +01:00
Andreas Kling
463931384d LibJS: Don't use Handle<Value> for JS::Object private fields
There's no reason to use handles here, we can just mark private element
values from objects that store them.
2023-12-10 09:44:26 +01:00
Andreas Kling
d8be9ebc16 LibJS: Add fast path in ArrayIteratorPrototype::next()
When iterating over vanilla objects/arrays with normal property storage,
we can skip the generic Get mechanism in favor of looking directly at
property storage. This is essentially what we do in the bytecode path.
2023-12-09 00:20:25 +01:00
Andreas Kling
373ec387c1 LibJS: Add fast_is<ArrayIterator>() 2023-12-09 00:20:25 +01:00
Andreas Kling
73ceb475b9 LibJS: Add fast path for magical "length" property in LengthOfArrayLike
For Array objects, we can avoid a generic Get here since we know it has
magical "length" behavior anyway.
2023-12-09 00:20:25 +01:00
Andreas Kling
f47a14b9d6 LibJS: Use a premade shape when creating iterator result objects
Instead of going through the steps of creating an empty new object,
and adding two properties ("value" and "done") to it, we can pre-bake
a shape object and cache the property offsets.

This makes creating iterator result objects in the runtime much faster.

47% speedup on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
2023-12-08 00:54:05 +01:00
Dan Klishch
96d44b1572 Userland: Make bit-fields compatible with MSVC C++ ABI 2023-12-07 10:28:19 -07:00
Andreas Kling
4699c81fc1 LibJS: Stop converting between Object <-> IteratorRecord all the time
This patch makes IteratorRecord an Object. Although it's not exposed to
author code, this does allow us to store it in a VM register.

Now that we can store it in a VM register, we don't need to convert it
back and forth between IteratorRecord and Object when accessing it from
bytecode.

The big win here is avoiding 3 [[Get]] accesses on every iteration step
of for..of loops. There are also a bunch of smaller efficiencies gained.

20% speed-up on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
2023-12-07 14:06:34 +01:00
Andreas Kling
a2c3db8367 LibJS: Add basic support for module code with top-level await
For now, we handle this by creating a synthetic async function to wrap
the top-level module code. This allows us to piggyback on the async
function driver wrapper mechanism.
2023-12-06 12:58:04 +01:00
Andreas Kling
26c21fba8e LibJS: Use LoadRequestedModules in the ad-hoc module loading path
This ensures that modules go through the expected state transitions,
fixing hundreds of test262 tests.
2023-12-06 12:58:04 +01:00
Andreas Kling
58294db294 LibJS: Add successfully loaded modules to the VM's stored module list
This ensures that repeated loads of the same module succeed. (There is a
specific criteria where the same exact module object has to be returned
for multiple loads of the same referrer + specifier.)

Note that we don't check the referrer at the moment, that's a FIXME.
2023-12-03 20:46:55 +01:00
Andreas Kling
8b7d27b349 LibJS+LibWeb: More bringing module loading closer to spec
In particular, this patch removes three host hooks on JS::VM in favor
of the new JS-side module loading stuff.
2023-12-03 20:46:55 +01:00
Andreas Kling
07f567cd9f LibJS+LibWeb: Another round of bringing module loading closer to spec
In particular, this patch focuses on:
- Updating the old "import assertions" to the new "import attributes"
- Allowing realms as module import referrer
2023-12-03 20:46:55 +01:00
Andreas Kling
0817d8bda6 LibJS+LibWeb: Make CyclicModule & GraphLoadingState GC-allocated
This allows them to participate in the ownership graph and fixes a
lifetime issue in module loading found by ASAN.

Co-Authored-By: networkException <networkexception@serenityos.org>
2023-12-03 20:46:55 +01:00
Todderod
e335354b30 LibJS: Call builtins directly in the bytecode interpreter
Allows the bytecode interpreter to call the builtins c++
implementation directly without making a javascript call
just as the JIT.

Kraken test speedups: imaging-gaussian-blur.js (1.5x) and
audio-oscillator.js (1.2x)
2023-12-01 13:01:26 +01:00
Timothy Flynn
026363024f LibJS: Stub out Atomics.notify
We don't have the facilities to implement this method fully (namely, a
fully realized SharedArrayBuffer). But we can implement enough to
validate the values passed in by the user.
2023-11-30 09:51:46 -05:00
Timothy Flynn
78edaad97d LibJS: Stub out Atomics.wait and Atomics.waitAsync
We don't have the facilities to implement these methods fully (namely, a
fully realized SharedArrayBuffer). But we can implement enough to
validate the values passed in by the user.
2023-11-30 09:51:46 -05:00
Timothy Flynn
a7073c3f1f LibJS: Skip test262 tests with the CanBlockIsFalse flag
From test262 documentation, this flag means:

    The test file should only be run when the [[CanBlock]] property of
    the Agent Record executing the file is `false`.

This patch stubs out the accessor for that internal slot and skips tests
with the CanBlockIsFalse if that internal slot is true.
2023-11-30 09:51:46 -05:00
Andreas Kling
be8952b89d LibJS: Remove pointless Vector copy in FDI 2023-11-29 09:48:18 +01:00
Andreas Kling
aaa7b50f06 LibJS: Skip lexical declaration traversal in FDI if there are none 2023-11-29 09:48:18 +01:00
Andreas Kling
3b6785245f LibJS: Don't call shrink_to_fit() on same environment twice in FDI 2023-11-29 09:48:18 +01:00
Andreas Kling
3fc0333ee6 LibJS: Put Bytecode::CallFrame + register slots in a single allocation
The number of registers in a call frame never changes, so we can
allocate it at the end of the CallFrame object and save ourselves the
cost of allocating separate Vector storage for every call frame.
2023-11-29 09:48:18 +01:00
Andreas Kling
3dc5f467a8 LibJS: Always allocate ExecutionContext objects on the malloc heap
Instead of allocating these in a mixture of ways, we now always put
them on the malloc heap, and keep an intrusive linked list of them
that we can iterate for GC marking purposes.
2023-11-29 09:48:18 +01:00
Andreas Kling
845da3901d LibJS: Make ExecutionContext::function_name a GCPtr<PrimitiveString>
This required setting things up so that all function objects can plop
a PrimitiveString there instead of an AK string.

This is a step towards making ExecutionContext easier to allocate.
2023-11-29 09:48:18 +01:00
Andreas Kling
eda2a6d9f7 LibJS: Don't die when making PrimitiveString from "" DeprecatedFlyString 2023-11-29 09:48:18 +01:00
Andreas Kling
ecfcc9aef3 LibJS: Make Bytecode::Executable GC-allocated
This is a step towards making ExecutionContext easier to allocate.
2023-11-29 09:48:18 +01:00
Andreas Kling
ece961f882 LibJS: Pass call/construct argument lists as ReadonlySpan<Value>
(Instead of MarkedVector<Value>.) This is a step towards not storing
argument lists in MarkedVector<Value> at all. Note that they still end
up in MarkedVectors since that's what ExecutionContext has.
2023-11-29 09:48:18 +01:00
Andreas Kling
4cce181ece LibJS: Devirtualize Object::is_typed_array() 2023-11-26 19:32:51 +01:00