Commit graph

524 commits

Author SHA1 Message Date
Andreas Kling
8a5e71256d LibJS/Bytecode: Add codegen for ImportCall
Also moved most of the AST ImportCall::execute() into a helper so we can
share the code.
2023-06-24 17:13:30 +02:00
Luke Wilde
95d619943e LibJS/Bytecode: Support private identifiers in optional chaining
Fixes 4 test262 tests :^)
2023-06-23 21:05:18 +02:00
Andreas Kling
99b23fe2ad LibJS/Bytecode: Emit GetPrivateById for private member expressions
This makes it possible to call private member functions.

347 new passes on test262. :^)
2023-06-23 17:51:04 +02:00
Andreas Kling
85a3a1c085 LibJS/Bytecode: Add codegen for "named evaluation if anonymous function"
This gives anonymous functions the name from the LHS they are being
assigned to.

171 new passes on test262. :^)
2023-06-23 16:09:33 +02:00
Andreas Kling
e5c7d8407b LibJS/Bytecode: Support private class fields
This is accomplished with two new instructions:
- GetPrivateById
- PutPrivateById

Looks like 1616 new passes on test262. :^)
2023-06-23 08:53:10 +02:00
Andreas Kling
6537ed8fff LibJS/Bytecode: Simplify Bytecode::Interpreter lifetime model
The JS::VM now owns the one Bytecode::Interpreter. We no longer have
multiple bytecode interpreters, and there is no concept of a "current"
bytecode interpreter.

If you ask for VM::bytecode_interpreter_if_exists(), it will return null
if we're not running the program in "bytecode enabled" mode.

If you ask for VM::bytecode_interpreter(), it will return a bytecode
interpreter in all modes. This is used for situations where even the AST
interpreter switches to bytecode mode (generators, etc.)
2023-06-22 21:16:17 +02:00
Luke Wilde
357174d8fd LibJS/Bytecode: Actually get value from super base for computed property 2023-06-17 20:26:14 +02:00
Luke Wilde
1116ba191a LibJS/Bytecode: Implement optional chaining 2023-06-17 20:26:14 +02:00
Andreas Kling
eee4b6eca7 LibJS/Bytecode: Let var without initializer codegen to nothing
Otherwise we incorrectly overwrite the binding with `undefined` at the
point where the `var` statement is.

Fixes 9 test262 tests. :^)
2023-06-17 15:37:33 +02:00
Andreas Kling
9c568282dc Ladybird+LibJS: Add CLI option to run browser with LibJS bytecode VM
This required quite a bit of plumbing, but now you can run

    ladybird --use-bytecode
2023-06-17 14:16:45 +02:00
Andreas Kling
d89e0b36d4 LibJS/Bytecode: Support class field initializers
Fixes 513 test262 tests. :^)
2023-06-17 11:00:39 +02:00
Andreas Kling
82828ad936 LibJS/Bytecode: Extract accumulator value before incurring side effects
Many operations in JavaScript may incur side effects, including calling
arbitrary user code. Since the user code will clobber the accumulator,
we have to take care to extract anything we need from the accumulator
before doing anything that may have side effects.

Fixes 3 test262 tests. :^)
2023-06-17 11:00:39 +02:00
Andreas Kling
61148bce5f LibJS/Bytecode: Use the correct this value in GetById
The fix for this was to port the "don't create unnecessary FooObject
for property access on primitives" optimization from Reference,
which also brings us the correct behavior.
2023-06-16 21:46:43 +02:00
Andreas Kling
dbfe1311ef LibJS/Bytecode: Simplify creating/leaving lexical environment
Since we no longer need to create or leave var environments directly
in bytecode, we can streamline the two instructions by making them
always operate on the lexical environment.
2023-06-16 21:46:43 +02:00
Andreas Kling
12ce0789da LibJS/Bytecode: Remove BlockBoundaryType::LeaveVariableEnvironment
We never need to manually exit a var environment from bytecode anymore.
2023-06-16 21:46:43 +02:00
Andreas Kling
ac246d764d LibJS/Bytecode: Leave BlockDeclarationInstantiation in C++
Instead of implementing this AO in bytecode, we now have an instruction
for it that simply invokes the C++ implementation.

This allows us to simplify Bytecode::Generator quite a bit by removing
all the variable scope tracking.
2023-06-16 21:46:43 +02:00
Andreas Kling
d364d99cb8 LibJS/Bytecode: Perform ToNumeric on accumulator before postfix inc/dec
This ensures we get the expected behavior of code like:

    let a = []
    let b = a++

(Where b should be 0, not [], because JavaScript.)
2023-06-16 12:56:39 +02:00
Andreas Kling
c9bd324369 LibJS/Bytecode: Set "home object" of functions within object expression
We manage this by having a stack of home objects in Generator, and then
adding an optional home object parameter to the NewFunction instruction.
2023-06-16 12:56:39 +02:00
Andreas Kling
6f39882f11 LibJS/Bytecode: Fix multiple wrong jumps in ForStatement codegen 2023-06-16 08:40:45 +02:00
Andreas Kling
0772a23c65 LibJS/Bytecode: Add "raw" property correctly for tagged template literal
We were adding it to the wrong object before. :^)
2023-06-16 08:40:45 +02:00
Andreas Kling
2ac8a4bbb7 LibJS/Bytecode: Add support for direct eval()
This is implemented as a special mode of the Call opcode that invokes
the PerformEval AO (instead of the Call or Construct AO).
2023-06-16 08:40:45 +02:00
Andreas Kling
8a3e350321 LibJS/Bytecode: Don't choke on MemberExpression with PrivateIdentifier 2023-06-16 08:40:45 +02:00
Andreas Kling
d063f35afd LibJS/Bytecode: Leave GlobalDeclarationInstantiation in C++
Don't try to implement this AO in bytecode. Instead, the bytecode
Interpreter class now has a run() API with the same inputs as the AST
interpreter. It sets up the necessary environments etc, including
invoking the GlobalDeclarationInstantiation AO.
2023-06-16 08:40:45 +02:00
Andreas Kling
872d798951 LibJS/Bytecode: Leave FunctionDeclarationInstantantiation in C++
Instead of trying to implement this AO in bytecode, we can just let it
be a C++ thing. Once we implement fast uncaptured locals, we won't even
be calling it super often.
2023-06-16 08:40:45 +02:00
Andreas Kling
0d4c7fa392 LibJS/Bytecode: Make for..in iterate property names as string
Makes 107 new tests pass in test262. :^)
2023-05-26 17:52:51 +02:00
kleines Filmröllchen
213025f210 AK: Rename Time to Duration
That's what this class really is; in fact that's what the first line of
the comment says it is.

This commit does not rename the main files, since those will contain
other time-related classes in a little bit.
2023-05-24 23:18:07 +02:00
Luke Wilde
b15128c45b LibJS/Bytecode: Implement initial support for super member expressions 2023-05-16 11:26:31 +02:00
Andreas Kling
ce634957c1 LibJS/Bytecode: Restore old environments when an exception is caught
Unwind contexts now remember the lexical and variable environments in
effect when they were created. If an exception is caught, we revert
to those environments in the running execution context.
2023-05-14 06:18:28 +02:00
Andreas Kling
81a62f4f59 LibJS/Bytecode: Fix bogus program termination after try with catch
For `try` statements with a `catch` clause, we were generating *two*
"next" blocks. This meant that not throwing an exception would cause
execution to stop.

Fix this by using the "next" block pointer for the try "entry" and
"handler" blocks.
2023-05-14 06:18:28 +02:00
Andreas Kling
0b49b93e98 LibJS/Bytecode: Variable declarators should always prefer lexical env
This fixes an issue where object environments (from `with` statement)
were bypassed by statements like `var x = 1` (for objects with an `x`
property).

Fixes 25 tests in test262. :^)
2023-05-13 17:01:45 +02:00
Ben Wiederhake
7f70676123 LibJS: Revert to original text in spec
See also:
36ff6187f6
https://github.com/SerenityOS/serenity/pull/18682#issuecomment-1537249544
2023-05-07 11:57:08 +02:00
Ben Wiederhake
36ff6187f6 Everywhere: Change spelling of 'behaviour' to 'behavior'
"The official project language is American English […]."
5d2e915623/CONTRIBUTING.md (L30)

Here's a short statistic of the occurrences of the word "behavio(u)r":

$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
      2 BEHAVIOR
     24 Behaviour
     32 behaviour
    407 Behavior
    992 behavior

Therefore, it is clear that "behaviour" (56 occurrences) should be
regarded a typo, and "behavior" (1401 occurrences) should be preferred.

Note that The occurrences in LibJS are intentionally NOT changed,
because there are taken verbatim from the specification. Hence:

$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
      2 BEHAVIOR
     10 behaviour
     24 Behaviour
    407 Behavior
   1014 behavior
2023-05-07 01:05:09 +02:00
Daniel Bertalan
be7bc41470 LibJS: Fix mix-up between assignment and comparison 2023-05-02 07:03:57 -04:00
Linus Groh
e54536421a LibJS: Port iterator_next() to NonnullGCPtr 2023-04-15 16:22:57 +02:00
Linus Groh
b33b0d60e6 LibJS: Port Value::get_method() to GCPtr 2023-04-14 09:59:29 +02:00
Linus Groh
f345f72b55 LibJS: Port Value::to_object() to NonnullGCPtr 2023-04-14 09:59:29 +02:00
Hendiadyoin1
170f732000 LibJS: Fix a bunch of unwind related errors in GenerateCFG
We were missing some unwind related control flow paths, and followed
some in improper ways, leading us to access a dead unwind frame in some
cases, as well as generating a technically wrong CFG.

This reorders the ways EnterUnwindContext works and alleviates those
errors.
2023-03-17 09:57:51 +00:00
Matthew Olsson
7c0c1c8f49 LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtr 2023-03-15 08:48:49 +01:00
Andreas Kling
21db2b7b90 Everywhere: Remove NonnullOwnPtr.h includes 2023-03-06 23:46:35 +01:00
Andreas Kling
359d6e7b0b Everywhere: Stop using NonnullOwnPtrVector
Same as NonnullRefPtrVector: weird semantics, questionable benefits.
2023-03-06 23:46:35 +01:00
Andreas Kling
8a48246ed1 Everywhere: Stop using NonnullRefPtrVector
This class had slightly confusing semantics and the added weirdness
doesn't seem worth it just so we can say "." instead of "->" when
iterating over a vector of NNRPs.

This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
2023-03-06 23:46:35 +01:00
Luke Wilde
fb7aaeff3e LibJS/Bytecode: Return ThrowCompletionOr<void> from CreateVariable op 2023-02-27 23:57:08 +00:00
Luke Wilde
f4be95af69 LibJS: Don't discard ThrowCompletionOr<void> from declaration iteration 2023-02-27 23:57:08 +00:00
Hendiadyoin1
8e5ebb04f4 LibJS: Use a pseudo top-level UnwindFrame in GenerateCFG
Previously we assumed that there is always one such frame, now there is.
2023-02-26 23:09:37 +01:00
Hendiadyoin1
de514f29ad LibJS: Align codegen AwaitExpressions to YieldExpressions
We use generators in bytecode to approximate async functions, but the
code generated by AwaitExpressions did not have the value processing
paths that Yield requires, eg the `generator.throw()` path, which is
used by AsyncFunctionDriverWrapper to signal Promise rejections.
2023-02-26 19:40:09 +01:00
Hendiadyoin1
1f6a0ef6e0 LibJS: Don't enter finally blocks upon yield in bytecode mode 2023-02-26 19:40:09 +01:00
Hendiadyoin1
088dc1b24b LibJS: Simplify Generator::perform_needed_unwinds
This does not need to cater to the needs of `break` and `continue
anymore, which allows us to simplify it a bit.
2023-02-26 19:40:09 +01:00
Hendiadyoin1
d65488b80c LibJS: Generate unwind chains for continue in Bytecode
This works similar to `break`
The `try-finally-continue` still do not pass with this, likely because
of binding issues.
2023-02-26 19:40:09 +01:00
Hendiadyoin1
f5376cb282 LibJS: Generate unwind chains for break in Bytecode
This uses a newly added instruction `ScheduleJump`
This instruction tells the finally proceeding it, that instead of
jumping to it's next block it should jump to the designated block.
2023-02-26 19:40:09 +01:00
Hendiadyoin1
495ba53e46 LibJS: Correctly handle unwind frames in the GenerateCFG pass
To achieve this it now uses recursive descend, to make the state
managements easier.

With this we now correctly handle try-catch-finally blocks correctly,
modeling all possible controll flows between these blocks, which allows
analysis and optimization passes to make more accurate descisions about
accessibility of the enclosed blocks
2023-02-26 19:40:09 +01:00
Hendiadyoin1
5181957da5 LibJS: VERIFY on unknown terminator opcodes in GenerateCFG
If we mess up in here it could break promises later optimization stages
assume, so rather than having wrong results, make it scream as load as
it can.
2023-02-26 19:40:09 +01:00
Linus Groh
09d40bfbb2 Everywhere: Use _{short_,}string to create Strings from literals 2023-02-25 20:51:49 +01:00
Hendiadyoin1
5506951ffb LibJS: Don't try to merge unterminated BasicBlocks
This was causing a Segfault, trying to access the non-present terminator
2023-02-21 22:46:18 +01:00
Hediadyoin1
1c8adac442 LibJS: Use HashTable::take_first in GetObjectPropertyIterator
This is a bit more idiomatic than
```c++
auto it = table.begin();
auto k = *it;
table.remove(it);
```
and also saves us from copying the stored value.
2023-02-21 22:13:06 +01:00
Andreas Kling
bd5d8e9d35 LibJS: Make RefPtr and NonnullRefPtr usage const-correct
This mainly affected the AST, which is now const throughout.
2023-02-21 00:54:04 +01:00
Timothy Flynn
1400a85fae LibJS: Remove unused CodeGenerationError::to_deprecated_string 2023-02-17 09:14:23 -05:00
Timothy Flynn
88814acbd3 LibJS+Everywhere: Convert JS::Error to String
This includes an Error::create overload to create an Error from a UTF-8
StringView. If creating a String from that view fails, the factory will
return an OOM InternalError instead. VM::throw_completion can also make
use of this overload via its perfect forwarding.
2023-02-17 09:14:23 -05:00
Timothy Flynn
93ad25fbe5 LibJS: Add to_string definitions to CodeGenerationError and ParserError 2023-02-17 09:14:23 -05:00
Timothy Flynn
24e9cea524 LibJS: Convert remaining usages of Value::TDSWOSE to Value::TSWOSE
Note the couple of cases using MUST are just debugging statements.
2023-02-16 14:32:22 +01:00
Timothy Flynn
a73b8292ed LbJS: Convert exception-related usages of Value::TDSWOSE to String
TDSWOSE being to_deprecated_string_without_side_effects.
2023-02-16 14:32:22 +01:00
Timothy Flynn
b245300ba1 LibJS+Everywhere: Deprecate Value::to_string_without_side_effects 2023-02-16 14:32:22 +01:00
Timothy Flynn
c3abb1396c LibJS+LibWeb: Convert string view PrimitiveString instances to String
First, this adds an overload of PrimitiveString::create for StringView.
This overload will throw an OOM completion if creating a String fails.
This is not only a bit more convenient, but it also ensures at compile
time that all PrimitiveString::create(string_view) invocations will be
handled as String and OOM-aware.

Next, this wraps all invocations to PrimitiveString::create(string_view)
with MUST_OR_THROW_OOM.

A small PrimitiveString::create(DeprecatedFlyString) overload also had
to be added to disambiguate between the StringView and DeprecatedString
overloads.
2023-02-09 17:13:33 +00:00
MacDue
63b11030f0 Everywhere: Use ReadonlySpan<T> instead of Span<T const> 2023-02-08 19:15:45 +00:00
Linus Groh
6e7459322d AK: Remove StringBuilder::build() in favor of to_deprecated_string()
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
2023-01-27 20:38:49 +00:00
Timothy Flynn
0ddc2e1f50 LibCrypto+Everywhere: Rename *BigInteger::to_base to to_base_deprecated 2023-01-15 01:00:20 +00:00
Timothy Flynn
f3db548a3d AK+Everywhere: Rename FlyString to DeprecatedFlyString
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so
let's rename it to A) match the name of DeprecatedString, B) write a new
FlyString class that is tied to String.
2023-01-09 23:00:24 +00:00
Andrew Kaster
82a01bf32f LibJS: Use Core::ElapsedTimer in Bytecode::Pass instead of gettimeofday
We have a nice utility for doing exactly what this code is using, so
let's use it :^)
2023-01-07 14:51:04 +01:00
Ben Wiederhake
6fd478b6ce Everywhere: Remove unused includes of AK/Format.h
These instances were detected by searching for files that include
AK/Format.h, but don't match the regex:

\\b(CheckedFormatString|critical_dmesgln|dbgln|dbgln_if|dmesgln|FormatBu
ilder|__FormatIfSupported|FormatIfSupported|FormatParser|FormatString|Fo
rmattable|Formatter|__format_value|HasFormatter|max_format_arguments|out
|outln|set_debug_enabled|StandardFormatter|TypeErasedFormatParams|TypeEr
asedParameter|VariadicFormatParams|v_critical_dmesgln|vdbgln|vdmesgln|vf
ormat|vout|warn|warnln|warnln_if)\\b

(Without the linebreaks.)

This regex is pessimistic, so there might be more files that don't
actually use any formatting functions.

Observe that this revealed that Userland/Libraries/LibC/signal.cpp is
missing an include.

In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
2023-01-02 20:27:20 -05:00
Sam Atkins
29733e65f8 AK+Everywhere: Replace all Bitmap::must_create() uses with ::create()
Well, *someone* has to add some more FIXMEs to keep FIXME Roulette
going. :^)
2022-12-22 15:48:53 +01:00
Linus Groh
e785c66f91 LibJS: Convert get_this_environment() to NonnullGCPtr 2022-12-16 09:59:56 +01:00
Linus Groh
107e06a396 LibJS: Convert new_declarative_environment() to NonnullGCPtr 2022-12-16 09:59:56 +01:00
Linus Groh
bd40464195 LibJS: Convert standalone construct() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
Linus Groh
22089436ed LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
Ali Mohammad Pur
f96a3c002a Everywhere: Stop shoving things into ::std and mentioning them as such
Note that this still keeps the old behaviour of putting things in std by
default on serenity so the tools can be happy, but if USING_AK_GLOBALLY
is unset, AK behaves like a good citizen and doesn't try to put things
in the ::std namespace.

std::nothrow_t and its friends get to stay because I'm being told that
compilers assume things about them and I can't yeet them into a
different namespace...for now.
2022-12-14 11:44:32 +01:00
Linus Groh
ddc6e139a6 LibJS: Convert Object::create() to NonnullGCPtr 2022-12-14 09:59:45 +00:00
Linus Groh
91b0123eaf LibJS: Convert Array::create{,_from}() to NonnullGCPtr 2022-12-14 09:59:45 +00:00
Luke Wilde
4db2efaecb LibJS/Bytecode: Implement yield* 2022-12-10 00:21:10 +00:00
Luke Wilde
758a4cb1a6 LibJS/Bytecode: Implement var/lexical binding destructuring in for/of 2022-12-10 00:21:10 +00:00
Andreas Kling
b894acd6b2 LibJS: Make one compact allocation for CallExpression and its Arguments
Instead of CallExpression storing its arguments in a Vector<Argument>,
we now custom-allocate the memory slot for CallExpression (and its
subclass NewExpression) so that it fits both CallExpression and its list
of Arguments in one allocation.

This reduces memory usage on twitter.com/awesomekling by 8.8 MiB :^)
2022-12-08 23:36:17 +00:00
Linus Groh
525f22d018 LibJS: Replace standalone js_string() with PrimitiveString::create()
Note that js_rope_string() has been folded into this, the old name was
misleading - it would not always create a rope string, only if both
sides are not empty strings. Use a three-argument create() overload
instead.
2022-12-07 16:43:06 +00:00
Linus Groh
5db38d7ba1 LibJS: Replace standalone js_bigint() with BigInt::create()
Three standalone Cell creation functions remain in the JS namespace:

- js_bigint()
- js_string()
- js_symbol()

All of them are leftovers from early iterations when LibJS still took
inspiration from JSC, which itself has jsString(). Nowadays, we pretty
much exclusively use static create() functions to construct types
allocated on the JS heap, and there's no reason to not do the same for
these.
Also change the return type from BigInt* to NonnullGCPtr<BigInt> while
we're here.

This is patch 1/3, replacement of js_string() and js_symbol() follow.
2022-12-07 16:43:06 +00:00
Linus Groh
daec065fde LibJS: Move initialize_instance_elements() from VM to Object
This makes more sense as an Object method rather than living within the
VM class for no good reason. Most of the other 7.3.xx AOs already work
the same way.
Also add spec comments while we're here.
2022-12-07 00:23:51 +00:00
Hendiadyoin1
fcc3348bc8 LibJS: Intercept returns through finally blocks in Bytecode
This is still not perfect, as we now actually crash in the
`try-finally-continue` tests, while we now succeed all
`try-catch-finally-*` tests.

Note that we do not yet go through the finally block when exiting the
unwind context through a break or continue.
2022-12-06 16:09:24 +03:30
Hendiadyoin1
c2108489a5 LibJS: Don't try to manage unwind contexts in the execution loop in BC
We are already doing this in a good manner via the generated code,
doing so in the execution loop as well will cause us to pop contexts
multiple times, which is not very good.
2022-12-06 16:09:24 +03:30
Hendiadyoin1
133faa0acc LibJS: Remove FinishUnwind instruction
This is essentially a LeaveUnwind+Jump, so lets just do that, that will
make it easier to optimize it, or see unwind state transitions
2022-12-06 16:09:24 +03:30
Hendiadyoin1
fc332be2e5 LibJS: Leave unwind contexts on enter of finally blocks in Bytecode
Before we were doing so while exiting the catch-block, but not when
exiting the try-block.
This now centralizes the responsibility to exit the unwind context to
the finalizer, ignoring return/break/continue.
This makes it easier to handle the return case in a future commit.
2022-12-06 16:09:24 +03:30
Linus Groh
57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
2022-12-06 08:54:33 +01:00
Linus Groh
d26aabff04 Everywhere: Run clang-format 2022-12-03 23:52:23 +00:00
Hendiadyoin1
eb50969781 LibJS: Add an EliminateLoads pass to Bytecode
This pass tries to eliminate repeated lookups of variables by name, by
remembering where these where last loaded to.

For now the lookup cache needs to be fully cleared with each call or
property access, because we do not have a way to check if these have any
side effects on the currently visible scopes.

Note that property accesses can cause getters/setters to be called, so
these are treated as calls in all cases.
2022-12-03 15:25:05 +00:00
Hendiadyoin1
fafe498238 LibJS: Expose some internals of Instructions
These will be needed in the future to allow optimization passes to check
against these
2022-12-03 15:25:05 +00:00
Hendiadyoin1
fd6e75fd01 LibJS: Add a way to replace references to registers in Bytecode 2022-12-03 15:25:05 +00:00
Hendiadyoin1
f5e7fa4d0e LibJS: Make Register comparable 2022-12-03 15:25:05 +00:00
Hendiadyoin1
186237aec8 LibJS: Don't try to merge blocks not ending in Jumps 2022-12-03 17:07:30 +03:30
Hendiadyoin1
192897c269 LibJS: Remeber which instruction terminated a block 2022-12-03 17:07:30 +03:30
Hendiadyoin1
8c4717fc6e LibJS: Add a debug_position helper to the Bytecode Interpreter
This also changes argument_list_evaluation's dbgln to use it.
2022-12-03 17:07:30 +03:30
Hendiadyoin1
b86f1c2fe7 LibJS: Restore cached current_block on return in Bytecode
Otherwise debug prints will show the wrong block until we preform a jump
2022-12-03 17:07:30 +03:30
Hendiadyoin1
a00c421d61 LibJS: Handle FinishUnwind in GenerateCFG 2022-12-03 17:07:30 +03:30
Hendiadyoin1
6998b72d22 LibJS: Mark FinishUnwind as a terminator 2022-12-03 17:07:30 +03:30
Hendiadyoin1
ded7545db1 LibJS: Use a switch statement in GenerateCFG 2022-12-03 17:07:30 +03:30
Hendiadyoin1
7697e09660 LibJS: Don't mark blocks for unification multiple times
This would cause a UAF otherwise
2022-12-03 17:07:30 +03:30
Luke Wilde
5bc3371226 LibJS: Perform received abrupt generator completions in the generator
Previously, throw and return completions would not be executed inside
the generator. This is incorrect, as throw and return need to perform
unwinds which can potentially execute more code inside the generator,
such as finally blocks.

This is done by also passing the completion type alongside the passed
in value. The continuation block will immediately extract and type and
value and perform the appropriate operation for the given type.

For normal completions, this is continuing as normal.
For throw completions, it will perform `throw <value>`.
For return completions, it will perform `return <value>`, which is a
`Yield return` in this case due to being inside a generator.

This also refactors GeneratorObject to properly send across the
completion type and value to the generator inside of trying to operate
on the completions itself.

This is a prerequisite for yield*, as it performs special iterator
operations when receiving a throw/return completion and does not
complete the generator like the regular yield would.

There's still more work to be done to make GeneratorObject::execute
be closer to the spec. It's mostly a restructuring of the existing
GeneratorObject::next_impl.
2022-11-26 12:55:59 +01:00
Luke Wilde
277132f70d LibJS/Bytecode: Store unwind contexts inside RegisterWindow
Unwind contexts need to be preserved as we exit and re-enter a
generator.

For example, this would previously crash when returning from the try
statement after yielding as we lost the unwind context when yielding,
but still have a LeaveUnwindContext instruction from running
`perform_needed_unwinds` when generating the return statement.
```js
function* a() {
    try {
        return (yield 1);
    } catch {}
}

iter = a();
iter.next();
iter.next();
```
2022-11-26 12:55:59 +01:00
Luke Wilde
b914680f0c LibJS/Bytecode: Make yield by itself yield undefined 2022-11-26 12:55:59 +01:00
Andreas Kling
71067cbc6c LibJS+LibWeb: Make Runtime/AbstractOperations.h not include AST.h
This led to considerable fallout and many files had to be patched with
now-missing include statements.
2022-11-23 16:05:59 +00:00
Andreas Kling
2d33b2996f LibJS: Teach GetVariable bytecode op to deal with global variable cache
This mirrors the behavior of Identifer::to_reference() in the AST
interpreter.
2022-11-11 15:25:52 +01:00
Sam Atkins
c33eae24f9 AK+Everywhere: Replace DistinctNumeric bool parameters with named ones
This means that rather than this:

```
AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false,
    false, true, FunctionAddress);
```

We now have this:
```
AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, FunctionAddress, Arithmetic,
    Comparison, Increment);
```

Which is a lot more readable. :^)

Co-authored-by: Ali Mohammad Pur <mpfard@serenityos.org>
2022-11-11 17:50:53 +03:30
Andreas Kling
67236d9573 LibJS: Disable bytecode optimizations again
Bytecode optimizations still break test262, so let's not enable this
until they have been confirmed to work there.
2022-11-01 11:44:41 +01:00
Hendiadyoin1
4a06e68ecd LibJS: Set default bytecode optimization level to Optimize 2022-11-01 11:21:18 +01:00
Hendiadyoin1
1e1bf84e6d LibJS: Add a sanity check to bytecodes argument_list_evaluation 2022-11-01 11:21:18 +01:00
Hendiadyoin1
c9e7d452c5 LibJS: Add a note about inaccuracies to UnifySameBlocks 2022-11-01 11:21:18 +01:00
Hendiadyoin1
c66284ab0b LibJS: Fix MergeBlocks emitting some blocks twice 2022-11-01 11:21:18 +01:00
Hendiadyoin1
28e2467b48 LibJS: Minor cleanups in MergeBlocks 2022-11-01 11:21:18 +01:00
Hendiadyoin1
1ac1a5bd58 LibJS: Don't memcpy NewBigInt instruction
These aren't trivially copyable, so we have to be a bit more careful
2022-11-01 11:21:18 +01:00
Hendiadyoin1
a1f1d9e4a7 LibJS: Expose some information about the bytecode interpreters state
This is quite helpful, when reporting internal errors.
2022-11-01 11:21:18 +01:00
Andreas Kling
178f0b9971 LibJS: Support non-base-10 BigInt literals in bytecode VM
Fixes 39 tests in test262 and a handful in test-js. :^)
2022-10-19 19:58:15 +02:00
Andreas Kling
29935fe943 LibJS: Support for (x in obj) iteration in bytecode VM
We were mistakenly treating these as `for (x of obj)`. By reorganizing
the code a little bit, we actually support both kinds of iteration with
less duplication. :^)

Fixes 17 tests in test262.
2022-10-19 19:03:57 +02:00
Andreas Kling
d9b543da68 LibJS: Disable bytecode optimizations by default
The optimization passes are not stable, which makes test262 flaky.
Address this by introducing a new OptimizationLevel::None and making it
the default.

This removes all the flakiness from test262 in my testing.

We can enable optimizations by default again once they have been made
stable. :^)
2022-10-19 14:37:57 +02:00
Hendiadyoin1
490c097bc4 LibJS: Forward a string aproximation of the CallExpression to Call Ops
This gives us better debug output when analysing calls to `undefined`
and also fixes multiple test-js cases expecting an
`(evaluated from $Expression)` in the error message.

This also refactors out the generation of that string, to avoid code
duplication with the AST interpreter.
2022-10-17 01:36:41 +02:00
Hendiadyoin1
3e65afa41a LibJS: Show class name in the dump from the NewClass instruction 2022-10-02 18:49:17 +01:00
Hendiadyoin1
baa4d69668 LibJS: Set class' source text in NewClass instruction
This fixes the classes toString method.
2022-10-02 18:49:17 +01:00
Hendiadyoin1
911506af9f LibJS: Align Instructions as void* and roundup variably sized ones sizes
Both is indeed needed,
the standard alignment would have been 4, but some Instructions, like
Jumps need an alignment of 8

Fixes #12127.
2022-10-01 00:04:02 +01:00
Hendiadyoin1
89408d5f64 LibJS: Handle argument spreading in the bytecode vm 2022-10-01 00:04:02 +01:00
Hendiadyoin1
ae52ae8f9f LibJS: Add support for SpreadExpressions in array literals for bytecode
For this it adds another opcode `Append $lhs` which appends the
accumulator to the Array in $lhs, optionally spreading it.
2022-10-01 00:04:02 +01:00
Hendiadyoin1
4235b2020f LibJS: Switch to array-calls in the bytecode vm
This will make it easier to implement spreading arguments.
2022-10-01 00:04:02 +01:00
Hendiadyoin1
ab763a56f6 LibJS: Allow SpreadExpressions to generate bytecode 2022-10-01 00:04:02 +01:00
Hendiadyoin1
21ae882cfd LibJS: Implement SuperCall for the Bytecode-VM 2022-08-31 15:22:36 +01:00
Hendiadyoin1
25be67299e LibJS: Use builder.join in to_string_impl()s where applicable 2022-08-31 15:22:36 +01:00
Linus Groh
50428ea8d2 LibJS: Move intrinsics to the realm
Intrinsics, i.e. mostly constructor and prototype objects, but also
things like empty and new object shape now live on a new heap-allocated
JS::Intrinsics object, thus completing the long journey of taking all
the magic away from the global object.
This represents the Realm's [[Intrinsics]] slot in the spec and matches
its existing [[GlobalObject]] / [[GlobalEnv]] slots in terms of
architecture.

In the majority of cases it should now be possibly to fully allocate a
regular object without the global object existing, and in fact that's
what we do now - the realm is allocated before the global object, and
the intrinsics between both :^)
2022-08-27 11:29:10 +01:00
Linus Groh
987927a596 LibJS: Remove Bytecode::Register::global_object()
This is unused.
2022-08-23 13:58:30 +01:00
Linus Groh
275dea9d98 LibJS: Remove {Bytecode::,}Interpreter::global_object()
The basic idea is that a global object cannot just come out of nowhere,
it must be associated to a realm - so get it from there, if needed.

This is to enforce the changes from all the previous commits by not
handing out global objects unless you actually have an initialized
realm (either stored somewhere, or the VM's current realm).
2022-08-23 13:58:30 +01:00
Linus Groh
b345a0acca LibJS+LibWeb: Reduce use of GlobalObject as an intermediary
- Prefer VM::current_realm() over GlobalObject::associated_realm()
- Prefer VM::heap() over GlobalObject::heap()
- Prefer Cell::vm() over Cell::global_object()
- Prefer Wrapper::vm() over Wrapper::global_object()
- Inline Realm::global_object() calls used to access intrinsics as they
  will later perform a direct lookup without going through the global
  object
2022-08-23 13:58:30 +01:00
Linus Groh
b465f46e00 LibJS: Remove GlobalObject parameter from native functions 2022-08-23 13:58:30 +01:00
Linus Groh
25849f8a6d LibJS: Replace GlobalObject with VM in common AOs [Part 18/19] 2022-08-23 13:58:30 +01:00
Linus Groh
f0b793db74 LibJS: Replace GlobalObject with VM in RegExp AOs [Part 9/19] 2022-08-23 13:58:30 +01:00
Linus Groh
ccdfa2320c LibJS: Replace GlobalObject with VM in Iterator AOs [Part 7/19] 2022-08-23 13:58:30 +01:00
Linus Groh
ae9e031f56 LibJS: Replace GlobalObject with VM in Reference AOs [Part 6/19] 2022-08-23 13:58:30 +01:00
Linus Groh
275a7a0c0a LibJS: Replace GlobalObject with VM in Environment AOs [Part 5/19] 2022-08-23 13:58:30 +01:00
Linus Groh
a022e548b8 LibJS: Replace GlobalObject with VM in Value AOs [Part 4/19]
This is where the fun begins. :^)
2022-08-23 13:58:30 +01:00
Linus Groh
999da617c5 LibJS: Remove GlobalObject from VM::this_value()
This is a continuation of the previous six commits.

The global object is only needed to return it if the execution context
stack is empty, but that doesn't seem like a useful thing to allow in
the first place - if you're not currently executing JS, and the
execution context stack is empty, there is no this value to retrieve.
2022-08-23 13:58:30 +01:00
Linus Groh
f3117d46dc LibJS: Remove GlobalObject from VM::throw_completion()
This is a continuation of the previous five commits.

A first big step into the direction of no longer having to pass a realm
(or currently, a global object) trough layers upon layers of AOs!
Unlike the create() APIs we can safely assume that this is only ever
called when a running execution context and therefore current realm
exists. If not, you can always manually allocate the Error and put it in
a Completion :^)

In the spec, throw exceptions implicitly use the current realm's
intrinsics as well: https://tc39.es/ecma262/#sec-throw-an-exception
2022-08-23 13:58:30 +01:00
Linus Groh
5398dcc55e LibJS: Remove GlobalObject from execute() and related AST functions
This is a continuation of the previous four commits.

Passing a global object here is largely redundant, we definitely need
the interpreter but can get the VM and (later) current active realm from
there - and also the global object while we still need it, although I'd
like to remove Interpreter::global_object() in the future.

This now matches the bytecode interpreter's execute_impl() functions.
2022-08-23 13:58:30 +01:00
Linus Groh
e992a9f469 LibJS+LibWeb: Replace GlobalObject with Realm in Heap::allocate<T>()
This is a continuation of the previous three commits.

Now that create() receives the allocating realm, we can simply forward
that to allocate(), which accounts for the majority of these changes.
Additionally, we can get rid of the realm_from_global_object() in one
place, with one more remaining in VM::throw_completion().
2022-08-23 13:58:30 +01:00
Linus Groh
b99cc7d050 LibJS+LibWeb: Replace GlobalObject with Realm in create() functions
This is a continuation of the previous two commits.

As allocating a JS cell already primarily involves a realm instead of a
global object, and we'll need to pass one to the allocate() function
itself eventually (it's bridged via the global object right now), the
create() functions need to receive a realm as well.
The plan is for this to be the highest-level function that actually
receives a realm and passes it around, AOs on an even higher level will
use the "current realm" concept via VM::current_realm() as that's what
the spec assumes; passing around realms (or global objects, for that
matter) on higher AO levels is pointless and unlike for allocating
individual objects, which may happen outside of regular JS execution, we
don't need control over the specific realm that is being used there.
2022-08-23 13:58:30 +01:00
Linus Groh
5a106b6401 Everywhere: Prefix 'TYPEDEF_DISTINCT_NUMERIC_GENERAL' with 'AK_' 2022-07-22 23:09:43 +01:00
Daniel Bertalan
42e22f89a4 AK+LibGfx+LibJS: Pass -1 as the file descriptor to anonymous mmap
Serenity/Linux/macOS ignore the file descriptor when an anonymous
mapping is requested. However, BSDs require the fd to be -1.
2022-07-19 12:39:24 +02:00
Luke Wilde
fe2efbb2fc LibJS/Bytecode: Implement initializers for array binding patterns 2022-07-18 09:00:21 +01:00
Luke Wilde
0151dc562a LibJS/Bytecode: Implement destructuring assignment 2022-07-18 09:00:21 +01:00
Luke Wilde
f99f5d740e LibJS/Bytecode: Evaluate LHS of assignment before RHS
We had the same issue with the AST interpreter, see issue #3689.
2022-07-18 09:00:21 +01:00
Luke Wilde
896c477107 LibJS/Bytecode: Don't begin breakable scope before variable scope in for
This is no longer required, since the variable scope is ended after
switching to the end block, which means that LeaveLexicalEnvironment
will always be generated instead of depending on the unwind mechanism
to handle it for us.
2022-07-18 09:00:21 +01:00