Commit graph

173 commits

Author SHA1 Message Date
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
Luke Wilde
631bbcd00a LibJS: Refactor interpreter to use Script and Source Text Modules
This also refactors interpreter creation to follow
InitializeHostDefinedRealm, but I couldn't fit it in the title :^)

This allows us to follow the spec much more closely rather than being
completely ad-hoc with just the parse node instead of having all the
surrounding data such as the realm of the parse node.

The interpreter creation refactor creates the global execution context
once and doesn't take it off the stack. This allows LibWeb to take the
global execution context and manually handle it, following the HTML
spec. The HTML spec calls this the "realm execution context" of the
environment settings object.

It also allows us to specify the globalThis type, as it can be
different from the global object type. For example, on the web, Window
global objects use a WindowProxy global this value to enforce the same
origin policy on operations like [[GetOwnProperty]].

Finally, it allows us to directly call Program::execute in perform_eval
and perform_shadow_realm_eval as this moves
global_declaration_instantiation into Interpreter::run
(ScriptEvaluation) as per the spec.

Note that this doesn't evalulate Source Text Modules yet or refactor
the bytecode interpreter, that's work for future us :^)

This patch was originally build by Luke for the environment settings
object change but was also needed for modules. So I (davidot) have
modified it with the new completion changes and setup for that.

Co-authored-by: davidot <davidot@serenityos.org>
2022-01-22 01:21:18 +00:00
davidot
a5b11f7484 LibJS: Fix that '_' no longer accessed the last value in the REPL
This is now also not a concept that VM knows about and handled
completely by the REPL.
2022-01-16 14:57:12 +01:00
Timothy Flynn
58ccca6a9d LibJS+js: Pretty-print Date objects using the ToDateString AO 2022-01-15 20:13:48 +01:00
Timothy Flynn
27c845eef2 js: Pretty-print the Intl.DisplayNames [[LanguageDisplay]] internal slot 2022-01-13 13:43:57 +01:00
Linus Groh
eb60d16549 LibJS: Convert Interpreter::run() to ThrowCompletionOr<Value>
Instead of making it a void function, checking for an exception, and
then receiving the relevant result via VM::last_value(), we can
consolidate all of this by using completions.

This allows us to remove more uses of VM::exception(), and all uses of
VM::last_value().
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
9e50bd91a6 js: Remove uses of TRY_OR_DISCARD()
Slightly more verbose, but that's the last user of TRY_OR_DISCARD gone!
2022-01-04 23:37:26 +00: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
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
Timothy Flynn
565a880ce5 Userland: Link directly against LibUnicodeData where needed
This is partially a revert of commits:
    10a8b6d411
    561b67a1ad

Rather than adding the prot_exec pledge requried to use dlopen(), we can
link directly against LibUnicodeData in applications that we know need
that library.

This might make the dlopen() dance a bit unnecessary. The same purpose
might now be fulfilled with weak symbols. That can be revisted next, but
for now, this at least removes the potential security risk of apps like
the Browser having prot_exec privileges.
2021-12-30 14:18:12 +01:00
Sam Atkins
d702678d16 LibJS+WebContent+Browser+js: Implement console.group() methods
This implements:
- console.group()
- console.groupCollapsed()
- console.groupEnd()

In the Browser, we use `<details>` for the groups, which is not actually
implemented yet, so groups are always open.

In the REPL, groups are non-interactive, but still indent any output.
This looks weird since the console prompt and return values remain on
the far left, but this matches what Node does so it's probably fine. :^)
I expect `console.group()` is not used much outside of browsers.
2021-12-27 21:44:07 +01:00
Sam Atkins
ff5e07d718 LibJS+WebContent+js: Bring console.trace() to spec
The spec very kindly defines `Printer` as accepting
"Implementation-specific representations of printable things such as a
stack trace or group." for the `args`. We make use of that here by
passing the `Trace` itself to `Printer`, instead of having to produce a
representation of the stack trace in advance and then pass that to
`Printer`. That both avoids the hassle of tracking whether the data has
been html-encoded or not, and means clients don't have to implement the
whole `trace()` algorithm, but only the code needed to output the trace.
2021-12-27 21:44:07 +01:00
Sam Atkins
ce694490f3 LibJS+WebContent+js: Bring console.assert() to spec 2021-12-27 21:44:07 +01:00
Sam Atkins
9b78e287b0 LibJS+WebContent+js: Bring console.clear() to spec
This is identical to before, since we don't have "group stacks" yet, but
clear() now uses ThrowCompletionOr.
2021-12-27 21:44:07 +01:00
Sam Atkins
834ced82d4 LibJS+WebContent+js: Bring console.count[Reset]() to spec
The `CountReset` log level is displayed as a warning, since the message
is always to warn that the counter doesn't exist. This is also in line
with the table at https://console.spec.whatwg.org/#loglevel-severity
2021-12-27 21:44:07 +01:00
Sam Atkins
260836135a LibJS+WebContent+js: Reimplement console.log() and friends to spec
This implements the Logger and Printer abstract operations defined in
the console spec, and stubs out the Formatter AO. These are then used
for the "output a categorized log message" functions.
2021-12-27 21:44:07 +01:00
Timothy Flynn
10a8b6d411 Userland: Add unveil/pledge requisites for dynamic Unicode data loading
Loading libunicodedata.so will require dlopen(), which in turn requires
mmap(). The 'prot_exec' pledge is needed for this.

Further, the .so itself must be unveiled for reading. The "real" path is
unveiled (libunicodedata.so.serenity) as the symlink (libunicodedata.so)
itself cannot be unveiled.
2021-12-21 13:09:49 -08:00
Linus Groh
038d354b5d LibJS: Remove Object::value_of()
Being really close to Object.prototype.valueOf() name wise makes this
unnecessarily confusing - while it sometimes serves as the
implementation of a valueOf() function, it's an abstraction which the
spec doesn't have.
Use the appropriate getters to retrieve specific internal slots instead,
most commonly [[FooData]] from the primitive wrapper objects.
For the Object class specifically, use the Value(Object*) ctor instead.
2021-12-10 22:52:36 +00:00
James Puleo
dd25dfbc20 js: Improve usage of TRY when executing a file program 2021-12-08 17:17:35 -08:00
Timothy Flynn
6ad00088c0 js: Implement pretty-printing of Intl.DateTimeFormat 2021-11-29 22:48:46 +00:00
Brian Gianforcaro
cf4fa936be Everywhere: Use default execpromises argument for Core::System::pledge 2021-11-28 08:04:57 +01:00
Andreas Kling
f1cc3d0fc4 Userland: Use Core::ArgsParser's Vector<StringView> API everywhere
...and remove the Vector<String> variant since there are no remaining
users of this API.
2021-11-26 23:27:57 +01:00
Idan Horowitz
58397f356f js: Add command line flag for disabling source line hints 2021-11-24 18:05:24 +00:00
Idan Horowitz
15fafdc645 js: Pretty-print custom error types 2021-11-24 18:05:24 +00:00
Idan Horowitz
11d1950e74 js: Add command line flag for disabling ANSI colors 2021-11-24 18:05:24 +00:00
Andreas Kling
21a5fb0fa2 LibCore+LibSystem: Move syscall wrappers from LibSystem to LibCore
With this change, System::foo() becomes Core::System::foo().

Since LibCore builds on other systems than SerenityOS, we now have to
make sure that wrappers work with just a standard C library underneath.
2021-11-23 11:33:36 +01:00
Mustafa Quraish
2fbcab46bf Everywhere: Use ArgsParser::parse() with Main::Arguments directly
Use the updated API everywhere we are currently manually passing in
`arguments.argc` and `arguments.argv`.
2021-11-22 21:13:42 -08:00
Linus Groh
8fa5dc7241 js: Use pledge()
It is now no longer possible to make network connections from a hijacked
js(1) :^)
2021-11-22 23:07:43 +01:00
Linus Groh
cfecfbb214 js: Port to LibMain :^)
This wasn't particularly difficult, and there's not much use for the
nicer interface yet either. While unveil() is of limited use in js(1)
as it should be able to open arbitrary files, I feel like we should be
able to add a pledge() call.
2021-11-22 23:07:43 +01:00
davidot
22e679d844 LibJS + js: Rethrow exception on the vm after bytecode interpreter run
When the bytecode interpreter was converted to ThrowCompletionOr<Value>
it then also cleared the vm.exception() making it seem like no exception
was thrown.
Also removed the TRY_OR_DISCARD as that would skip the error handling
parts.
2021-11-17 13:12:05 +00:00
Andreas Kling
587f9af960 AK: Make JSON parser return ErrorOr<JsonValue> (instead of Optional)
Also add slightly richer parse errors now that we can include a string
literal with returned errors.

This will allow us to use TRY() when working with JSON data.
2021-11-17 00:21:10 +01:00
Ali Mohammad Pur
070d2eaa51 LibJS+LibTest+js: Convert BC::Interpreter::run to ThrowCompletionOr<>
Note that this is just a shallow API change.
2021-11-12 13:01:59 +00:00
Andreas Kling
8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
Idan Horowitz
390a04a985 LibJS: Convert the GetValue AO to ThrowCompletionOr 2021-11-02 19:48:35 +01:00
Timothy Flynn
0f91b22795 js: Convert JavaScript REPL to ThrowCompletionOr 2021-10-31 07:50:30 +02:00
Andreas Kling
f75d78f56a LibJS: Include executable name in bytecode dumps 2021-10-24 17:18:06 +02:00
Andreas Kling
c95dde971b LibJS: Move global "should dump bytecode" flag into LibJS
This will allow us to trigger bytecode executable dumps when generating
bytecode inside LibJS as well, not just in clients like js and test-js.
2021-10-24 17:18:06 +02:00
Idan Horowitz
40eb3a39d4 LibJS: Rename define_native_function => define_old_native_function
This method will eventually be removed once all native functions are
converted to ThrowCompletionOr
2021-10-20 12:27:19 +01:00
Idan Horowitz
20163c0584 LibJS: Add ThrowCompletionOr versions of the JS native function macros
The old versions were renamed to JS_DECLARE_OLD_NATIVE_FUNCTION and
JS_DEFINE_OLD_NATIVE_FUNCTION, and will be eventually removed once all
native functions were converted to the new format.
2021-10-20 12:27:19 +01:00
Idan Horowitz
20d990563c LibJS: Convert to_number() to ThrowCompletionOr 2021-10-18 08:01:38 +03:00
Linus Groh
1adf57530c js: Implement pretty-printing of ShadowRealm 2021-10-14 00:41:41 +01:00
Linus Groh
52976bfac6 LibJS: Convert to_object() to ThrowCompletionOr 2021-10-13 09:55:10 +01:00
Linus Groh
4d8912a92b LibJS: Convert to_string() to ThrowCompletionOr
Also update get_function_name() to use ThrowCompletionOr, but this is
not a standard AO and should be refactored out of existence eventually.
2021-10-13 09:55:10 +01:00
Linus Groh
fe802f5ff5 js: Fix pretty-printing of RegExp objects
Regressed in b7e5f08.

Use the newly available RegExpObject::escape_regexp_pattern() instead of
attempting to call the RegExp.prototype.source accessor getter directly.
2021-10-05 18:35:49 +01:00
Linus Groh
b7e5f08e56 LibJS: Convert Object::get() to ThrowCompletionOr
To no one's surprise, this patch is pretty big - this is possibly the
most used AO of all of them. Definitely worth it though.
2021-10-03 20:14:03 +01:00
davidot
f4f1397735 js: Allow for completion of lexically declared variables
This does require us to have a method which lists all the bindings in
a declarative environment which is not in the spec.
2021-10-03 17:42:05 +02:00
davidot
0be0e7ea6e js: Fix that auto completion of properties failed
For this we store the global environment in which we can do a lookup
for the references variable. This is probably not entirely as the spec
would specify as we would need a running executing context at all times
you do things with references.

Fixes #10281
2021-10-03 17:42:05 +02:00
Andreas Kling
6a1b82df2b LibJS: Put zombie cell tracking code behind a compile-time flag
Since this is a debug-only feature, let's not have it impact GC marking
performance when you don't need it.
2021-10-02 16:39:28 +02:00
davidot
830ea0414c LibJS: Make scoping follow the spec
Before this we used an ad-hoc combination of references and 'variables'
stored in a hashmap. This worked in most cases but is not spec like.
Additionally hoisting, dynamically naming functions and scope analysis
was not done properly.

This patch fixes all of that by:
  - Implement BindingInitialization for destructuring assignment.
  - Implementing a new ScopePusher which tracks the lexical and var
    scoped declarations. This hoists functions to the top level if no
    lexical declaration name overlaps. Furthermore we do checking of
    redeclarations in the ScopePusher now requiring less checks all over
    the place.
  - Add methods for parsing the directives and statement lists instead
    of having that code duplicated in multiple places. This allows
    declarations to pushed to the appropriate scope more easily.
  - Remove the non spec way of storing 'variables' in
    DeclarativeEnvironment and make Reference follow the spec instead of
    checking both the bindings and 'variables'.
  - Remove all scoping related things from the Interpreter. And instead
    use environments as specified by the spec. This also includes fixing
    that NativeFunctions did not produce a valid FunctionEnvironment
    which could cause issues with callbacks and eval. All
    FunctionObjects now have a valid NewFunctionEnvironment
    implementation.
  - Remove execute_statements from Interpreter and instead use
    ASTNode::execute everywhere this simplifies AST.cpp as you no longer
    need to worry about which method to call.
  - Make ScopeNodes setup their own environment. This uses four
    different methods specified by the spec
    {Block, Function, Eval, Global}DeclarationInstantiation with the
    annexB extensions.
  - Implement and use NamedEvaluation where specified.

Additionally there are fixes to things exposed by these changes to eval,
{for, for-in, for-of} loops and assignment.

Finally it also fixes some tests in test-js which where passing before
but not now that we have correct behavior :^).
2021-09-30 08:16:32 +01:00