Commit graph

199 commits

Author SHA1 Message Date
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
Luke Wilde
c55a4c7f30 LibJS/Bytecode: Create global variables before setting them
This allows them to be accessed before assignment, and also prevents
throwing in strict mode as we are trying to set a non-existent
variable.
2022-07-18 09:00:21 +01:00
Luke Wilde
12e3abc9e7 LibJS/Bytecode: Make setting failures throw only in strict mode 2022-07-18 09:00:21 +01:00
sin-ack
c8585b77d2 Everywhere: Replace single-char StringView op. arguments with chars
This prevents us from needing a sv suffix, and potentially reduces the
need to run generic code for a single character (as contains,
starts_with, ends_with etc. for a char will be just a length and
equality check).

No functional changes.
2022-07-12 23:11:35 +02:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).

No functional changes.
2022-07-12 23:11:35 +02:00
Luke Wilde
9ad807d08b LibJS/Bytecode: Pass contains_direct_call_to_eval into ESFO::create
Previously it would pass in `is_arrow_function` as
`contains_direct_call_to_eval`, which broke strict mode propagation in
arrow functions. This makes test-js work without falling apart because
`this` is mysteriously undefined because of the use of arrow functions
inside classes, which are strict mode by default.
2022-06-13 07:13:03 +04:30
Luke Wilde
482a827346 LibJS/Bytecode: Make typeof return "undefined" on unresolvable IDs
Previously it would throw instead of returning "undefined" for
`typeof Identifier` if Identifier does not exist.
2022-06-13 07:13:03 +04:30
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Ali Mohammad Pur
007ffcd763 LibJS: Implement bytecode generation for all ObjectExpression properties 2022-03-31 18:11:08 +02:00
Luke Wilde
7cc53b7ef1 LibJS/Bytecode: Implement the delete unary expression
`delete` has to operate directly on Reference Records, so this
introduces a new set of operations called DeleteByValue, DeleteVariable
and DeleteById. They operate similarly to their Get counterparts,
except they end in creating a (temporary) Reference and calling delete_
on it.
2022-03-28 14:05:33 +02:00
Luke Wilde
741745baab LibJS/Bytecode: Update NewArray stringifier to print a register range
NewArray now only contains two elements maximum in `m_elements` to
indicate the range of registers to create the array from.

However, `m_element_count` still contains how many registers are in the
range and the stringifier was not updated to account for this. Thus, if
the range contained more than 2 registers, it would do a read OOB on
`m_elements`.

This makes it now just print the first and second entries in
`m_elements` in the format of `[<reg>-<reg>]`.
2022-03-28 14:05:33 +02:00
Luke Wilde
096d2bb772 LibJS/Bytecode: Make construct Call throw if callee isn't a constructor 2022-03-19 22:01:52 +01:00
Luke Wilde
eac5534ce4 LibJS/Bytecode: Add support for new.target 2022-03-19 22:01:52 +01:00
Ali Mohammad Pur
8f7021faf7 LibJS: Implement bytecode generation for For-In/Of statements
This also implements the rather interesting behaviour that #12772 relies
on, so this fixes that bug in BC mode (the AST interp remains affected).
2022-03-19 12:51:29 +01:00
Ali Mohammad Pur
a37bee919a LibJS: Use ranges instead of specifying all registers for NewArray
Listing all the registers will lead to the inability to allocate enough
space in one basic block (as there can be an arbitrary number of
registers used), instead switch to specifying the range of registers
used and save a lot of space in the process.
2022-03-14 21:15:27 +03:30
Luke Wilde
e517cb505a LibJS/Bytecode: Make NewArray write directly to indexed properties
This follows how the regular AST interpreter creates arrays, as using
Array::create_from uses create_data_property_or_throw, which will crash
when it encounters an empty value. We require empty values to represent
array holes.
2022-03-14 21:15:27 +03:30
Ali Mohammad Pur
2000251333 LibJS: Implement bytecode generation for WithStatement 2022-03-13 17:50:21 +01:00
Ali Mohammad Pur
41184c960d LibJS: Propagate abrupt completions in Bytecode::Op::Call
This was not handling the nullary call case correctly, remove the whole
nullary check as there's nothing particularly expensive in the catch-all
case anyway.
2022-03-13 17:50:21 +01:00
Ali Mohammad Pur
1bbfaf8627 LibJS: More properly implement scoping rules in bytecode codegen
Now we emit CreateVariable and SetVariable with the appropriate
initialization/environment modes, much closer to the spec.
This makes a whole lot of things like let/const variables, function
and variable hoisting and some other things work :^)
2022-02-13 14:41:33 +00:00
Ali Mohammad Pur
d7c207beb9 LibJS: Implement the NewClass opcode 2022-02-13 14:41:33 +00:00
Linus Groh
bc183dbbcb LibJS: Replace uses of MarkedValueList with MarkedVector<Value>
This is effectively a drop-in replacement.
2022-02-09 12:25:27 +00:00
davidot
8108fc7f9c LibJS: Convert Instruction::execute in bytecode to ThrowCompletionOr
This allows us to use TRY in these functions :^).
2022-02-08 09:12:42 +00:00
Linus Groh
6f20f49b21 Everywhere: Rename JS::PropertyKey variables from property_{name => key}
PropertyKey used to be called PropertyName, but got renamed. Let's
update all the variables of this type as well.
2022-02-06 22:02:45 +00:00
Andreas Kling
fc04465fa3 LibJS: Remove unnecessary GlobalObject pointer from Environment
As it turns out, we didn't actually need this pointer. :^)
2022-01-31 16:19:23 +01:00
mjz19910
1ef633472b Everywhere: Convert VM::call() to JS::call() 2022-01-23 15:24:45 +00:00
Linus Groh
1ee7e97e24 LibJS: Pass source text to ECMAScriptFunctionObject::create() 2022-01-19 20:33:08 +00:00
Linus Groh
09a11fa6ea LibJS: Implement proper Iterator records
Instead of using plain objects as Iterator records, causes confusion
about the object itself actually being its [[Iterator]] slot, and
requires non-standard type conversion shenanigans fpr the [[NextValue]]
and [[Done]] internal slots,  implement a proper Iterator record struct
and use it throughout.

Also annotate the remaining Iterator AOs with spec comments while we're
here.
2022-01-09 22:02:43 +01:00
Linus Groh
da856d7742 LibJS: Update AST to use completions :^)
This is another major milestone on our journey towards removing global
VM exception state :^)
Does pretty much exactly what it says on the tin: updating
ASTNode::execute() to return a Completion instead of a plain value. This
will *also* allow us to eventually remove the non-standard unwinding
mechanism and purely rely on the various completion types.
2022-01-03 21:50:50 +01:00
Linus Groh
85f0fc2b83 LibJS: Return Optional<T> from Completion::{value,target}(), not T
In the end this is a nicer API than having separate has_{value,target}()
and having to check those first, and then making another Optional from
the unwrapped value:

    completion.has_value() ? completion.value() : Optional<Value> {}
    //                       ^^^^^^^^^^^^^^^^^^
    //         Implicit creation of non-empty Optional<Value>

This way we need to unwrap the optional ourselves, but can easily pass
it to something else as well.

This is in anticipation of the AST using completions :^)
2022-01-03 21:50:50 +01:00
davidot
a24df37713 LibJS: Convert resolve_this_binding() to ThrowCompletionOr
Also add spec comments.
2021-12-31 00:03:20 +01:00
davidot
676554d3f8 LibJS: Convert resolve_binding() to ThrowCompletionOr
The spec has a note stating that resolve binding will always return a
reference whose [[ReferencedName]] field is name. However this is not
correct as the underlying method GetIdentifierReference may throw on
env.HasBinding(name) thus it can throw. However, there are some
scenarios where it cannot throw because the reference is known to exist
in that case we use MUST with a comment.
2021-12-30 15:29:33 +01:00
Ali Mohammad Pur
b96118b5d1 LibJS: Fix codegen for nodes after try statements without 'finally'
Previously we were just dropping them on the ground :P
2021-11-12 13:01:59 +00:00
Idan Horowitz
1aaaf521b8 LibJS: Convert the PutValue AO to ThrowCompletionOr 2021-11-02 19:48:35 +01:00
Idan Horowitz
390a04a985 LibJS: Convert the GetValue AO to ThrowCompletionOr 2021-11-02 19:48:35 +01:00
Andreas Kling
a831cd9cc7 LibJS: Make bytecode VM throw TypeError on attempt to call non-callable
This isn't perfect, but allows us to progress instead of crashing in
the TODO().
2021-10-25 12:57:21 +02:00
Andreas Kling
398c181c79 LibJS: Rename PropertyName to PropertyKey
Let's use the same name as the spec. :^)
2021-10-24 17:18:07 +02:00
Andreas Kling
715e7fada8 LibJS: Add the "fast non-local access" optimization to the bytecode VM
The GetVariable bytecode op now caches environment coordinates for fast
cross-scope variable lookup.
2021-10-24 17:18:07 +02:00
Andreas Kling
da98212001 LibJS: Add a separate "identifier table" to bytecode executables
This is a specialized string table for storing identifiers only.
Identifiers are always FlyStrings, which makes many common operations
faster by allowing O(1) comparison.
2021-10-24 17:18:07 +02:00
Andreas Kling
3117182c2e LibJS: Implement 'this' in the bytecode VM
ThisExpression now emits a "ResolveThisBinding" bytecode op, which
simply loads the VM's current 'this' binding into the accumulator.
2021-10-24 17:18:06 +02:00
Idan Horowitz
844be7a0a5 LibJS: Convert the RegExpCreate AO to ThrowCompletionOr 2021-10-23 18:01:51 +02:00
Idan Horowitz
e26d9f419b LibJS: Remove vm.construct and it's usages 2021-10-23 02:49:41 +03:00