Commit graph

175 commits

Author SHA1 Message Date
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
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
davidot
c4f3d44be1 LibJS: Add the HostEnsureCanAddPrivateElement hook
This hook allows us to reject private elements on certain exotic
objects like the window object in browser.
Note that per the spec we should only call this hook if the host is a
web browser, however because LibJS has no way of knowing whether it is
in a web browser environment we just always call the host hook.
2022-08-17 23:56:24 +01: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
Linus Groh
028a6b90b1 LibJS: Revert partial resizable ArrayBuffer implementation
This is a manual but clean revert of all commits from #12595.

Adding a partial implementation of the resizable ArrayBuffer proposal
without implementing all the updates to TypedArray infrastructure that
is also covered by the spec introduced a bunch of crashes, so we
decided to revert it for now until a full implementation is completed.
2022-07-06 15:52:57 +02:00
Linus Groh
93b4c3bb82 LibJS: Infer file extensions when resolving module paths
This allows `import "./foo"` to succeed, even if the file is actually
called `foo.js`. IDEs commonly exclude file extensions in auto-imports.

Closes #14364.
2022-06-26 22:03:53 +01:00
Linus Groh
2b3dd87296 LibJS: Rename filepath to filename in module related code
This is already the parameter name of Core::File::open() and
VM::get_stored_module() - both of which this is passed to - as well as
the member name of the Module class.
2022-06-26 22:03:53 +01:00
Luke Wilde
77ba3d3e3f LibJS: Remove callerRealm from HostEnsureCanCompileStrings
This is a normative change in the ecma262 spec.

See: https://github.com/tc39/ecma262/commit/2527be4
2022-05-08 17:12:27 +02:00
Linus Groh
03e13715ac LibJS: Update two comments saying "completion value"
This is an editorial change in the ECMA-262 spec.

See: https://github.com/tc39/ecma262/commit/7913cea
2022-05-03 22:49:31 +02:00
Linus Groh
9f3f3b0864 LibJS: Remove implicit wrapping/unwrapping of completion records
This is an editorial change in the ECMA-262 spec, with similar changes
in some proposals.

See:
- https://github.com/tc39/ecma262/commit/7575f74
- https://github.com/tc39/proposal-array-grouping/commit/df899eb
- https://github.com/tc39/proposal-shadowrealm/commit/9eb5a12
- https://github.com/tc39/proposal-shadowrealm/commit/c81f527
2022-05-03 01:09:29 +02:00
Linus Groh
719137418d LibJS: Change "as [the] argument[s]" to "with arguments" in comments
This is an editorial change in the ECMA-262 spec.

See: https://github.com/tc39/ecma262/commit/e671b96
2022-05-01 22:47:38 +02:00
Linus Groh
5a26a547db LibJS: Update a couple of outdated spec comments
These are editorial changes in the ECMA-262 spec.

See:
- https://github.com/tc39/ecma262/commit/e080a7f
- https://github.com/tc39/ecma262/commit/c5a9094
- https://github.com/tc39/ecma262/commit/5091520
- https://github.com/tc39/ecma262/commit/1c6564b
- https://github.com/tc39/ecma262/commit/e06c80c
2022-05-01 22:47:38 +02:00
Linus Groh
e815d3f9ce LibJS: De-duplicate ClassFieldDefinition Records
This was defined twice, despite being the very same thing:
- ClassElement::ClassFieldDefinition
- ECMAScriptFunctionObject::InstanceField

Move the former to a new header and use it everywhere. Also update the
define_field() AO to take a single field instead of separate name and
initializer arguments.
2022-04-20 00:08:32 +02:00
Luke Wilde
34f902fb52 LibJS: Add missing steps and spec comments to PerformEval
While adding spec comments to PerformEval, I noticed we were missing
multiple steps.

Namely, these were:
- Checking if the host will allow us to compile the string
  (allowing LibWeb to perform CSP for eval)
- The parser's initial state depending on the environment around us
  on direct eval:
   - Allowing new.target via eval in functions
   - Allowing super calls and super properties via eval in classes
   - Disallowing the use of the arguments object in class field
     initializers at eval's parse time
- Setting ScriptOrModule of eval's execution context

The spec allows us to apply the additional parsing steps in any order.
The method I have gone with is passing in a struct to the parser's
constructor, which overrides the parser's initial state to (dis)allow
the things stated above from the get-go.
2022-04-11 21:23:36 +01:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Lenny Maiorani
d00b79568f Libraries: Use default constructors/destructors in LibJS
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-16 16:19:40 +00:00
ForLoveOfCats
f350c153e8 LibJS: Implement and test ArrayBuffer.prototype.resize 2022-03-02 20:53:18 +01:00
Linus Groh
47cdd90836 LibJS: Use new NativeFunction::create() in most places
Resolves one FIXME where we can now pass a realm, and sets the length
correctly in a bunch of places that previously didn't.
Also reduces the number of "format function name string from arbitrary
PropertyKey" implementations, although two more remain present in the
AST (used with ECMAScriptFunctionObjects, which is a different beast).
2022-02-20 23:21:40 +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
Luke Wilde
4c1c6ef91c LibJS: Setup host hooks and have promise jobs work out the realm
This allows the host of LibJS (notably LibWeb in this case) to override
certain functions such as HostEnqueuePromiseJob, so it can do it's own
thing in certain situations. Notably, LibWeb will override
HostEnqueuePromiseJob to put promise jobs on the microtask queue.

This also makes promise jobs use AK::Function instead of
JS::NativeFunction. This removes the need to go through a JavaScript
function and it more closely matches the spec's idea of "abstract
closures"
2022-02-08 17:47:44 +00:00
davidot
9264f9d24e LibJS+Everywhere: Remove VM::exception() and most related functions
This commit removes all exception related code:
Remove VM::exception(), VM::throw_exception() etc. Any leftover
throw_exception calls are moved to throw_completion.
The one method left is clear_exception() which is now a no-op. Most of
these calls are just to clear whatever exception might have been thrown
when handling a Completion. So to have a cleaner commit this will be
removed in a next commit.

It also removes the actual Exception and TemporaryClearException classes
since these are no longer used.

In any spot where the exception was actually used an attempt was made to
preserve that behavior. However since it is no longer tracked by the VM
we cannot access exceptions which were thrown in previous calls.
There are two such cases which might have different behavior:
- In Web::DOM::Document::interpreter() the on_call_stack_emptied hook
  used to print any uncaught exception but this is now no longer
  possible as the VM does not store uncaught exceptions.
- In js the code used to be interruptable by throwing an exception on
  the VM. This is no longer possible but was already somewhat fragile
  before as you could happen to throw an exception just before a VERIFY.
2022-02-08 09:12:42 +00:00
Andreas Kling
7ad4702cbf LibJS: Unbreak build with JS_MODULE_DEBUG
Thanks to David for noticing this! :^)
2022-02-07 19:59:21 +01:00
Andreas Kling
85cf80507f LibJS: Make ScriptOrModule use WeakPtr instead of raw pointers 2022-02-07 19:16:45 +01:00
davidot
14d1601a76 LibJS: Remove the VERIFY_NOT_REACHED in link_and_eval_module
Since the spec does not fully define the entry points of modules what
this means is kind of unclear. But it does work in most cases and can
be useful. We do print out a warning just to clarify why there could be
strange things.
2022-02-05 11:52:51 +01:00
davidot
5749d85534 LibJS: Keep handles on promise functions while resolving a module 2022-02-05 11:52:51 +01:00
davidot
6b5c882af3 LibJS: Add support for JSON modules
We now have one supported assertion: 'type' if that is 'json' we attempt
to parse the module as JSON.
2022-01-30 17:40:20 +00:00
davidot
f568939568 LibJS: Implement the import assertions proposal
The hard part of parsing them in import statements and calls was already
done so this is just removing some check which threw before on
assertions. And filtering the assertions based on the result of a new
host hook.
2022-01-30 17:40:20 +00:00
mjz19910
61cf1c066e LibJS: Remove VM::call() 2022-01-23 15:24:45 +00:00
mjz19910
1ef633472b Everywhere: Convert VM::call() to JS::call() 2022-01-23 15:24:45 +00:00
davidot
91b3e5b31f LibJS: Implement the ImportMeta MetaProperty
This "standard" implementation of this is to do nothing.
2022-01-22 01:21:18 +00:00
davidot
7cbf4b90e8 LibJS: Implement ImportCall and HostImportModuleDynamically
This allows us to load modules from scripts.
This can be dangerous as it can load arbitrary files. Because of that it
fails and throws by default. Currently, only js and JavaScriptTestRunner
enable the default hook.

This also adds tests to test-js which test module code. Because we
form a spec perspective can't "enter" a module this is the easiest way
to run tests without having to modify test-js to have special cases for
modules.
To specify modules in test-js we use the extension '.mjs' this is to
ensure the files are not executed. We do still want to lint these files
so the prettier scripts have changed to look for '.mjs' files as well.
2022-01-22 01:21:18 +00:00
davidot
779e677467 LibJS: Implement HostResolveImportedModule for LibJS
This loads modules with relative paths from the referencing module.
In this commit the only way to run a module is via the interpreter
which can link and evaluate a module (and all its dependencies).
2022-01-22 01:21:18 +00:00
davidot
57c5a59cab LibJS: Add ScriptOrModule to execution context and track it everywhere 2022-01-22 01:21:18 +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
963b0f76cf LibJS: Remove now unused VM::{set_,}last_value()
This was effectively replaced by correct use of completions, including
UpdateEmpty semantics.
2022-01-08 23:43:03 +01:00
Linus Groh
9d0d3affd4 LibJS: Replace the custom unwind mechanism with completions :^)
This includes:

- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
2022-01-06 12:36:23 +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
c296df6b58 LibJS: Convert to_reference() to ThrowCompletionOr 2021-12-31 00:03:20 +01:00
davidot
a24df37713 LibJS: Convert resolve_this_binding() to ThrowCompletionOr
Also add spec comments.
2021-12-31 00:03:20 +01:00
davidot
b303b8cf4e LibJS: Convert thrown exception to completion in binding initialization
This regressed in 676554d3 as it assumed to_reference() (already)
returned a completion type instead of putting the error in
vm.exception().
2021-12-30 20:14:13 +01:00
davidot
d72022ba04 LibJS: Convert get_identifier_reference() to ThrowCompletionOr
And while we're here add spec comments.
2021-12-30 15:29:33 +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
Linus Groh
df931e6a83 LibJS: Implement and use the InitializeBoundName AO 2021-12-29 10:34:28 +01:00
Linus Groh
ca48151147 LibJS: Add spec comments to VM::binding_initialization() 2021-12-29 10:34:23 +01:00
Linus Groh
451149df0b LibJS: Ensure get_new_target() never returns an empty value
Also add spec comments and remove a redundant exception check while
we're here :^)
2021-12-29 00:16:51 +01:00
Timothy Flynn
d69f5ca128 LibJS: Update spec numbers for Operations on Objects AOs
The error cause proposal was merged, so some spec numbers were bumped.
2021-12-21 14:56:28 +01:00