1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:48:11 +00:00

LibJS+LibWeb: More bringing module loading closer to spec

In particular, this patch removes three host hooks on JS::VM in favor
of the new JS-side module loading stuff.
This commit is contained in:
Andreas Kling 2023-12-02 22:56:47 +01:00
parent 07f567cd9f
commit 8b7d27b349
15 changed files with 234 additions and 319 deletions

View file

@ -67,46 +67,52 @@ ThrowCompletionOr<u32> Module::inner_module_evaluation(VM& vm, Vector<Module*>&,
}
// 16.2.1.9 FinishLoadingImportedModule ( referrer, specifier, payload, result ), https://tc39.es/ecma262/#sec-FinishLoadingImportedModule
// FIXME: We currently implement an outdated version of https://tc39.es/proposal-import-attributes, as such it is not possible to
// use the exact steps from https://tc39.es/proposal-import-attributes/#sec-HostLoadImportedModule here.
// FIXME: Support Realm for referrer.
void finish_loading_imported_module(Realm& realm, Variant<JS::NonnullGCPtr<JS::Script>, JS::NonnullGCPtr<JS::CyclicModule>> referrer, ModuleRequest const& module_request, GraphLoadingState& payload, ThrowCompletionOr<Module*> const& result)
void finish_loading_imported_module(ImportedModuleReferrer referrer, ModuleRequest const& module_request, ImportedModulePayload payload, ThrowCompletionOr<NonnullGCPtr<Module>> const& result)
{
// 1. If result is a normal completion, then
if (!result.is_error()) {
auto loaded_modules = referrer.visit(
[](JS::NonnullGCPtr<JS::Script> script) -> Vector<ModuleWithSpecifier> { return script->loaded_modules(); },
[](JS::NonnullGCPtr<JS::CyclicModule> module) -> Vector<ModuleWithSpecifier> { return module->loaded_modules(); });
// NOTE: Only Script and CyclicModule referrers have the [[LoadedModules]] internal slot.
if (referrer.has<NonnullGCPtr<Script>>() || referrer.has<NonnullGCPtr<CyclicModule>>()) {
auto loaded_modules = referrer.visit(
[](JS::NonnullGCPtr<JS::Script> script) -> Vector<ModuleWithSpecifier> { return script->loaded_modules(); },
[](JS::NonnullGCPtr<JS::CyclicModule> module) -> Vector<ModuleWithSpecifier> { return module->loaded_modules(); },
[](auto&) {
VERIFY_NOT_REACHED();
return Vector<ModuleWithSpecifier> {};
});
bool found_record = false;
bool found_record = false;
// a.a. If referrer.[[LoadedModules]] contains a Record whose [[Specifier]] is specifier, then
for (auto const& record : loaded_modules) {
if (record.specifier == module_request.module_specifier) {
// i. Assert: That Record's [[Module]] is result.[[Value]].
VERIFY(record.module == result.value());
found_record = true;
// a. If referrer.[[LoadedModules]] contains a Record whose [[Specifier]] is specifier, then
for (auto const& record : loaded_modules) {
if (record.specifier == module_request.module_specifier) {
// i. Assert: That Record's [[Module]] is result.[[Value]].
VERIFY(record.module == result.value());
found_record = true;
}
}
}
// b. Else,
if (!found_record) {
auto* module = const_cast<Module*>(result.value());
// b. Else,
if (!found_record) {
auto module = result.value();
// i. Append the Record { [[Specifier]]: specifier, [[Module]]: result.[[Value]] } to referrer.[[LoadedModules]].
loaded_modules.append(ModuleWithSpecifier {
.specifier = module_request.module_specifier,
.module = NonnullGCPtr<Module>(*module) });
// i. Append the Record { [[Specifier]]: specifier, [[Module]]: result.[[Value]] } to referrer.[[LoadedModules]].
loaded_modules.append(ModuleWithSpecifier {
.specifier = module_request.module_specifier,
.module = NonnullGCPtr<Module>(*module) });
}
}
}
// FIXME: 2. If payload is a GraphLoadingState Record, then
// a. Perform ContinueModuleLoading(payload, result)
continue_module_loading(realm, payload, result);
// FIXME: Else,
// FIXME: a. Perform ContinueDynamicImport(payload, result).
if (payload.has<NonnullGCPtr<GraphLoadingState>>()) {
// a. Perform ContinueModuleLoading(payload, result)
continue_module_loading(payload.get<NonnullGCPtr<GraphLoadingState>>(), result);
}
// Else,
else {
// a. Perform ContinueDynamicImport(payload, result).
continue_dynamic_import(payload.get<NonnullGCPtr<PromiseCapability>>(), result);
}
// 4. Return unused.
}