فهرست منبع

LibJS: Replace GlobalObject with VM in Promise AOs [Part 8/19]

Linus Groh 2 سال پیش
والد
کامیت
d74f8039eb

+ 6 - 6
Userland/Libraries/LibJS/AST.cpp

@@ -3359,11 +3359,11 @@ Completion ImportCall::execute(Interpreter& interpreter) const
     // Note: options_value is undefined by default.
 
     // 6. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-    auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 7. Let specifierString be Completion(ToString(specifier)).
     // 8. IfAbruptRejectPromise(specifierString, promiseCapability).
-    auto specifier_string = TRY_OR_REJECT_WITH_VALUE(global_object, promise_capability, specifier->to_string(vm));
+    auto specifier_string = TRY_OR_REJECT_WITH_VALUE(vm, promise_capability, specifier->to_string(vm));
 
     // 9. Let assertions be a new empty List.
     Vector<ModuleRequest::Assertion> assertions;
@@ -3382,7 +3382,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
 
         // b. Let assertionsObj be Get(options, "assert").
         // c. IfAbruptRejectPromise(assertionsObj, promiseCapability).
-        auto assertion_object = TRY_OR_REJECT_WITH_VALUE(global_object, promise_capability, options_value.get(vm, vm.names.assert));
+        auto assertion_object = TRY_OR_REJECT_WITH_VALUE(vm, promise_capability, options_value.get(vm, vm.names.assert));
 
         // d. If assertionsObj is not undefined,
         if (!assertion_object.is_undefined()) {
@@ -3398,10 +3398,10 @@ Completion ImportCall::execute(Interpreter& interpreter) const
 
             // ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key).
             // iii. IfAbruptRejectPromise(keys, promiseCapability).
-            auto keys = TRY_OR_REJECT_WITH_VALUE(global_object, promise_capability, assertion_object.as_object().enumerable_own_property_names(Object::PropertyKind::Key));
+            auto keys = TRY_OR_REJECT_WITH_VALUE(vm, promise_capability, assertion_object.as_object().enumerable_own_property_names(Object::PropertyKind::Key));
 
             // iv. Let supportedAssertions be ! HostGetSupportedImportAssertions().
-            auto supported_assertions = interpreter.vm().host_get_supported_import_assertions();
+            auto supported_assertions = vm.host_get_supported_import_assertions();
 
             // v. For each String key of keys,
             for (auto const& key : keys) {
@@ -3409,7 +3409,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
 
                 // 1. Let value be Get(assertionsObj, key).
                 // 2. IfAbruptRejectPromise(value, promiseCapability).
-                auto value = TRY_OR_REJECT_WITH_VALUE(global_object, promise_capability, assertion_object.get(vm, property_key));
+                auto value = TRY_OR_REJECT_WITH_VALUE(vm, promise_capability, assertion_object.get(vm, property_key));
 
                 // 3. If Type(value) is not String, then
                 if (!value.is_string()) {

+ 2 - 2
Userland/Libraries/LibJS/CyclicModule.cpp

@@ -201,7 +201,7 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
 
     // 6. Let capability be ! NewPromiseCapability(%Promise%).
     // 7. Set module.[[TopLevelCapability]] to capability.
-    m_top_level_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    m_top_level_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 8. Let result be Completion(InnerModuleEvaluation(module, stack, 0)).
     auto result = inner_module_evaluation(vm, stack, 0);
@@ -443,7 +443,7 @@ void CyclicModule::execute_async_module(VM& vm)
     VERIFY(m_has_top_level_await);
 
     // 3. Let capability be ! NewPromiseCapability(%Promise%).
-    auto capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
     auto fulfilled_closure = [&](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {

+ 11 - 11
Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp

@@ -39,15 +39,15 @@ static Object* async_from_sync_iterator_continuation(VM& vm, Object& result, Pro
     // 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
     // 2. Let done be Completion(IteratorComplete(result)).
     // 3. IfAbruptRejectPromise(done, promiseCapability).
-    auto done = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_complete(vm, result));
+    auto done = TRY_OR_MUST_REJECT(vm, promise_capability, iterator_complete(vm, result));
 
     // 4. Let value be Completion(IteratorValue(result)).
     // 5. IfAbruptRejectPromise(value, promiseCapability).
-    auto value = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_value(vm, result));
+    auto value = TRY_OR_MUST_REJECT(vm, promise_capability, iterator_value(vm, result));
 
     // 6. Let valueWrapper be PromiseResolve(%Promise%, value).
     // 7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
-    auto value_wrapper = TRY_OR_MUST_REJECT(global_object, promise_capability, promise_resolve(global_object, *global_object.promise_constructor(), value));
+    auto value_wrapper = TRY_OR_MUST_REJECT(vm, promise_capability, promise_resolve(vm, *global_object.promise_constructor(), value));
 
     // 8. Let unwrap be a new Abstract Closure with parameters (value) that captures done and performs the following steps when called:
     auto unwrap = [done](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
@@ -74,7 +74,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::next)
     auto* this_object = MUST(typed_this_object(vm));
 
     // 3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-    auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
     auto& sync_iterator_record = this_object->sync_iterator_record();
@@ -84,7 +84,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::next)
     // 6. Else,
     //     a. Let result be Completion(IteratorNext(syncIteratorRecord)).
     // 7. IfAbruptRejectPromise(result, promiseCapability).
-    auto* result = TRY_OR_REJECT(global_object, promise_capability,
+    auto* result = TRY_OR_REJECT(vm, promise_capability,
         (vm.argument_count() > 0 ? iterator_next(vm, sync_iterator_record, vm.argument(0))
                                  : iterator_next(vm, sync_iterator_record)));
 
@@ -102,14 +102,14 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
     auto* this_object = MUST(typed_this_object(vm));
 
     // 3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-    auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
     auto* sync_iterator = this_object->sync_iterator_record().iterator;
 
     // 5. Let return be Completion(GetMethod(syncIterator, "return")).
     // 6. IfAbruptRejectPromise(return, promiseCapability).
-    auto* return_method = TRY_OR_REJECT(global_object, promise_capability, Value(sync_iterator).get_method(vm, vm.names.return_));
+    auto* return_method = TRY_OR_REJECT(vm, promise_capability, Value(sync_iterator).get_method(vm, vm.names.return_));
 
     // 7. If return is undefined, then
     if (return_method == nullptr) {
@@ -128,7 +128,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
     // 9. Else,
     //     a. Let result be Completion(Call(return, syncIterator)).
     // 10. IfAbruptRejectPromise(result, promiseCapability).
-    auto result = TRY_OR_REJECT(global_object, promise_capability,
+    auto result = TRY_OR_REJECT(vm, promise_capability,
         (vm.argument_count() > 0 ? call(global_object, return_method, sync_iterator, vm.argument(0))
                                  : call(global_object, return_method, sync_iterator)));
 
@@ -155,14 +155,14 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
     auto* this_object = MUST(typed_this_object(vm));
 
     // 3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-    auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
     auto* sync_iterator = this_object->sync_iterator_record().iterator;
 
     // 5. Let throw be Completion(GetMethod(syncIterator, "throw")).
     // 6. IfAbruptRejectPromise(throw, promiseCapability).
-    auto* throw_method = TRY_OR_REJECT(global_object, promise_capability, Value(sync_iterator).get_method(vm, vm.names.throw_));
+    auto* throw_method = TRY_OR_REJECT(vm, promise_capability, Value(sync_iterator).get_method(vm, vm.names.throw_));
 
     // 7. If throw is undefined, then
     if (throw_method == nullptr) {
@@ -176,7 +176,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
     // 9. Else,
     //     a. Let result be Completion(Call(throw, syncIterator)).
     // 10. IfAbruptRejectPromise(result, promiseCapability).
-    auto result = TRY_OR_REJECT(global_object, promise_capability,
+    auto result = TRY_OR_REJECT(vm, promise_capability,
         (vm.argument_count() > 0 ? call(global_object, throw_method, sync_iterator, vm.argument(0))
                                  : call(global_object, throw_method, sync_iterator)));
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Completion.cpp

@@ -38,7 +38,7 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
     // NOTE: This is not needed, as we don't suspend anything.
 
     // 2. Let promise be ? PromiseResolve(%Promise%, value).
-    auto* promise_object = TRY(promise_resolve(global_object, *global_object.promise_constructor(), value));
+    auto* promise_object = TRY(promise_resolve(vm, *global_object.promise_constructor(), value));
 
     Optional<bool> success;
     Value result;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp

@@ -867,7 +867,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
         // AsyncFunctionBody : FunctionBody
         else if (m_kind == FunctionKind::Async) {
             // 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-            auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+            auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
             // 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
             auto declaration_result = function_declaration_instantiation(ast_interpreter);

+ 1 - 2
Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp

@@ -53,7 +53,6 @@ void FinalizationRegistry::remove_dead_cells(Badge<Heap>)
 ThrowCompletionOr<void> FinalizationRegistry::cleanup(Optional<JobCallback> callback)
 {
     auto& vm = this->vm();
-    auto& global_object = this->global_object();
 
     // 1. Assert: finalizationRegistry has [[Cells]] and [[CleanupCallback]] internal slots.
     // Note: Ensured by type.
@@ -73,7 +72,7 @@ ThrowCompletionOr<void> FinalizationRegistry::cleanup(Optional<JobCallback> call
         it.remove(m_records);
 
         // c. Perform ? HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »).
-        TRY(vm.host_call_job_callback(global_object, cleanup_callback, js_undefined(), move(arguments)));
+        TRY(vm.host_call_job_callback(cleanup_callback, js_undefined(), move(arguments)));
     }
 
     // 4. Return unused.

+ 5 - 2
Userland/Libraries/LibJS/Runtime/JobCallback.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -30,8 +30,11 @@ inline JobCallback make_job_callback(FunctionObject& callback)
 }
 
 // 9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList ), https://tc39.es/ecma262/#sec-hostcalljobcallback
-inline ThrowCompletionOr<Value> call_job_callback(GlobalObject& global_object, JobCallback& job_callback, Value this_value, MarkedVector<Value> arguments_list)
+inline ThrowCompletionOr<Value> call_job_callback(VM& vm, JobCallback& job_callback, Value this_value, MarkedVector<Value> arguments_list)
 {
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
+
     // 1. Assert: IsCallable(jobCallback.[[Callback]]) is true.
     VERIFY(!job_callback.callback.is_null());
 

+ 8 - 7
Userland/Libraries/LibJS/Runtime/Promise.cpp

@@ -19,9 +19,10 @@
 namespace JS {
 
 // 27.2.4.7.1 PromiseResolve ( C, x ), https://tc39.es/ecma262/#sec-promise-resolve
-ThrowCompletionOr<Object*> promise_resolve(GlobalObject& global_object, Object& constructor, Value value)
+ThrowCompletionOr<Object*> promise_resolve(VM& vm, Object& constructor, Value value)
 {
-    auto& vm = global_object.vm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     // 1. If IsPromise(x) is true, then
     if (value.is_object() && is<Promise>(value.as_object())) {
@@ -34,7 +35,7 @@ ThrowCompletionOr<Object*> promise_resolve(GlobalObject& global_object, Object&
     }
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, &constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, &constructor));
 
     // 3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
     (void)TRY(call(global_object, *promise_capability.resolve, js_undefined(), value));
@@ -150,7 +151,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
 
         // 14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Creating PromiseResolveThenableJob for thenable {}", &promise, resolution);
-        auto job = create_promise_resolve_thenable_job(global_object, promise, resolution, move(then_job_callback));
+        auto job = create_promise_resolve_thenable_job(vm, promise, resolution, move(then_job_callback));
 
         // 15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job.job, job.realm);
@@ -274,7 +275,7 @@ void Promise::trigger_reactions() const
     for (auto& reaction : reactions) {
         // a. Let job be NewPromiseReactionJob(reaction, argument).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / trigger_reactions()]: Creating PromiseReactionJob for PromiseReaction @ {} with argument {}", this, &reaction, m_result);
-        auto [job, realm] = create_promise_reaction_job(global_object(), *reaction, m_result);
+        auto [job, realm] = create_promise_reaction_job(vm, *reaction, m_result);
 
         // b. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / trigger_reactions()]: Enqueuing job @ {} in realm {}", this, &job, realm);
@@ -344,7 +345,7 @@ Value Promise::perform_then(Value on_fulfilled, Value on_rejected, Optional<Prom
 
         // b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: State is State::Fulfilled, creating PromiseReactionJob for PromiseReaction @ {} with argument {}", this, fulfill_reaction, value);
-        auto [fulfill_job, realm] = create_promise_reaction_job(global_object(), *fulfill_reaction, value);
+        auto [fulfill_job, realm] = create_promise_reaction_job(vm, *fulfill_reaction, value);
 
         // c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &fulfill_job, realm);
@@ -364,7 +365,7 @@ Value Promise::perform_then(Value on_fulfilled, Value on_rejected, Optional<Prom
 
         // d. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: State is State::Rejected, creating PromiseReactionJob for PromiseReaction @ {} with argument {}", this, reject_reaction, reason);
-        auto [reject_job, realm] = create_promise_reaction_job(global_object(), *reject_reaction, reason);
+        auto [reject_job, realm] = create_promise_reaction_job(vm, *reject_reaction, reason);
 
         // e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
         dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &reject_job, realm);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Promise.h

@@ -11,7 +11,7 @@
 
 namespace JS {
 
-ThrowCompletionOr<Object*> promise_resolve(GlobalObject&, Object& constructor, Value);
+ThrowCompletionOr<Object*> promise_resolve(VM&, Object& constructor, Value);
 
 class Promise : public Object {
     JS_OBJECT(Promise, Object);

+ 39 - 42
Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp

@@ -21,10 +21,9 @@
 namespace JS {
 
 // 27.2.4.1.1 GetPromiseResolve ( promiseConstructor ), https://tc39.es/ecma262/#sec-getpromiseresolve
-static ThrowCompletionOr<Value> get_promise_resolve(GlobalObject& global_object, Value constructor)
+static ThrowCompletionOr<Value> get_promise_resolve(VM& vm, Value constructor)
 {
     VERIFY(constructor.is_constructor());
-    auto& vm = global_object.vm();
 
     // 1. Let promiseResolve be ? Get(promiseConstructor, "resolve").
     auto promise_resolve = TRY(constructor.get(vm, vm.names.resolve));
@@ -40,9 +39,10 @@ static ThrowCompletionOr<Value> get_promise_resolve(GlobalObject& global_object,
 using EndOfElementsCallback = Function<ThrowCompletionOr<Value>(PromiseValueList&)>;
 using InvokeElementFunctionCallback = Function<ThrowCompletionOr<Value>(PromiseValueList&, RemainingElements&, Value, size_t)>;
 
-static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve, EndOfElementsCallback end_of_list, InvokeElementFunctionCallback invoke_element_function)
+static ThrowCompletionOr<Value> perform_promise_common(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve, EndOfElementsCallback end_of_list, InvokeElementFunctionCallback invoke_element_function)
 {
-    auto& vm = global_object.vm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     VERIFY(constructor.is_constructor());
     VERIFY(promise_resolve.is_function());
@@ -116,13 +116,13 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
 }
 
 // 27.2.4.1.2 PerformPromiseAll ( iteratorRecord, constructor, resultCapability, promiseResolve ), https://tc39.es/ecma262/#sec-performpromiseall
-static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
+static ThrowCompletionOr<Value> perform_promise_all(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
 {
-    auto& vm = global_object.vm();
-    auto& realm = *global_object.associated_realm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     return perform_promise_common(
-        global_object, iterator_record, constructor, result_capability, promise_resolve,
+        vm, iterator_record, constructor, result_capability, promise_resolve,
         [&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
             // 1. Let valuesArray be CreateArrayFromList(values).
             auto* values_array = Array::create_from(realm, values.values());
@@ -151,13 +151,13 @@ static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object,
 }
 
 // 27.2.4.2.1 PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, promiseResolve ), https://tc39.es/ecma262/#sec-performpromiseallsettled
-static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
+static ThrowCompletionOr<Value> perform_promise_all_settled(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
 {
-    auto& vm = global_object.vm();
-    auto& realm = *global_object.associated_realm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     return perform_promise_common(
-        global_object, iterator_record, constructor, result_capability, promise_resolve,
+        vm, iterator_record, constructor, result_capability, promise_resolve,
         [&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
             auto* values_array = Array::create_from(realm, values.values());
 
@@ -195,13 +195,12 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
 }
 
 // 27.2.4.3.1 PerformPromiseAny ( iteratorRecord, constructor, resultCapability, promiseResolve ), https://tc39.es/ecma262/#sec-performpromiseany
-static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
+static ThrowCompletionOr<Value> perform_promise_any(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
 {
-    auto& vm = global_object.vm();
-    auto& realm = *global_object.associated_realm();
+    auto& realm = *vm.current_realm();
 
     return perform_promise_common(
-        global_object, iterator_record, constructor, result_capability, promise_resolve,
+        vm, iterator_record, constructor, result_capability, promise_resolve,
         [&](PromiseValueList& errors) -> ThrowCompletionOr<Value> {
             // 1. Let error be a newly created AggregateError object.
             auto* error = AggregateError::create(realm);
@@ -231,12 +230,10 @@ static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object,
 }
 
 // 27.2.4.5.1 PerformPromiseRace ( iteratorRecord, constructor, resultCapability, promiseResolve ), https://tc39.es/ecma262/#sec-performpromiserace
-static ThrowCompletionOr<Value> perform_promise_race(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
+static ThrowCompletionOr<Value> perform_promise_race(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
 {
-    auto& vm = global_object.vm();
-
     return perform_promise_common(
-        global_object, iterator_record, constructor, result_capability, promise_resolve,
+        vm, iterator_record, constructor, result_capability, promise_resolve,
         [&](PromiseValueList&) -> ThrowCompletionOr<Value> {
             // ii. Return resultCapability.[[Promise]].
             return Value(result_capability.promise);
@@ -324,18 +321,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
     auto* constructor = TRY(vm.this_value().to_object(vm));
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, constructor));
 
     // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
-    auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
+    auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
 
     // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
-    auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
+    auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0)));
 
     // 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
-    auto result = perform_promise_all(global_object, iterator_record, constructor, promise_capability, promise_resolve);
+    auto result = perform_promise_all(vm, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
@@ -344,7 +341,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
             result = iterator_close(vm, iterator_record, result.release_error());
 
         // b. IfAbruptRejectPromise(result, promiseCapability).
-        TRY_OR_REJECT(global_object, promise_capability, result);
+        TRY_OR_REJECT(vm, promise_capability, result);
     }
 
     // 9. Return ? result.
@@ -358,18 +355,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
     auto* constructor = TRY(vm.this_value().to_object(vm));
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, constructor));
 
     // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
-    auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
+    auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
 
     // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
-    auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
+    auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0)));
 
     // 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
-    auto result = perform_promise_all_settled(global_object, iterator_record, constructor, promise_capability, promise_resolve);
+    auto result = perform_promise_all_settled(vm, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
@@ -378,7 +375,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
             result = iterator_close(vm, iterator_record, result.release_error());
 
         // b. IfAbruptRejectPromise(result, promiseCapability).
-        TRY_OR_REJECT(global_object, promise_capability, result);
+        TRY_OR_REJECT(vm, promise_capability, result);
     }
 
     // 9. Return ? result.
@@ -392,18 +389,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
     auto* constructor = TRY(vm.this_value().to_object(vm));
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, constructor));
 
     // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
-    auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
+    auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
 
     // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
-    auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
+    auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0)));
 
     // 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
-    auto result = perform_promise_any(global_object, iterator_record, constructor, promise_capability, promise_resolve);
+    auto result = perform_promise_any(vm, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
@@ -412,7 +409,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
             result = iterator_close(vm, iterator_record, result.release_error());
 
         // b. IfAbruptRejectPromise(result, promiseCapability).
-        TRY_OR_REJECT(global_object, promise_capability, result);
+        TRY_OR_REJECT(vm, promise_capability, result);
     }
 
     // 9. Return ? result.
@@ -426,18 +423,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
     auto* constructor = TRY(vm.this_value().to_object(vm));
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, constructor));
 
     // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
-    auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
+    auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
 
     // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
-    auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
+    auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0)));
 
     // 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
-    auto result = perform_promise_race(global_object, iterator_record, constructor, promise_capability, promise_resolve);
+    auto result = perform_promise_race(vm, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
@@ -446,7 +443,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
             result = iterator_close(vm, iterator_record, result.release_error());
 
         // b. IfAbruptRejectPromise(result, promiseCapability).
-        TRY_OR_REJECT(global_object, promise_capability, result);
+        TRY_OR_REJECT(vm, promise_capability, result);
     }
 
     // 9. Return ? result.
@@ -462,7 +459,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
     auto* constructor = TRY(vm.this_value().to_object(vm));
 
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
-    auto promise_capability = TRY(new_promise_capability(global_object, constructor));
+    auto promise_capability = TRY(new_promise_capability(vm, constructor));
 
     // 3. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
     [[maybe_unused]] auto result = TRY(JS::call(global_object, *promise_capability.reject, js_undefined(), reason));
@@ -484,7 +481,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
         return vm.throw_completion<TypeError>(ErrorType::NotAnObject, constructor.to_string_without_side_effects());
 
     // 3. Return ? PromiseResolve(C, x).
-    return TRY(promise_resolve(global_object, constructor.as_object(), value));
+    return TRY(promise_resolve(vm, constructor.as_object(), value));
 }
 
 // 27.2.4.8 get Promise [ @@species ], https://tc39.es/ecma262/#sec-get-promise-@@species

+ 22 - 14
Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp

@@ -16,9 +16,10 @@
 namespace JS {
 
 // 27.2.2.1 NewPromiseReactionJob ( reaction, argument ), https://tc39.es/ecma262/#sec-newpromisereactionjob
-static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, PromiseReaction& reaction, Value argument)
+static ThrowCompletionOr<Value> run_reaction_job(VM& vm, PromiseReaction& reaction, Value argument)
 {
-    auto& vm = global_object.vm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     // a. Let promiseCapability be reaction.[[Capability]].
     auto& promise_capability = reaction.capability();
@@ -55,7 +56,7 @@ static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, Pr
         dbgln_if(PROMISE_DEBUG, "run_reaction_job: Calling handler callback {} @ {} with argument {}", handler.value().callback.cell()->class_name(), handler.value().callback.cell(), argument);
         MarkedVector<Value> arguments(vm.heap());
         arguments.append(argument);
-        handler_result = vm.host_call_job_callback(global_object, handler.value(), js_undefined(), move(arguments));
+        handler_result = vm.host_call_job_callback(handler.value(), js_undefined(), move(arguments));
     }
 
     // f. If promiseCapability is undefined, then
@@ -89,12 +90,15 @@ static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, Pr
 }
 
 // 27.2.2.1 NewPromiseReactionJob ( reaction, argument ), https://tc39.es/ecma262/#sec-newpromisereactionjob
-PromiseJob create_promise_reaction_job(GlobalObject& global_object, PromiseReaction& reaction, Value argument)
+PromiseJob create_promise_reaction_job(VM& vm, PromiseReaction& reaction, Value argument)
 {
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
+
     // 1. Let job be a new Job Abstract Closure with no parameters that captures reaction and argument and performs the following steps when called:
     //    See run_reaction_job for "the following steps".
-    auto job = [global_object = make_handle(&global_object), reaction = make_handle(&reaction), argument = make_handle(argument)]() mutable {
-        return run_reaction_job(*global_object.cell(), *reaction.cell(), argument.value());
+    auto job = [&vm, reaction = make_handle(&reaction), argument = make_handle(argument)]() mutable {
+        return run_reaction_job(vm, *reaction.cell(), argument.value());
     };
 
     // 2. Let handlerRealm be null.
@@ -111,7 +115,7 @@ PromiseJob create_promise_reaction_job(GlobalObject& global_object, PromiseReact
             handler_realm = get_handler_realm_result.release_value();
         } else {
             // c. Else, set handlerRealm to the current Realm Record.
-            handler_realm = global_object.vm().current_realm();
+            handler_realm = vm.current_realm();
         }
 
         // d. NOTE: handlerRealm is never null unless the handler is undefined. When the handler is a revoked Proxy and no ECMAScript code runs, handlerRealm is used to create error objects.
@@ -122,9 +126,10 @@ PromiseJob create_promise_reaction_job(GlobalObject& global_object, PromiseReact
 }
 
 // 27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then ), https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob
-static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_object, Promise& promise_to_resolve, Value thenable, JobCallback& then)
+static ThrowCompletionOr<Value> run_resolve_thenable_job(VM& vm, Promise& promise_to_resolve, Value thenable, JobCallback& then)
 {
-    auto& vm = global_object.vm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     // a. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
     auto [resolve_function, reject_function] = promise_to_resolve.create_resolving_functions();
@@ -134,7 +139,7 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_ob
     MarkedVector<Value> arguments(vm.heap());
     arguments.append(Value(&resolve_function));
     arguments.append(Value(&reject_function));
-    auto then_call_result = vm.host_call_job_callback(global_object, then, thenable, move(arguments));
+    auto then_call_result = vm.host_call_job_callback(then, thenable, move(arguments));
 
     // c. If thenCallResult is an abrupt completion, then
     if (then_call_result.is_error()) {
@@ -149,8 +154,11 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_ob
 }
 
 // 27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then ), https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob
-PromiseJob create_promise_resolve_thenable_job(GlobalObject& global_object, Promise& promise_to_resolve, Value thenable, JobCallback then)
+PromiseJob create_promise_resolve_thenable_job(VM& vm, Promise& promise_to_resolve, Value thenable, JobCallback then)
 {
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
+
     // 2. Let getThenRealmResult be Completion(GetFunctionRealm(then.[[Callback]])).
     auto get_then_realm_result = get_function_realm(global_object, *then.callback.cell());
 
@@ -161,7 +169,7 @@ PromiseJob create_promise_resolve_thenable_job(GlobalObject& global_object, Prom
         then_realm = get_then_realm_result.release_value();
     } else {
         // 4. Else, let thenRealm be the current Realm Record.
-        then_realm = global_object.vm().current_realm();
+        then_realm = vm.current_realm();
     }
 
     // 5. NOTE: thenRealm is never null. When then.[[Callback]] is a revoked Proxy and no code runs, thenRealm is used to create error objects.
@@ -170,8 +178,8 @@ PromiseJob create_promise_resolve_thenable_job(GlobalObject& global_object, Prom
     // 1. Let job be a new Job Abstract Closure with no parameters that captures promiseToResolve, thenable, and then and performs the following steps when called:
     //    See PromiseResolveThenableJob::call() for "the following steps".
     //    NOTE: This is done out of order, since `then` is moved into the lambda and `then` would be invalid if it was done at the start.
-    auto job = [global_object = make_handle(&global_object), promise_to_resolve = make_handle(&promise_to_resolve), thenable = make_handle(thenable), then = move(then)]() mutable {
-        return run_resolve_thenable_job(*global_object.cell(), *promise_to_resolve.cell(), thenable.value(), then);
+    auto job = [&vm, promise_to_resolve = make_handle(&promise_to_resolve), thenable = make_handle(thenable), then = move(then)]() mutable {
+        return run_resolve_thenable_job(vm, *promise_to_resolve.cell(), thenable.value(), then);
     };
 
     // 6. Return the Record { [[Job]]: job, [[Realm]]: thenRealm }.

+ 3 - 3
Userland/Libraries/LibJS/Runtime/PromiseJobs.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -20,7 +20,7 @@ struct PromiseJob {
 };
 
 // NOTE: These return a PromiseJob to prevent awkward casting at call sites.
-PromiseJob create_promise_reaction_job(GlobalObject&, PromiseReaction&, Value argument);
-PromiseJob create_promise_resolve_thenable_job(GlobalObject&, Promise&, Value thenable, JobCallback then);
+PromiseJob create_promise_reaction_job(VM&, PromiseReaction&, Value argument);
+PromiseJob create_promise_resolve_thenable_job(VM&, Promise&, Value thenable, JobCallback then);
 
 }

+ 3 - 3
Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp

@@ -49,7 +49,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::then)
     auto* constructor = TRY(species_constructor(global_object, *promise, *global_object.promise_constructor()));
 
     // 4. Let resultCapability be ? NewPromiseCapability(C).
-    auto result_capability = TRY(new_promise_capability(global_object, constructor));
+    auto result_capability = TRY(new_promise_capability(vm, constructor));
 
     // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).
     return promise->perform_then(on_fulfilled, on_rejected, result_capability);
@@ -111,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
             auto result = TRY(call(global_object, on_finally, js_undefined()));
 
             // ii. Let promise be ? PromiseResolve(C, result).
-            auto* promise = TRY(promise_resolve(global_object, constructor, result));
+            auto* promise = TRY(promise_resolve(vm, constructor, result));
 
             // iii. Let returnValue be a new Abstract Closure with no parameters that captures value and performs the following steps when called:
             auto return_value = [value_handle = make_handle(value)](auto&, auto&) -> ThrowCompletionOr<Value> {
@@ -140,7 +140,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
             auto result = TRY(call(global_object, on_finally, js_undefined()));
 
             // ii. Let promise be ? PromiseResolve(C, result).
-            auto* promise = TRY(promise_resolve(global_object, constructor, result));
+            auto* promise = TRY(promise_resolve(vm, constructor, result));
 
             // iii. Let throwReason be a new Abstract Closure with no parameters that captures reason and performs the following steps when called:
             auto throw_reason = [reason_handle = make_handle(reason)](auto&, auto&) -> ThrowCompletionOr<Value> {

+ 3 - 3
Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp

@@ -12,10 +12,10 @@
 namespace JS {
 
 // 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
-ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global_object, Value constructor)
+ThrowCompletionOr<PromiseCapability> new_promise_capability(VM& vm, Value constructor)
 {
-    auto& vm = global_object.vm();
-    auto& realm = *global_object.associated_realm();
+    auto& realm = *vm.current_realm();
+    auto& global_object = realm.global_object();
 
     // 1. If IsConstructor(C) is false, throw a TypeError exception.
     if (!constructor.is_constructor())

+ 37 - 33
Userland/Libraries/LibJS/Runtime/PromiseReaction.h

@@ -21,47 +21,51 @@ struct PromiseCapability {
 };
 
 // 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
-#define __TRY_OR_REJECT(global_object, capability, expression, CALL_CHECK)                                                                     \
-    ({                                                                                                                                         \
-        auto _temporary_try_or_reject_result = (expression);                                                                                   \
-        /* 1. If value is an abrupt completion, then */                                                                                        \
-        if (_temporary_try_or_reject_result.is_error()) {                                                                                      \
-            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                                  \
-            CALL_CHECK(JS::call(global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
-                                                                                                                                               \
-            /* b. Return capability.[[Promise]]. */                                                                                            \
-            return capability.promise;                                                                                                         \
-        }                                                                                                                                      \
-                                                                                                                                               \
-        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                           \
-        _temporary_try_or_reject_result.release_value();                                                                                       \
+#define __TRY_OR_REJECT(vm, capability, expression, CALL_CHECK)                                                                                 \
+    ({                                                                                                                                          \
+        auto& _realm = *vm.current_realm();                                                                                                     \
+        auto& _global_object = _realm.global_object();                                                                                          \
+        auto _temporary_try_or_reject_result = (expression);                                                                                    \
+        /* 1. If value is an abrupt completion, then */                                                                                         \
+        if (_temporary_try_or_reject_result.is_error()) {                                                                                       \
+            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                                   \
+            CALL_CHECK(JS::call(_global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
+                                                                                                                                                \
+            /* b. Return capability.[[Promise]]. */                                                                                             \
+            return capability.promise;                                                                                                          \
+        }                                                                                                                                       \
+                                                                                                                                                \
+        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                            \
+        _temporary_try_or_reject_result.release_value();                                                                                        \
     })
 
-#define TRY_OR_REJECT(global_object, capability, expression) \
-    __TRY_OR_REJECT(global_object, capability, expression, TRY)
+#define TRY_OR_REJECT(vm, capability, expression) \
+    __TRY_OR_REJECT(vm, capability, expression, TRY)
 
-#define TRY_OR_MUST_REJECT(global_object, capability, expression) \
-    __TRY_OR_REJECT(global_object, capability, expression, MUST)
+#define TRY_OR_MUST_REJECT(vm, capability, expression) \
+    __TRY_OR_REJECT(vm, capability, expression, MUST)
 
 // 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
-#define TRY_OR_REJECT_WITH_VALUE(global_object, capability, expression)                                                                 \
-    ({                                                                                                                                  \
-        auto _temporary_try_or_reject_result = (expression);                                                                            \
-        /* 1. If value is an abrupt completion, then */                                                                                 \
-        if (_temporary_try_or_reject_result.is_error()) {                                                                               \
-            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                           \
-            TRY(JS::call(global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
-                                                                                                                                        \
-            /* b. Return capability.[[Promise]]. */                                                                                     \
-            return Value { capability.promise };                                                                                        \
-        }                                                                                                                               \
-                                                                                                                                        \
-        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                    \
-        _temporary_try_or_reject_result.release_value();                                                                                \
+#define TRY_OR_REJECT_WITH_VALUE(vm, capability, expression)                                                                             \
+    ({                                                                                                                                   \
+        auto& _realm = *vm.current_realm();                                                                                              \
+        auto& _global_object = _realm.global_object();                                                                                   \
+        auto _temporary_try_or_reject_result = (expression);                                                                             \
+        /* 1. If value is an abrupt completion, then */                                                                                  \
+        if (_temporary_try_or_reject_result.is_error()) {                                                                                \
+            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                            \
+            TRY(JS::call(_global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
+                                                                                                                                         \
+            /* b. Return capability.[[Promise]]. */                                                                                      \
+            return Value { capability.promise };                                                                                         \
+        }                                                                                                                                \
+                                                                                                                                         \
+        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                     \
+        _temporary_try_or_reject_result.release_value();                                                                                 \
     })
 
 // 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
-ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global_object, Value constructor);
+ThrowCompletionOr<PromiseCapability> new_promise_capability(VM& vm, Value constructor);
 
 // 27.2.1.2 PromiseReaction Records, https://tc39.es/ecma262/#sec-promisereaction-records
 class PromiseReaction final : public Cell {

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp

@@ -214,7 +214,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
     // 1. Assert: evalContext is an execution context associated to a ShadowRealm instance's [[ExecutionContext]].
 
     // 2. Let innerCapability be ! NewPromiseCapability(%Promise%).
-    auto inner_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto inner_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // 3. Let runningContext be the running execution context.
     // 4. If runningContext is not already suspended, suspend runningContext.
@@ -269,7 +269,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
     auto* on_fulfilled = NativeFunction::create(realm, move(steps), 1, "", &caller_realm);
 
     // 12. Let promiseCapability be ! NewPromiseCapability(%Promise%).
-    auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
+    auto promise_capability = MUST(new_promise_capability(vm, global_object.promise_constructor()));
 
     // NOTE: Even though the spec tells us to use %ThrowTypeError%, it's not observable if we actually do.
     // Throw a nicer TypeError forwarding the import error message instead (we know the argument is an Error object).

+ 2 - 2
Userland/Libraries/LibJS/Runtime/VM.cpp

@@ -51,8 +51,8 @@ VM::VM(OwnPtr<CustomData> custom_data)
         promise_rejection_tracker(promise, operation);
     };
 
-    host_call_job_callback = [](GlobalObject& global_object, JobCallback& job_callback, Value this_value, MarkedVector<Value> arguments) {
-        return call_job_callback(global_object, job_callback, this_value, move(arguments));
+    host_call_job_callback = [this](JobCallback& job_callback, Value this_value, MarkedVector<Value> arguments) {
+        return call_job_callback(*this, job_callback, this_value, move(arguments));
     };
 
     host_enqueue_finalization_registry_cleanup_job = [this](FinalizationRegistry& finalization_registry) {

+ 1 - 1
Userland/Libraries/LibJS/Runtime/VM.h

@@ -229,7 +229,7 @@ public:
     void enable_default_host_import_module_dynamically_hook();
 
     Function<void(Promise&, Promise::RejectionOperation)> host_promise_rejection_tracker;
-    Function<ThrowCompletionOr<Value>(GlobalObject&, JobCallback&, Value, MarkedVector<Value>)> host_call_job_callback;
+    Function<ThrowCompletionOr<Value>(JobCallback&, Value, MarkedVector<Value>)> host_call_job_callback;
     Function<void(FinalizationRegistry&)> host_enqueue_finalization_registry_cleanup_job;
     Function<void(Function<ThrowCompletionOr<Value>()>, Realm*)> host_enqueue_promise_job;
     Function<JobCallback(FunctionObject&)> host_make_job_callback;

+ 3 - 1
Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp

@@ -128,7 +128,9 @@ JS::VM& main_thread_vm()
         };
 
         // 8.1.5.3.1 HostCallJobCallback(callback, V, argumentsList), https://html.spec.whatwg.org/multipage/webappapis.html#hostcalljobcallback
-        vm->host_call_job_callback = [](JS::GlobalObject& global_object, JS::JobCallback& callback, JS::Value this_value, JS::MarkedVector<JS::Value> arguments_list) {
+        vm->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, JS::MarkedVector<JS::Value> arguments_list) {
+            auto& realm = *vm->current_realm();
+            auto& global_object = realm.global_object();
             auto& callback_host_defined = verify_cast<WebEngineCustomJobCallbackData>(*callback.custom_data);
 
             // 1. Let incumbent settings be callback.[[HostDefined]].[[IncumbentSettings]]. (NOTE: Not necessary)