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

1248 commits

Author SHA1 Message Date
Linus Groh
2d4650714f LibJS: Use ThrowCompletionOr in get_prototype_from_constructor()
Also add spec step comments to it while we're here.
2021-09-15 23:46:53 +01:00
Linus Groh
bc1b8f9cc8 LibJS: Use ThrowCompletionOr in get_function_realm() 2021-09-15 23:46:53 +01:00
Linus Groh
3d43eb0774 LibJS: Use ThrowCompletionOr in species_constructor()
Also add spec step comments to it as well as a missing exception check
while we're here.
2021-09-15 23:46:53 +01:00
Linus Groh
c4c40f4cf3 LibJS: Use ThrowCompletionOr in create_list_from_array_like()
Also add spec step comments to it while we're here.
2021-09-15 23:46:53 +01:00
Linus Groh
568296d0cc LibJS: Use ThrowCompletionOr in require_object_coercible() 2021-09-15 23:46:53 +01:00
Linus Groh
33679a8445 LibJS: Add a JS::Completion class and JS::ThrowCompletionOr<T> template
We decided that we want to move away from throwing exceptions in AOs
and regular functions implicitly and then returning some
default-constructed value (usually an empty JS::Value) - this requires
remembering to check for an exception at the call site, which is
error-prone. It's also awkward for return values that cannot be
default-constructed, e.g. MarkedValueList.
Instead, the thrown value should be part of the function return value.

The solution to this is moving closer to the spec and using something
they call "completion records":
https://tc39.es/ecma262/#sec-completion-record-specification-type

This has various advantages:

- It becomes crystal clear whether some AO can fail or not, and errors
  need to be handled and values unwrapped explicitly (for that reason
  compatibility with the TRY() macro is already built-in, and a similar
  TRY_OR_DISCARD() macro has been added specifically for use in LibJS,
  while the majority of functions doesn't return ThrowCompletionOr yet)
- We no longer need to mix "valid" and "invalid" values of various types
  for the success and exception outcomes (e.g. null/non-null AK::String,
  empty/non-empty JS::Value)
- Subsequently it's no longer possible to accidentally use an exception
  outcome return value as a success outcome return value (e.g. any AO
  that returns a numeric type would return 0 even after throwing an
  exception, at least before we started making use of Optional for that)
- Eventually the VM will no longer need to store an exception, and
  temporarily clearing an exception (e.g. to call a function) becomes
  obsolete - instead, completions will simply propagate up to the caller
  outside of LibJS, which then can deal with it in any way
- Similar to throw we'll be able to implement the functionality of
  break, continue, and return using completions, which will lead to
  easier to understand code and fewer workarounds - the current
  unwinding mechanism is not even remotely similar to the spec's
  approach

The spec's NormalCompletion and ThrowCompletion AOs have been
implemented as simple wrappers around the JS::Completion constructor.
UpdateEmpty has been implemented as a JS::Completion method.

There's also a new VM::throw_completion<T>() helper, which basically
works like VM::throw_exception<T>() - it creates a T object (usually a
JS::Error), and returns it wrapped in a JS::Completion of Type::Throw.

Two temporary usage patterns have emerged:

1. Callee already returns ThrowCompletionOr, but caller doesn't:

    auto foo = TRY_OR_DISCARD(bar());

2. Caller already returns ThrowCompletionOr, but callee doesn't:

    auto foo = bar();
    if (auto* exception = vm.exception())
        return throw_completion(exception->value());

Eventually all error handling and unwrapping can be done with just TRY()
or possibly even operator? in the future :^)

Co-authored-by: Andreas Kling <kling@serenityos.org>
2021-09-15 23:46:53 +01:00
Linus Groh
1a7828a9f3 LibJS: Return default-constructed values instead of the INVALID constant
This is much more common across the whole codebase and even these two
files. The same is used to return an empty JS::Value in an exception
check, for example.
2021-09-15 18:41:33 +01:00
Linus Groh
657d17ace3 LibJS: Remove two unused includes from AbstractOperations.cpp 2021-09-15 18:36:06 +01:00
Ali Mohammad Pur
53d24fbd65 LibJS: Make References see into Environment's bindings as well
'bindings' is the spec-compliant version of 'variables', but we were
simply not even looking at them, which made things using bindings (such
as named function expressions) break in unexpected ways after the move
to using references in call expressions.

Co-Authored-By: davidot <david.tuin@gmail.com>
2021-09-15 11:56:00 +02:00
Linus Groh
88a31f3bac LibJS: Fix [[TimeZoneOffsetString]] value in ParseTemporalInstantString
This is a normative change in the Temporal spec.

See: 78c3b8b
2021-09-15 00:23:11 +01:00
Andreas Kling
df5414f47f LibJS: Reorganize ExecutionContext a little bit
- Move it to a separate header file
- Annotate the members that represent spec slots
- Reorganize the members (by spec vs non-spec)
2021-09-14 21:41:51 +02:00
Ali Mohammad Pur
72ddaa31e3 LibJS: Implement parsing and execution of optional chains 2021-09-14 20:03:27 +01:00
Ali Mohammad Pur
f7a68ae998 LibJS: Mark two JS::Reference functions const
These two are inherently const, and the next commit needs to call them
on a const object, so let's just mark them const.
2021-09-14 20:03:27 +01:00
Linus Groh
7c39a5860d LibJS: Convert Temporal.ZonedDateTime.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
297bf19508 LibJS: Convert Temporal.TimeZone.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
fdd26567c1 LibJS: Convert Temporal.PlainYearMonth.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
06f3defcf5 LibJS: Convert Temporal.PlainTime.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
6e5d6060fa LibJS: Convert Temporal.PlainMonthDay.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
c47c660477 LibJS: Convert Temporal.PlainDateTime.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
0a30705cf2 LibJS: Convert Temporal.PlainDate.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
7314d05ca7 LibJS: Convert Temporal.Instant.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
a5f559f38a LibJS: Convert Temporal.Duration.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
47bbdd157f LibJS: Convert Temporal.Calendar.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
8253e14818 LibJS: Convert Intl.NumberFormat.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
b0c1179ff8 LibJS: Convert Intl.Locale.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
c277658ca6 LibJS: Convert Intl.ListFormat.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
b256b50476 LibJS: Convert Intl.DisplayNames.prototype to be a PrototypeObject 2021-09-13 19:07:26 +01:00
Linus Groh
a9c33b5bbd LibJS: Remove leftover typed_this() declarations 2021-09-13 19:07:26 +01:00
Brian Gianforcaro
fc1b9288bc LibJS: Extract exception check duplication in iso_month_day_from_fields
Flagged by sonarcloud.
2021-09-13 14:05:22 +00:00
Linus Groh
4f362fc703 LibJS: Set OrdinaryFunctionObject's realm from the Tnterpreter
...instead of relying on the VM having a current execution context. This
was an incorrect assumption I made, and it caused onfoo attribute
handler construction in LibWeb to crash.
Just use the same mechanism as NativeFunction in the meantime.
2021-09-12 23:12:51 +01:00
Linus Groh
c5bd382524 LibJS: Leave NativeFunction's Realm unset if VM has no Interpreter
There's currently a fallback at the call site where the Realm is needed
(due to a slightly incorrect implementation of [[Call]] / [[Construct]])
so this is better than crashing (in LibWeb, currently).
2021-09-12 15:18:25 +02:00
Linus Groh
7b92889e6b LibJS: Change Interpreter::create_with_existing_{global_object => realm}
We need both a GlobalObject and Realm now, but can get the former from
the latter (once initialized).
This also fixes JS execution in LibWeb, as we failed to set the Realm of
the newly created Interpreter in this function.
2021-09-12 15:18:25 +02:00
Timothy Flynn
673fc02ac5 LibJS: Move locale_relevant_extension_keys to Intl.Locale 2021-09-12 12:57:17 +01:00
Timothy Flynn
7769cd2cab LibJS: Move number_format_relevant_extension_keys to Intl.NumberFormat
This method represents the Intl.NumberFormat's [[RelevantExtensionKeys]]
internal slot, so it makes more sense for this to be directly in the
class itself.
2021-09-12 12:57:17 +01:00
Timothy Flynn
94a5a0437c LibJS: Move Intl.NumberFormat's AOs to its object file 2021-09-12 12:57:17 +01:00
Timothy Flynn
0b08201fec LibJS: Move Intl.ListFormat's AOs to its object file
To be consistent with the style in Temporal, let's move all AOs in Intl
to their object file, rather than splitting the AOs between prototype
and constructor files.
2021-09-12 12:57:17 +01:00
Timothy Flynn
ae7b5280c2 LibJS: Make "options" objects const references in NumberFormat's AOs 2021-09-12 12:57:17 +01:00
Timothy Flynn
7f700bd84e LibJS: Make GetNumberOption's "options" object a const reference 2021-09-12 12:57:17 +01:00
Timothy Flynn
aa2af06c84 LibJS: Store Intl.Locale's "tag" argument as a plain string 2021-09-12 12:57:17 +01:00
Timothy Flynn
4411e16798 LibJS: Change GetOption AO to accept the options as a concrete Object
This was being verified at runtime anyways, so let the compiler ensure
it. This also matches the GetOption AO in Temporal now.
2021-09-12 12:57:17 +01:00
Timothy Flynn
ada56981dc LibJS: Sort Intl AbstractOperation declarations by spec ID
The definitions in the .cpp file are already sorted this way.
2021-09-12 12:57:17 +01:00
Timothy Flynn
094c390fb1 LibJS: Move CanonicalCodeForDisplayNames to Intl.DisplayNames
Intl.DisplayNames was the first Intl object implemented, and at that
point all AOs were just put into the main Intl AO header. But AOs that
belong to specific objects belong in that object's header. So this moves
CanonicalCodeForDisplayNames to the Intl.DisplayNames header.
2021-09-12 12:57:17 +01:00
Linus Groh
80e58dab9a LibJS: Make get_function_realm() actually return a Realm 2021-09-12 11:10:20 +01:00
Linus Groh
06e89311fa LibJS: Set the callee context's realm in prepare_for_ordinary_call()
This includes making FunctionObject::realm() actually return a Realm,
instead of a GlobalObject.
2021-09-12 11:10:20 +01:00
Linus Groh
332946ab4f LibJS: Prepare ExecutionContext to store the current Realm Record
Also add VM::current_realm() to retrieve it, similar to all the other
getters (running_execution_context() et al.).
2021-09-12 11:10:20 +01:00
Linus Groh
15c33477e4 LibJS: Make prepare_for_ordinary_call() new_target parameter an Object*
This got changed in the spec at some point, replacing the assertion in
step 1 with "... and newTarget (an Object or undefined)" in the
parameter description.
Subsequently, there's now one step less, so the numbers all change.
2021-09-12 11:10:20 +01:00
Linus Groh
f29a82dd84 LibJS: Move the GlobalEnvironment from GlobalObject to Realm
This is where the spec wants to have it. Requires a couple of hacks as
currently everything that needs a Realm actually has a GlobalObject, so
we need to go via the Interpreter.
2021-09-12 11:10:20 +01:00
Linus Groh
1e79934acf LibJS: Add [[GlobalThisValue]] internal slot to GlobalEnvironment
Instead of hardcoding the environment's global object as the return
value of GlobalEnvironment::global_this_value(), it now stores an Object
reference which is passed to the constructor for this purpose.

From the spec (https://tc39.es/ecma262/#sec-global-environment-records):

[[GlobalThisValue]] | Object | The value returned by this in global
scope. Hosts may provide any ECMAScript Object value.
2021-09-12 11:10:20 +01:00
Linus Groh
2b8d5696ab LibJS: Allocate a Realm next to GlobalObject in Interpreter::create()
Also pass a Realm reference to the Bytecode::Interpreter constructor,
just like we pass the GlobalObject.
2021-09-12 11:10:20 +01:00
Linus Groh
d9c3bafcd9 LibJS: Start adding a JS::Realm class (spec's "Realm Record") 2021-09-12 11:10:20 +01:00