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

2012 commits

Author SHA1 Message Date
Linus Groh
2c222ba40b LibJS: Implement Temporal.PlainYearMonth.prototype.toPlainDate() 2021-10-11 08:31:39 +01:00
Linus Groh
99adb54391 LibJS: Implement Temporal.Calendar.prototype.dateUntil() 2021-10-11 08:31:39 +01:00
Brian Gianforcaro
1b00ddf07e LibJS: Optimize PropertyName and StringPrototype for size
We can reduce the amount of padding the compiler adds in order to
ensure data alignment of member variables by ordering the types in
a struct by size in decending order.

Found By PVS-Studio: https://pvs-studio.com/en/docs/warnings/v802/
2021-10-10 13:48:04 +02:00
Linus Groh
01370136ee LibJS: Convert delete_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
f35e268024 LibJS: Convert get_binding_value() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
7652138ce0 LibJS: Convert set_mutable_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
ae397541fb LibJS: Convert initialize_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
2691c65639 LibJS: Convert create_immutable_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
4baf3a91e8 LibJS: Convert create_mutable_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
fbb176c926 LibJS: Convert has_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
617d3cd3d3 LibJS: Convert bind_this_value() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
0aa24f4ce5 LibJS: Convert get_this_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
4f03138971 LibJS: Convert get_super_base() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-09 21:53:47 +01:00
Linus Groh
a456eae4b1 LibJS: Remove unused FunctionEnvironment::replace_this_binding() 2021-10-09 21:53:47 +01:00
Linus Groh
9d352c602c LibJS: Add callee realm fallback to ordinary_call_bind_this()
This makes ECMAScriptFunctionObject calls in the bytecode interpreter
work again (regressed in #10402).
2021-10-09 15:18:29 +01:00
Linus Groh
fe5c2b7bb9 LibJS: Decouple new_function_environment() from FunctionObject
Now that only ECMAScriptFunctionObject uses this, we can remove the
FunctionObject::new_function_environment() pure virtual method and just
implement it as a standalone AO with an ECMAScriptFunctionObject
parameter, next to the other NewFooEnvironment AOs.
2021-10-09 14:29:20 +01:00
Linus Groh
53af66d57d LibJS: Move ordinary_call_bind_this() to ECMAScriptFunctionObject
Now that it only needs to deal with ECMAScriptFunctionObject via
internal_call() / internal_construct(), we can:

- Remove the generic FunctionObject parameter
- Move it from the VM to ECMAScriptFunctionObject
- Make it private
2021-10-09 14:29:20 +01:00
Linus Groh
25bcd36116 LibJS: Move prepare_for_ordinary_call() to ECMAScriptFunctionObject
Now that it only needs to deal with ECMAScriptFunctionObject via
internal_call() / internal_construct(), we can:

- Remove the generic FunctionObject parameter
- Move it from the VM to ECMAScriptFunctionObject
- Make it private
2021-10-09 14:29:20 +01:00
Linus Groh
cf168fac50 LibJS: Implement [[Call]] and [[Construct]] internal slots properly
This patch implements:

- Spec compliant [[Call]] and [[Construct]] internal slots, as virtual
  FunctionObject::internal_{call,construct}(). These effectively replace
  the old virtual FunctionObject::{call,construct}(), but with several
  advantages:
  - Clear and consistent naming, following the object internal methods
  - Use of completions
  - internal_construct() returns an Object, and not Value! This has been
    a source of confusion for a long time, since in the spec there's
    always an Object returned but the Value return type in LibJS meant
    that this could not be fully trusted and something could screw you
    over.
  - Arguments are passed explicitly in form of a MarkedValueList,
    allowing manipulation (BoundFunction). We still put them on the
    execution context as a lot of code depends on it (VM::arguments()),
    but not from the Call() / Construct() AOs anymore, which now allows
    for bypassing them and invoking [[Call]] / [[Construct]] directly.
    Nothing but Call() / Construct() themselves do that at the moment,
    but future additions to ECMA262 or already existing web specs might.
- Spec compliant, standalone Call() and Construct() AOs: currently the
  closest we have is VM::{call,construct}(), but those try to cater to
  all the different function object subclasses at once, resulting in a
  horrible mess and calling AOs with functions they should never be
  called with; most prominently PrepareForOrdinaryCall and
  OrdinaryCallBindThis, which are only for ECMAScriptFunctionObject.

As a result this also contains an implicit optimization: we no longer
need to create a new function environment for NativeFunctions - which,
worth mentioning, is what started this whole crusade in the first place
:^)
2021-10-09 14:29:20 +01:00
Linus Groh
58c34012dd LibJS: Pop execution context after running queued jobs in run()
These would crash starting with the next commit otherwise, calling a
function always requires the running execution context to exist.
2021-10-09 14:29:20 +01:00
Linus Groh
72f5252826 LibJS: Forward BoundFunction::has_constructor() to bound target function
A BoundFunction only implements [[Construct]] (has_constructor() in
LibJS) if its bound target function does.
2021-10-09 14:29:20 +01:00
Linus Groh
7fc2807929 LibJS: Add Completion::is_abrupt()
This is commonly used in the spec.
2021-10-09 14:29:20 +01:00
Linus Groh
5b61b60bbd LibJS: Use AllocateArrayBuffer where the spec tells us to 2021-10-09 12:36:28 +01:00
Linus Groh
1fba5ca8c3 LibJS: Implement the AllocateArrayBuffer() AO
This should be used instead of ArrayBuffer::create() in most places, as
it uses OrdinaryCreateFromConstructor to allow for a custom prototype.

The data block (ByteBuffer) is allocated separately and attached
afterwards, if we didn't fail due to OOM.
2021-10-09 12:36:28 +01:00
Andreas Kling
eafbf372d0 LibJS: Elide empty declarative environments inside switch statements
Most switch statements don't have any lexically scoped declarations,
so let's avoid allocating an environment in the common case where we
don't have to.
2021-10-09 00:42:10 +02:00
Nico Weber
b8dc3661ac Libraries: Fix -Wunreachable-code warnings from clang 2021-10-08 23:33:46 +02:00
Andreas Kling
2495460f6e LibJS: Prune WeakContainers before freeing HeapBlocks
WeakContainers need to look at the Cell::State bits to know if their
weak pointees got swept by garbage collection. So we must do this before
potentially freeing one or more HeapBlocks by notifying the allocator
that a block became empty.
2021-10-08 19:47:25 +02:00
Ali Mohammad Pur
13138811df LibJS: Partially revert 12b283f
This commit partially reverts "LibJS: Make accessing the current
function's arguments cheaper".
While the change passed all the currently passing test262 tests, it
seems to have _some_ flaw that silently breaks with some real-world
websites.
As the speedup with negligible at best, let's just revert it until we
can implement it more correctly.
2021-10-08 19:56:02 +03:30
Andreas Kling
fa6c06ce8d LibJS: Elide some declarative environments in ECMAScript function calls
By spec, calling an ECMAScript function object in non-strict mode should
always create a new top-level declarative environment, even if there are
no lexically scoped bindings (let/const) that belong in it. This is
used for scope disambiguation in direct eval() calls.

However, if there are no direct eval() calls within the function, and no
lexically scoped bindings, we can simply not allocate the extra
environment and save ourselves the trouble.
2021-10-08 15:00:34 +02:00
Andreas Kling
b2de563166 LibJS: Propagate "contains direct call to eval()" flag from parser
We now propagate this flag to FunctionDeclaration, and then also into
ECMAScriptFunctionObject.

This will be used to disable optimizations that aren't safe in the
presence of direct eval().
2021-10-08 12:43:38 +02:00
Ali Mohammad Pur
12b283f32f LibJS: Make accessing the current function's arguments cheaper
Instead of going through an environment record, make arguments of the
currently executing function generate references via the argument index,
which can later be resolved directly through the ExecutionContext.
2021-10-08 12:25:24 +02:00
Ali Mohammad Pur
da296ffd56 LibJS: Treat the Catch binding identifier as a var binding 2021-10-08 12:25:24 +02:00
Ali Mohammad Pur
6ab6321c2f LibJS: Remove redundant const_cast
The accessed field is mutable, so there's no need for this const_cast.
2021-10-08 12:25:24 +02:00
Andreas Kling
c27f91142d LibJS: Add ScopeNode accessors for declaration counts 2021-10-08 02:22:02 +02:00
Andreas Kling
7de2a84cd4 LibJS: Add missing initializer for ParserState::m_current_scope_pusher 2021-10-08 01:55:24 +02:00
Andreas Kling
b00b461b31 LibJS: Pre-size a HashTable in function_declaration_instantiation()
The dynamic resizing of this hash table was showing up in profiles.
Since we have an idea of how big it will get, use ensure_capacity().
2021-10-08 01:32:12 +02:00
Andreas Kling
70e25deea3 LibJS: Avoid a FlyString copy in ECMAScriptFunctionObject 2021-10-08 01:31:39 +02:00
Andreas Kling
23f4ff7247 LibJS: Make BlockAllocator cache reuse blocks in random order 2021-10-08 00:35:29 +02:00
Andreas Kling
17f239e1c0 LibJS: Increase GC heap BlockAllocator cache size
Let's accept keeping up to 8 MiB of HeapBlock memory cached. This allows
the GC allocator to reuse memory instead of asking the kernel for more.
2021-10-08 00:35:29 +02:00
Andreas Kling
527a6f4ded LibJS: Add fast_is<T>() for FunctionDeclaration 2021-10-08 00:35:29 +02:00
Andreas Kling
e67155638c LibJS: Take advantage of Value::Type::Int32 in a bunch of functions
If a JS::Value has type Int32, we know it's a finite, 32-bit integer.
Use this information to avoid converting it to a double if possible.
2021-10-07 19:27:30 +02:00
Linus Groh
ef004c6b98 LibJS: Use round_number_to_increment(double) in round_time()
Much nicer :^)
2021-10-07 13:00:24 +01:00
Linus Groh
8b07453bce LibJS: Add non-BigInt overload of round_number_to_increment()
Unlike the spec we chose BigInt for the input and output types here as
it was being used with ℝ(ns), ns being of type BigInt, in one place and
a conversion to double would not be safe.
Since in many places we'll have double input values, let's add a double
overload of this function to avoid awkward conversions and expensive
allocations.
2021-10-07 13:00:24 +01:00
Andreas Kling
df674023d6 LibJS: Add fast_is<T>() for FunctionExpression and ClassExpression
Spotted RTTI for these two above 1% in a profile.
2021-10-07 12:05:13 +02:00
Andreas Kling
41a072bded LibJS: Fast non-local variable access :^)
This patch introduces the "environment coordinate" concept, which
encodes the distance from a variable access to the binding it ends up
resolving to.

EnvironmentCoordinate has two fields:

    - hops:  The number of hops up the lexical environment chain we have
             to make before getting to the resolved binding.

    - index: The index of the resolved binding within its declarative
             environment record.

Whenever a variable lookup resolves somewhere inside a declarative
environment, we now cache the coordinates and reuse them in subsequent
lookups. This is achieved via a coordinate cache in JS::Identifier.

Note that non-strict direct eval() breaks this optimization and so it
will not be performed if the resolved environment has been permanently
screwed by eval().

This makes variable access *significantly* faster. :^)
2021-10-07 11:53:18 +02:00
Andreas Kling
421845b0cd LibJS: Taint variable environment chain after non-strict direct eval()
Since non-strict direct eval() can insert new bindings into a
surrounding var scope, we cannot safely cache some assumptions about
environment chain layout after eval() has taken place.

Since eval() is rare, let's do what other engines do and simply
deoptimize in its presence. This patch adds a new "permanently screwed"
flag to JS::Environment that will be set on the entire variable
environment chain upon non-strict direct eval().
2021-10-07 11:53:18 +02:00
Ben Wiederhake
a95b321bf1 LibJS: Add missing headers 2021-10-06 23:52:40 +01:00
Andreas Kling
4444bcabde LibJS: Make Reference aware of DeclarativeEnvironment indices
VM::resolve_binding() can now return a Reference that knows the exact
binding index if it's pointing into a DeclarativeEnvironment.

Reading/writing through the Reference will now use direct environment
access when possible.
2021-10-07 00:23:36 +02:00
Andreas Kling
540ce075b6 LibJS: Add direct (indexed) binding accessors to DeclarativeEnvironment
This patch adds two DeclarativeEnvironment APIs:

- get_binding_value_direct()
- set_mutable_binding_direct()

These work identically to their non-direct-suffixed counterparts, but
take an index instead of a bound name. This will allow someone who has
a binding index to get/set that binding directly without any additional
hash lookups.
2021-10-07 00:23:36 +02:00
Andreas Kling
cb696eff08 LibJS: Make Environment::has_binding() optionally return binding index
If the caller wants to use the binding index for anything, if there is
such a thing, it can now be obtained via an optional out-parameter.
2021-10-07 00:23:36 +02:00