From 80c2b02bd0b0933a42ee063afe401737c54427f8 Mon Sep 17 00:00:00 2001 From: Mark Zhou Date: Fri, 17 Mar 2023 18:04:48 +0000 Subject: [PATCH] [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 Reviewed-by: Anna Gringauze --- pkg/dev_compiler/lib/src/kernel/compiler.dart | 23 ++++++--- .../private/ddc_runtime/operations.dart | 51 +++++++++++++------ 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index f4ff5630b68..da947f06ebe 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -608,16 +608,25 @@ class ProgramCompiler extends ComputeOnceConstantVisitor } @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 @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. diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index d79a8adf1c9..fc3e66390cf 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -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('!', '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('', '# === 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 loadLibrary(@notNull String libraryUri, + @notNull String importPrefix, @notNull String targetModule) { + if (!_realDeferredLoading) { + var result = JS('', '#.get(#)', deferredImports, libraryUri); + if (JS('', '# === 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('', '# === void 0', loaded) || - JS('', '!#.has(#)', loaded, importPrefix)) { - throwDeferredIsLoadedError(enclosingLibrary, importPrefix); + @notNull String libraryUri, @notNull String importPrefix) { + if (!_realDeferredLoading) { + var loaded = JS('', '#.get(#)', deferredImports, libraryUri); + if (JS('', '# === void 0', loaded) || + JS('', '!#.has(#)', loaded, importPrefix)) { + throwDeferredIsLoadedError(libraryUri, importPrefix); + } + } else { + throw UnimplementedError('realDeferredLoading flag is not yet supported'); } }