[ddc] Adding a runtime flag for real deferred loading in DDC
Change-Id: If50f7437c827a32829f5093cb3a14cbc5e55f7a7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289340 Commit-Queue: Mark Zhou <markzipan@google.com> Reviewed-by: Anna Gringauze <annagrin@google.com>
This commit is contained in:
@@ -608,16 +608,25 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
}
|
||||
|
||||
@override
|
||||
String libraryToModule(Library library) {
|
||||
String libraryToModule(Library library, {bool throwIfNotFound = true}) {
|
||||
if (library.importUri.isScheme('dart')) {
|
||||
// TODO(jmesserly): we need to split out HTML.
|
||||
return js_ast.dartSdkModule;
|
||||
}
|
||||
var summary = _importToSummary[library]!;
|
||||
var summary = _importToSummary[library];
|
||||
if (summary == null) {
|
||||
if (throwIfNotFound) {
|
||||
throw StateError('Could not find summary for library "$library".');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
var moduleName = _summaryToModule[summary];
|
||||
if (moduleName == null) {
|
||||
throw StateError('Could not find module name for library "$library" '
|
||||
'from component "$summary".');
|
||||
if (throwIfNotFound) {
|
||||
throw StateError('Could not find module name for library "$library" '
|
||||
'from component "$summary".');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
return moduleName;
|
||||
}
|
||||
@@ -7050,9 +7059,11 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
|
||||
@override
|
||||
js_ast.Expression visitLoadLibrary(LoadLibrary node) =>
|
||||
runtimeCall('loadLibrary(#, #)', [
|
||||
runtimeCall('loadLibrary(#, #, #)', [
|
||||
js.string(node.import.enclosingLibrary.importUri.toString()),
|
||||
js.string(node.import.name!)
|
||||
js.string(node.import.name!),
|
||||
js.string(
|
||||
libraryToModule(node.import.targetLibrary, throwIfNotFound: false))
|
||||
]);
|
||||
|
||||
// TODO(jmesserly): DDC loads all libraries eagerly.
|
||||
|
||||
@@ -856,32 +856,51 @@ _canonicalMember(obj, name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
@notNull
|
||||
bool _realDeferredLoading = false;
|
||||
|
||||
/// Sets the runtime mode to perform deferred loading (instead of just runtime
|
||||
/// correctness checks on loaded libraries).
|
||||
///
|
||||
/// This is only supported in the DDC module system.
|
||||
void realDeferredLoading(bool enable) {
|
||||
_realDeferredLoading = enable;
|
||||
}
|
||||
|
||||
/// A map from libraries to a set of import prefixes that have been loaded.
|
||||
///
|
||||
/// Used to validate deferred library conventions.
|
||||
final deferredImports = JS<Object>('!', 'new Map()');
|
||||
|
||||
/// Emulates the implicit "loadLibrary" function provided by a deferred library.
|
||||
/// Loads the element [importPrefix] in the module [targetModule] from the
|
||||
/// context of the library [libraryUri].
|
||||
///
|
||||
/// Libraries are not actually deferred in DDC, so this just records the import
|
||||
/// for runtime validation, then returns a future that completes immediately.
|
||||
Future loadLibrary(
|
||||
@notNull String enclosingLibrary, @notNull String importPrefix) {
|
||||
var result = JS('', '#.get(#)', deferredImports, enclosingLibrary);
|
||||
if (JS<bool>('', '# === void 0', result)) {
|
||||
JS('', '#.set(#, # = new Set())', deferredImports, enclosingLibrary,
|
||||
result);
|
||||
/// Will load any modules required by [targetModule] as a side effect.
|
||||
/// Only supported in the DDC module system.
|
||||
Future<void> loadLibrary(@notNull String libraryUri,
|
||||
@notNull String importPrefix, @notNull String targetModule) {
|
||||
if (!_realDeferredLoading) {
|
||||
var result = JS('', '#.get(#)', deferredImports, libraryUri);
|
||||
if (JS<bool>('', '# === void 0', result)) {
|
||||
JS('', '#.set(#, # = new Set())', deferredImports, libraryUri, result);
|
||||
}
|
||||
JS('', '#.add(#)', result, importPrefix);
|
||||
return Future.value();
|
||||
} else {
|
||||
throw UnimplementedError('realDeferredLoading flag is not yet supported');
|
||||
}
|
||||
JS('', '#.add(#)', result, importPrefix);
|
||||
return Future.value();
|
||||
}
|
||||
|
||||
void checkDeferredIsLoaded(
|
||||
@notNull String enclosingLibrary, @notNull String importPrefix) {
|
||||
var loaded = JS('', '#.get(#)', deferredImports, enclosingLibrary);
|
||||
if (JS<bool>('', '# === void 0', loaded) ||
|
||||
JS<bool>('', '!#.has(#)', loaded, importPrefix)) {
|
||||
throwDeferredIsLoadedError(enclosingLibrary, importPrefix);
|
||||
@notNull String libraryUri, @notNull String importPrefix) {
|
||||
if (!_realDeferredLoading) {
|
||||
var loaded = JS('', '#.get(#)', deferredImports, libraryUri);
|
||||
if (JS<bool>('', '# === void 0', loaded) ||
|
||||
JS<bool>('', '!#.has(#)', loaded, importPrefix)) {
|
||||
throwDeferredIsLoadedError(libraryUri, importPrefix);
|
||||
}
|
||||
} else {
|
||||
throw UnimplementedError('realDeferredLoading flag is not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user