mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 06:23:45 +00:00
Improve dynamic module loading
We're seeing cases where known dynamic modules are being requested when the module isn't compiled yet. It's not clear how this is happening. I believe an empty cache entry is being created in postCompileModule and then the request for the dynamic module is happening before the sycnhronous module is loaded. This seems like the only way to get into this state ,but I can't reproduce it. Still, we now try to handle this case by simply having the dynamic module request overwrite the placeholder cache-entry created in postCompileModule.
This commit is contained in:
@@ -324,7 +324,7 @@ pub fn module(self: *Context, comptime want_result: bool, local: *const js.Local
|
|||||||
return if (comptime want_result) gop.value_ptr.* else {};
|
return if (comptime want_result) gop.value_ptr.* else {};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// first time seing this
|
// first time seeing this
|
||||||
gop.value_ptr.* = .{};
|
gop.value_ptr.* = .{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,6 +618,10 @@ fn _resolveModuleCallback(self: *Context, referrer: js.Module, specifier: [:0]co
|
|||||||
const mod = try compileModule(local, source.src(), normalized_specifier);
|
const mod = try compileModule(local, source.src(), normalized_specifier);
|
||||||
try self.postCompileModule(mod, normalized_specifier, local);
|
try self.postCompileModule(mod, normalized_specifier, local);
|
||||||
entry.module = try mod.persist();
|
entry.module = try mod.persist();
|
||||||
|
// Note: We don't instantiate/evaluate here - V8 will handle instantiation
|
||||||
|
// as part of the parent module's dependency chain. If there's a resolver
|
||||||
|
// waiting, it will be handled when the module is eventually evaluated
|
||||||
|
// (either as a top-level module or when accessed via dynamic import)
|
||||||
return mod.handle;
|
return mod.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,12 +658,14 @@ fn _dynamicModuleCallback(self: *Context, specifier: [:0]const u8, referrer: []c
|
|||||||
|
|
||||||
const promise = resolver.promise();
|
const promise = resolver.promise();
|
||||||
|
|
||||||
if (!gop.found_existing) {
|
if (!gop.found_existing or gop.value_ptr.module == null) {
|
||||||
|
// Either this is a completely new module, or it's an entry that was
|
||||||
|
// created (e.g., in postCompileModule) but not yet loaded
|
||||||
// this module hasn't been seen before. This is the most
|
// this module hasn't been seen before. This is the most
|
||||||
// complicated path.
|
// complicated path.
|
||||||
|
|
||||||
// First, we'll setup a bare entry into our cache. This will
|
// First, we'll setup a bare entry into our cache. This will
|
||||||
// prevent anyone one else from trying to asychronously load
|
// prevent anyone one else from trying to asynchronously load
|
||||||
// it. Instead, they can just return our promise.
|
// it. Instead, they can just return our promise.
|
||||||
gop.value_ptr.* = ModuleEntry{
|
gop.value_ptr.* = ModuleEntry{
|
||||||
.module = null,
|
.module = null,
|
||||||
@@ -674,19 +680,18 @@ fn _dynamicModuleCallback(self: *Context, specifier: [:0]const u8, referrer: []c
|
|||||||
};
|
};
|
||||||
|
|
||||||
// For now, we're done. but this will be continued in
|
// For now, we're done. but this will be continued in
|
||||||
// `dynamicModuleSourceCallback`, once the source for the
|
// `dynamicModuleSourceCallback`, once the source for the module is loaded.
|
||||||
// moduel is loaded.
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So we have a module, but no async resolver. This can only
|
// So we have a module, but no async resolver. This can only
|
||||||
// happen if the module was first synchronously loaded (Does that
|
// happen if the module was first synchronously loaded (Does that
|
||||||
// ever even happen?!) You'd think we cann just return the module
|
// ever even happen?!) You'd think we can just return the module
|
||||||
// but no, we need to resolve the module namespace, and the
|
// but no, we need to resolve the module namespace, and the
|
||||||
// module could still be loading!
|
// module could still be loading!
|
||||||
// We need to do part of what the first case is going to do in
|
// We need to do part of what the first case is going to do in
|
||||||
// `dynamicModuleSourceCallback`, but we can skip some steps
|
// `dynamicModuleSourceCallback`, but we can skip some steps
|
||||||
// since the module is alrady loaded,
|
// since the module is already loaded,
|
||||||
lp.assert(gop.value_ptr.module != null, "Context._dynamicModuleCallback has module", .{});
|
lp.assert(gop.value_ptr.module != null, "Context._dynamicModuleCallback has module", .{});
|
||||||
|
|
||||||
// If the module hasn't been evaluated yet (it was only instantiated
|
// If the module hasn't been evaluated yet (it was only instantiated
|
||||||
|
|||||||
Reference in New Issue
Block a user