Skip to content

Commit

Permalink
LibWeb: Hook up the HostInitializeShadowRealm callback
Browse files Browse the repository at this point in the history
This is enough for a basic shadow realm to work :^)

There is more that we still need to implement here such as module
loading and fixing up the global object, but this is enough to get some
basic usage working.
  • Loading branch information
shannonbooth committed Oct 27, 2024
1 parent 12551db commit c4c6fba
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PASS: Exception thrown 'TypeError: Wrapped value must be primitive or a function object, got [object Promise]'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Shadow realm evaluation returned: 2
13 changes: 13 additions & 0 deletions Tests/LibWeb/Text/input/HTML/shadow-realm-async-evaluate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script src="../include.js"></script>
<script>
test(() => {
const realm = new ShadowRealm()
const aSync = realm.evaluate(`async () => 1 + 1`);
try {
aSync();
println('Fail! No exception thrown');
} catch (e) {
println(`PASS: Exception thrown '${e}'`);
}
})
</script>
8 changes: 8 additions & 0 deletions Tests/LibWeb/Text/input/HTML/shadow-realm-sync-evaluate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script src="../include.js"></script>
<script>
test(() => {
const realm = new ShadowRealm();
const result = realm.evaluate(`() => 1 + 1`)();
println(`Shadow realm evaluation returned: ${result}`);
});
</script>
2 changes: 1 addition & 1 deletion Userland/Libraries/LibJS/Runtime/VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class VM : public RefCounted<VM> {
Function<ThrowCompletionOr<void>(Object&)> host_ensure_can_add_private_element;
Function<ThrowCompletionOr<HandledByHost>(ArrayBuffer&, size_t)> host_resize_array_buffer;
Function<void(StringView)> host_unrecognized_date_string;
Function<ThrowCompletionOr<NonnullGCPtr<ShadowRealm>>(Realm&, NonnullOwnPtr<ExecutionContext>, ShadowRealm&)> host_initialize_shadow_realm;
Function<ThrowCompletionOr<NonnullGCPtr<Object>>(Realm&, NonnullOwnPtr<ExecutionContext>, ShadowRealm&)> host_initialize_shadow_realm;

Vector<StackTraceElement> stack_trace() const;

Expand Down
41 changes: 41 additions & 0 deletions Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
#include <LibJS/Runtime/FinalizationRegistry.h>
#include <LibJS/Runtime/ModuleRequest.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/ShadowRealm.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/SourceTextModule.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/Bindings/SyntheticHostDefined.h>
#include <LibWeb/Bindings/WindowExposedInterfaces.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/MutationType.h>
Expand All @@ -35,7 +37,9 @@
#include <LibWeb/HTML/Scripting/Fetching.h>
#include <LibWeb/HTML/Scripting/ModuleScript.h>
#include <LibWeb/HTML/Scripting/Script.h>
#include <LibWeb/HTML/Scripting/SyntheticRealmSettings.h>
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
#include <LibWeb/HTML/ShadowRealmGlobalScope.h>
#include <LibWeb/HTML/TagNames.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/HTML/WindowProxy.h>
Expand Down Expand Up @@ -560,6 +564,43 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
HTML::fetch_single_imported_module_script(*module_map_realm, url.release_value(), *fetch_client, destination, fetch_options, *module_map_realm, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete);
};

// https://whatpr.org/html/9893/webappapis.html#hostinitializeshadowrealm(realm,-context,-o)
// 8.1.6.8 HostInitializeShadowRealm(realm, context, O)
s_main_thread_vm->host_initialize_shadow_realm = [](JS::Realm& realm, NonnullOwnPtr<JS::ExecutionContext> context, JS::ShadowRealm& object) -> JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> {
auto& vm = realm.vm();

// FIXME: 1. Set realm's is global prototype chain mutable to true.

// 2. Let globalObject be a new ShadowRealmGlobalScope object with realm.
auto global_object = HTML::ShadowRealmGlobalScope::create(realm);

// 3. Let settings be a new synthetic realm settings object that this algorithm will subsequently initialize.
auto settings = HTML::SyntheticRealmSettings {
// 4. Set settings's execution context to context.
.execution_context = move(context),

// 5. Set settings's principal realm to O's associated realm
.principal_realm = object.shape().realm(),

// 6. Set settings's underlying realm to realm.
.underlying_realm = realm,

// 7. Set settings's module map to a new module map, initially empty.
.module_map = realm.heap().allocate<HTML::ModuleMap>(realm),
};

// 8. Set realm.[[HostDefined]] to settings.
realm.set_host_defined(make<Bindings::SyntheticHostDefined>(move(settings)));

// FIXME: Spec bug - it should probably either not push a new execution context before invoking this AO.
// See: https://github.com/whatwg/html/pull/9893#discussion_r1817870272
vm.pop_execution_context();
object.set_execution_context(vm.running_execution_context().copy());

// 9. Return globalObject.
return global_object;
};

s_main_thread_vm->host_unrecognized_date_string = [](StringView date) {
dbgln("Unable to parse date string: \"{}\"", date);
};
Expand Down

0 comments on commit c4c6fba

Please sign in to comment.