Commit graph

1102 commits

Author SHA1 Message Date
Timothy Flynn
f7517c5b8d LibJS: Remove our existing Temporal implementation
Our Temporal implementation is woefully out of date. The spec has been
so vastly rewritten that it is unfortunately not practical to update our
implementation in-place. Even just removing Temporal objects that were
removed from the spec, or updating any of the simpler remaining objects,
has proven to be a mess in previous attempts.

So, this removes our Temporal implementation. AOs used by other specs
are left intact.
2024-11-20 19:04:30 -05:00
rmg-x
74b27d620d LibJS: Parse dates like "Wed Nov 20 2024" 2024-11-20 09:20:48 +00:00
Timothy Flynn
be09893fa7 AK+LibJS: Don't use Temporal for console.time() and console.timeLog()
We don't need nanosecond precision here anyways, as we only display
millisecond resolution.

This uses our simple duration formatter from AK, which is updated to
accept a Duration here. This method did not have any users after the
move from Serenity.
2024-11-18 17:46:41 -05:00
Timothy Flynn
8bd394f349 LibJS: Use an Intl prototype for a Function.prototype.toString test
The Temporal.TimeZone object no longer exists in the Temporal spec.
2024-11-18 17:46:41 -05:00
Timothy Flynn
ed76e1ed4b LibJS: Use Date for timing test-js tests
Stop relying on Temporal, at least temporarily. The classes used here
will soon be removed (until they are implemented again from scratch).
2024-11-18 17:46:41 -05:00
Timothy Flynn
dd6acfecd4 LibJS: Don't use Temporal to parse UTC offset strings
The production for these strings has been removed from Temporal. This
implements a separate parser in accordance with the Date spec.
2024-11-18 17:46:41 -05:00
Timothy Flynn
f88826691c LibJS: Remove usage of obsolete Duration record from Intl.DurationFormat
The Duration record no longer exists in Temporal. Implement it according
to the DurationFormat spec to prepare for its removal from our Temporal
implementation.

We also implement the DurationSign AO here as well, as the Temporal
implementation will now require a Temporal.Duration JS object.
2024-11-18 17:46:41 -05:00
Timothy Flynn
59e0b7ccb7 LibJS: Remove unused Temporal inclusion from Intl 2024-11-18 17:46:41 -05:00
Lucien Fiorini
ff791a63fc LibJS: Add fast paths for get and set on float typed arrays 2024-11-18 09:12:05 +01:00
Shannon Booth
fd0c63b338 LibJS: Align spec comments for ShadowRealm for HostInitializeShadowRealm
The proposed changes have been merged into the proposal with:

https://github.com/tc39/proposal-shadowrealm/commit/f20d02
2024-11-17 22:15:22 +01:00
Luke Wilde
6319dedbcd LibJS: Perform TLA async function construction in the module context
Previously it was only pushing the module context for the call to
capture the module execution context. This is incorrect, as the capture
occurs upon function construction. This resulted in it capturing the
execution context that execute_module was called from, instead of the
newly created module_context.
f87041bf3a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp (L92)

This can be demonstrated with the following setup:
index.html:
```html
<script>
    var foo = 1;
</script>
<script type="module">
    import {test} from "./scriptA.mjs";
</script>
```

scriptA.mjs:
```js
function foo() {
	return {a: "b"};
}
export let test = await foo();
```

Before this fix, this would throw:
```
[TypeError] 1 is not a function (evaluated from 'foo')
    at module code with top-level await
    at module code with top-level await
    at <unknown>
    at <unknown>
```

Fixes #2245.
2024-11-15 18:52:22 +01:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
Shannon Booth
c2988a7dd5 LibJS: Don't directly teach the heap about the javascript VM or Realm
Instead, smuggle it in as a `void*` private data and let Javascript
aware code cast out that pointer to a VM&.

In order to make this split, rename JS::Cell to JS::CellImpl. Once we
have a LibGC, this will become GC::Cell. CellImpl then has no specific
knowledge of the VM& and Realm&. That knowledge is instead put into
JS::Cell, which inherits from CellImpl. JS::Cell is responsible for
JavaScript's realm initialization, as well as converting of the void*
private data to what it knows should be the VM&.
2024-11-14 15:38:45 +01:00
Shannon Booth
ae6d105f41 LibJS: Use a Function to indirectly let Heap visit VM's GC roots
This allows the heap to mark cells that it needs to mark as roots
without needing to directly reference the VM.
2024-11-14 15:38:45 +01:00
Shannon Booth
0bf2a8362a LibJS: Make Value inherit from a NanBoxedValue
NanBoxedValue is intended to be a GC-allocatable type which is not
specific to javascript, towards the effort of factoring out the GC
implementation from LibJS.
2024-11-14 15:38:45 +01:00
Shannon Booth
c0bcebeb08 LibJS: Add const versions of Cell::visit 2024-11-14 15:38:45 +01:00
Shannon Booth
1e54003cb1 LibJS+LibWeb: Rename Heap::allocate_without_realm to Heap::allocate
Now that the heap has no knowledge about a JavaScript realm and is
purely for managing the memory of the heap, it does not make sense
to name this function to say that it is a non-realm variant.
2024-11-13 16:51:44 -05:00
Shannon Booth
9b79a686eb LibJS+LibWeb: Use realm.create<T> instead of heap.allocate<T>
The main motivation behind this is to remove JS specifics of the Realm
from the implementation of the Heap.

As a side effect of this change, this is a bit nicer to read than the
previous approach, and in my opinion, also makes it a little more clear
that this method is specific to a JavaScript Realm.
2024-11-13 16:51:44 -05:00
Shannon Booth
eef9a53eec LibJS: Make Heap own its own StackInfo instance
While this does mean that we keep one copy of the stack info in the VM,
and another in the Heap; keeping a separate instance removes one more
instance of coupling between the heap and LibJS specific details.
2024-11-13 11:08:35 +01:00
Shannon Booth
d199bf60cf LibJS: Do not clear VM's string cache in Heap's destructor
There is definitely a possibility I am misunderstanding the reason
behind it - but this does not appear neccessary. The VM owns both the
string cache and Heap. On destruction, the VM should clear out both
the heap and its string cache.
2024-11-13 11:08:35 +01:00
Shannon Booth
cf27eef583 LibJS: Move WeakContainer into the Heap folder
While this is used in the implementation of Runtime objects itself, Heap
seems like a more appropriate home. This will also help in factoring out
the GC implementation into it's own library as the heap explicitly has
knowledge of WeakContainer.
2024-11-13 11:08:35 +01:00
Shannon Booth
2f6bcb3538 LibJS: Remove some unused runtime headers from Heap folder 2024-11-13 11:08:35 +01:00
Shannon Booth
520aa04092 LibJS: Move Handle's Value specialization to Value header
This is part of an effort to keep JS runtime specifics outside of the
Heap implementation.
2024-11-13 11:08:35 +01:00
Hermes Junior
77a46ab1b8 LibJS: Correctly return cached value for global var bindings
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
When the cached value was not an accessor, it was simply ignored.
This is the value we really want, so we can just return it.
Shows up to 5x improvements on some benchmarks,
and 1.4x in general js-benchmarks.
2024-11-12 21:13:48 +01:00
Andreas Kling
b6a5b7e186 LibJS: Stop having AsyncFunctionDriverWrapper leak itself
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Async functions whose promise is never resolved were leaking, since they
had a strong root JS::Handle on themselves.

This doesn't appear to actually be necessary, since the wrapper will be
kept alive as long as it's reachable (and if it's not reachable, nobody
is going to resolve/reject the promise either).

This fixes the vast majority of leaks on Speedometer, bringing memory
usage at the end of a full run from ~12 GiB to ~3 GiB.
2024-11-12 17:38:21 +01:00
Andreas Kling
10724a7cb3 LibJS: Use ConservativeVector when instantiating static class fields
This fixes an issue where a badly-timed garbage collection could swallow
a static field initializer.

Caught by running test262 in GC-on-every-allocation mode.
2024-11-12 17:38:21 +01:00
Andreas Kling
2fb3b6c542 LibJS: Make ConservativeVector<T> visit all possible values
We were miscalculating the length of the buffer in pointer-sized chunks,
which is what the conservative root scan cares about.

This could cause some values to be prematurely garbage-collected.
2024-11-12 17:38:21 +01:00
Luke Wilde
956b279ae1 LibJS: Parse dates like "November 19 2024 00:00:00 +0900"
This format is used on https://jojowiki.com/ to show countdowns to new
releases.
2024-11-12 13:23:34 +01:00
Andreas Kling
6a6618f5ea LibJS: Add RawNonnullGCPtr<T>
This is really just a type alias for NonnullGCPtr<T>, but it provides
a way to have non-owning non-visited NonnullGCPtr<T> without getting
yelled at by the Clang plugin for catching GC errors.
2024-11-11 21:40:56 +01:00
Andreas Kling
e240084437 LibJS: Use correct cell address for HeapFunction captures in GC dumps
We were previously dumping the address of the cell pointer instead of
the address of the cell itself. This was causing mysterious orphans
in GC dumps, and it took me way too long to figure this out.
2024-11-11 21:40:56 +01:00
Luke Wilde
bd4c29322c LibJS: Allow division after IdentifierNames in optional chain
The following syntax is valid:
```js
e?.example / 1.2
```

Previously, the `/` would be treated as a unterminated regex literal,
because it was calling the regular `consume` instead of
`consume_and_allow_division`.

This is what is done when parsing IdentifierNames in
parse_secondary_expression when a period is encountered.

Allows us to parse clients-main-[hash].js on https://ubereats.com/
2024-11-11 20:19:26 +01:00
rmg-x
ea20545853 LibJS: Add support for Float16Array
Implements TC39 stage three proposal for Float16Arrays:
https://tc39.es/proposal-float16array
2024-11-10 14:48:20 -07:00
Andreas Kling
5aa1d7837f LibJS: Don't leak class field initializers
We were storing these in Handle (strong GC roots) hanging off of
ECMAScriptFunctionObject which effectively turned into world leaks.
2024-11-10 19:12:59 +01:00
Shannon Booth
e02ca0480f LibJS: Allow unpaired surrogates in String.prototype.replace
This was resulting in a crash for the WPT test case:

https://wpt.live/xhr/send-data-string-invalid-unicode.any.html
2024-11-10 09:14:03 -05:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Lenny Maiorani
e6f907a155 AK: Simplify constructors and conversions from nullptr_t
Problem:
- Many constructors are defined as `{}` rather than using the ` =
  default` compiler-provided constructor.
- Some types provide an implicit conversion operator from `nullptr_t`
  instead of requiring the caller to default construct. This violates
  the C++ Core Guidelines suggestion to declare single-argument
  constructors explicit
  (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c46-by-default-declare-single-argument-constructors-explicit).

Solution:
- Change default constructors to use the compiler-provided default
  constructor.
- Remove implicit conversion operators from `nullptr_t` and change
  usage to enforce type consistency without conversion.
2021-01-12 09:11:45 +01:00
Linus Groh
f369229770 LibJS: Replace all uses of to_size_t() and remove it :^)
Yay for more spec compliance! This is pretty easy as everything using
to_size_t() should just be using one of the other abstract operations we
already have implemented.
This allows us to get rid of get_length() in ArrayPrototype, which is
basically a slightly incorrect implementation of length_of_array_like(),
and then finally remove to_size_t()!
Also fixes a couple of "argument is undefined" vs "argument isn't given"
issues along the way.
2021-01-10 21:57:03 +01:00
Linus Groh
9be0b664e3 LibJS: Make length_of_array_like() take an Object rather than Value
The pseudo-code from the spec says "Assert: Type(obj) is Object.", so we
can just enforce this at compile time rather than taking it literally
and doing "ASSERT(value.is_object())".

Also fix an issue where the absence of a "length" property on the object
would cause a crash (to_number() on empty value).
2021-01-10 21:57:03 +01:00
Marcin Gasperowicz
b24ce0b5ee LibJS: Implement String.prototype.split
This adds a String.prototype.split implementation modelled after 
ECMA262 specification. 

Additionally, `Value::to_u32` was added as an implementation of
the standard `ToUint32` abstract operation.

There is a tiny kludge for when the separator is an empty string. 
Basic tests and visiting google.com prove that this is working.
2021-01-10 21:27:59 +01:00
asynts
1160817a9e AK: Add Formatter<FormatString> as helper class. 2021-01-09 21:11:09 +01:00
Linus Groh
7b2fdd08ce LibJS: Add tests for bitwise NOT operator 2021-01-09 19:09:02 +01:00
Linus Groh
9fca86109b LibJS: Make bitwise NOT work correctly with NaN and Infinity
This was missing a "toInt32()" which returns 0 for NaN and Infinity.
From the spec:

    6.1.6.1.2 Number::bitwiseNOT ( x )

    The abstract operation Number::bitwiseNOT takes argument x (a Number).
    It performs the following steps when called:

        Let oldValue be ! ToInt32(x).
        Return the result of applying bitwise complement to oldValue.
        The mathematical value of the result is exactly representable as
        a 32-bit two's complement bit string.

Fixes #4868.
2021-01-09 19:09:02 +01:00
Linus Groh
c55cb7843a LibJS: Use INVALID some more in abstract operations 2021-01-09 19:09:02 +01:00
Andreas Kling
7ed89703fe LibCrypto+LibJS: Fix broken subtraction of two negative signed bigints
Found by oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29326
2021-01-07 08:57:37 +01:00
Andreas Kling
51b880b038 LibJS: Disable ASAN during the conservative GC stack scan
This allows the JS fuzzer to survive garbage collection (so we can find
more interesting bugs!)

Found by oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29266
2021-01-05 12:27:45 +01:00
Andreas Kling
fdd974b7ef LibJS: Fix UB downcast during GlobalObject construction
When constructing a GlobalObject, it has to pass itself as the global
object to its own Shape. Since this is done in the Object constructor,
and Object is a base class of GlobalObject, it's not yet valid to cast
"this" to a GlobalObject*.

Fix this by having Shape store the global object as an Object& and move
Shape::global_object() to GlobalObject.h where we can at least perform a
valid static_cast in the getter.

Found by oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29267
2021-01-05 12:02:59 +01:00
Andreas Kling
db790dda62 LibJS: Remove hand-rolled type information in JS AST in favor of RTTI 2021-01-01 19:34:07 +01:00
Andreas Kling
d2613403e0 LibJS+LibWeb: Stop generating is_foo_wrapper() for JS DOM wrappers 2021-01-01 18:06:38 +01:00
Andreas Kling
f48751a739 LibJS: Remove hand-rolled Object is_foo() helpers in favor of RTTI 2021-01-01 17:46:39 +01:00