@@ -86,7 +86,6 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
8686 final WasmCompilerOptions options;
8787 final WasmTarget kernelTarget;
8888 final CoreTypes coreTypes;
89- final Map <String , Map <String , String >> loadIdMap = {};
9089 late final ModuleOutputData moduleOutputData;
9190
9291 DeferredLoadingModuleStrategy (
@@ -95,7 +94,7 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
9594 @override
9695 void prepareComponent () {
9796 if (options.loadsIdsUri != null ) {
98- component.accept (_DeferredLoadingLoadIdTransformer (coreTypes, loadIdMap ));
97+ component.accept (_DeferredLoadingLoadIdTransformer (component, coreTypes ));
9998 }
10099 }
101100
@@ -142,8 +141,7 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
142141 moduleMap[enclosingLibrary] = outputMapping;
143142 });
144143
145- await _initDeferredImports (
146- component, coreTypes, options, loadIdMap, moduleMap);
144+ await _initDeferredImports (component, coreTypes, options, moduleMap);
147145
148146 moduleOutputData =
149147 ModuleOutputData ([mainModule, ...rootSetToModule.values]);
@@ -229,7 +227,6 @@ class StressTestModuleStrategy extends ModuleStrategy {
229227 final WasmTarget kernelTarget;
230228 final ClassHierarchy classHierarchy;
231229 final WasmCompilerOptions options;
232- final Map <String , Map <String , String >> loadIdMap = {};
233230 late final ModuleOutputData moduleOutputData;
234231
235232 /// We load all 'dart:*' libraries since just doing the deferred load of modules
@@ -287,7 +284,7 @@ class StressTestModuleStrategy extends ModuleStrategy {
287284 [invokeMain.enclosingLibrary], classHierarchy, coreTypes);
288285
289286 if (options.loadsIdsUri != null ) {
290- component.accept (_DeferredLoadingLoadIdTransformer (coreTypes, loadIdMap ));
287+ component.accept (_DeferredLoadingLoadIdTransformer (component, coreTypes ));
291288 }
292289 }
293290
@@ -310,7 +307,7 @@ class StressTestModuleStrategy extends ModuleStrategy {
310307 importMap[importName] = [module];
311308 }
312309
313- await _initDeferredImports (component, coreTypes, options, loadIdMap,
310+ await _initDeferredImports (component, coreTypes, options,
314311 {coreTypes.index.getLibrary ('dart:_internal' ): importMap});
315312
316313 moduleOutputData = ModuleOutputData ([mainModule, ...modules]);
@@ -324,13 +321,11 @@ Future<void> _initDeferredImports(
324321 Component component,
325322 CoreTypes coreTypes,
326323 WasmCompilerOptions options,
327- Map <String , Map <String , String >> loadIdMap,
328324 Map <Library , Map <String , List <ModuleMetadata >>> moduleMap) async {
329325 if (options.loadsIdsUri == null ) {
330326 _initDeferredImportsPrefix (component, coreTypes, options, moduleMap);
331327 } else {
332- await _initDeferredImportsLoadIds (
333- component, coreTypes, options, loadIdMap, moduleMap);
328+ await _initDeferredImportsLoadIds (component, coreTypes, options, moduleMap);
334329 }
335330}
336331
@@ -377,34 +372,38 @@ Future<void> _initDeferredImportsLoadIds(
377372 Component component,
378373 CoreTypes coreTypes,
379374 WasmCompilerOptions options,
380- Map <String , Map <String , String >> loadIdMap,
381375 Map <Library , Map <String , List <ModuleMetadata >>> moduleMap) async {
382- await (File .fromUri (options.loadsIdsUri! )..createSync ()).writeAsString (
383- _generateDeferredMapJson (component.mainMethod! .enclosingLibrary.importUri,
384- moduleMap, loadIdMap));
376+ final file = File .fromUri (options.loadsIdsUri! );
377+ await file.create (recursive: true );
378+ await file.writeAsString (
379+ _generateDeferredMapJson (
380+ component, component.mainMethod! .enclosingLibrary.importUri, moduleMap),
381+ );
385382}
386383
387- String _generateDeferredMapJson (
388- Uri rootLibraryUri,
389- Map < Library , Map < String , List < ModuleMetadata >>> moduleMap,
390- Map < String , Map < String , String >> loadIds) {
384+ String _generateDeferredMapJson (Component component, Uri rootLibraryUri,
385+ Map < Library , Map < String , List < ModuleMetadata >>> moduleMap) {
386+ final loadIdRepo =
387+ component.metadata[ LoadIdRepository ._tag] as LoadIdRepository ;
391388 final output = < String , dynamic > {};
392- moduleMap.forEach ((library, imports) {
389+ loadIdRepo.mapping.forEach ((dep, loadId) {
390+ final loadIdStr = '$loadId ' ;
391+ final prefix = dep.name! ;
392+ final library = dep.enclosingLibrary;
393+ final modules = moduleMap[library]? [prefix];
394+
395+ // Can be null if the library or import was tree-shaken by TFA.
396+ if (modules == null ) return ;
397+
393398 final libOutput =
394- output[relativizeUri (rootLibraryUri, library.importUri, false )] = {};
395- libOutput['name' ] = library.name ?? '<unnamed>' ;
396- final libImports = libOutput['imports' ] = < String , List <String >> {};
397- final libPrefixMappings =
398- libOutput['importPrefixToLoadId' ] = < String , String > {};
399- final prefixLoadIds = loadIds['${library .importUri }' ]! ;
400- imports.forEach ((prefix, modules) {
401- final loadId = prefixLoadIds[prefix]! ;
402- final prefixImports = libImports[loadId] = < String > [];
403- libPrefixMappings[prefix] = loadId;
404- for (final module in modules) {
405- prefixImports.add (module.moduleName);
406- }
407- });
399+ output[relativizeUri (rootLibraryUri, library.importUri, false )] ?? = {
400+ 'name' : library.name ?? '<unnamed>' ,
401+ 'imports' : < String , List <String >> {},
402+ 'importPrefixToLoadId' : < String , String > {},
403+ };
404+
405+ libOutput['imports' ]! [loadIdStr] = [...modules.map ((m) => m.moduleName)];
406+ libOutput['importPrefixToLoadId' ][prefix] = loadIdStr;
408407 });
409408
410409 return const JsonEncoder .withIndent (' ' ).convert (output);
@@ -415,32 +414,69 @@ class _DeferredLoadingLoadIdTransformer extends Transformer {
415414 final Procedure ? _checkLibraryIsLoaded;
416415 final Procedure _loadLibraryFromLoadId;
417416 final Procedure _checkLibraryIsLoadedFromLoadId;
418- final Map <String , Map <String , String >> loadIdCollector;
419- int loadIdCounter = 1 ;
417+ final LoadIdRepository _loadIdRepository = LoadIdRepository ();
418+ Map <String , int > _libraryLoadIds = {};
419+ int _loadIdCounter = 1 ;
420420
421- _DeferredLoadingLoadIdTransformer (CoreTypes coreTypes, this .loadIdCollector )
421+ _DeferredLoadingLoadIdTransformer (Component component, CoreTypes coreTypes )
422422 : _loadLibrary = coreTypes.index.tryGetProcedure (
423423 'dart:_internal' , LibraryIndex .topLevel, 'loadLibrary' ),
424424 _checkLibraryIsLoaded = coreTypes.index.tryGetProcedure (
425425 'dart:_internal' , LibraryIndex .topLevel, 'checkLibraryIsLoaded' ),
426426 _loadLibraryFromLoadId = coreTypes.index
427427 .getTopLevelProcedure ('dart:_internal' , 'loadLibraryFromLoadId' ),
428428 _checkLibraryIsLoadedFromLoadId = coreTypes.index.getTopLevelProcedure (
429- 'dart:_internal' , 'checkLibraryIsLoadedFromLoadId' );
429+ 'dart:_internal' , 'checkLibraryIsLoadedFromLoadId' ) {
430+ component.addMetadataRepository (_loadIdRepository);
431+ }
432+
433+ @override
434+ TreeNode visitLibrary (Library node) {
435+ // Assign a load ID to each deferred import.
436+ _libraryLoadIds = {};
437+ for (final dep in node.dependencies) {
438+ if (! dep.isDeferred) continue ;
439+ final loadId = _loadIdCounter++ ;
440+ _loadIdRepository.mapping[dep] = loadId;
441+ _libraryLoadIds[dep.name! ] = loadId;
442+ }
443+
444+ // Don't visit this library if there are no deferred imports.
445+ return _libraryLoadIds.isEmpty ? node : super .visitLibrary (node);
446+ }
430447
431448 @override
432449 TreeNode visitStaticInvocation (StaticInvocation node) {
433450 if (node.target != _loadLibrary && node.target != _checkLibraryIsLoaded) {
434451 return super .visitStaticInvocation (node);
435452 }
436- final [libraryName as StringLiteral , importPrefix as StringLiteral ] =
437- node.arguments.positional;
438- final loadId = (loadIdCollector[libraryName.value] ?? =
439- {})[importPrefix.value] ?? = '${loadIdCounter ++}' ;
453+ final [_, importPrefix as StringLiteral ] = node.arguments.positional;
454+ final loadId = '${_libraryLoadIds [importPrefix .value ]!}' ;
440455 return StaticInvocation (
441456 node.target == _loadLibrary
442457 ? _loadLibraryFromLoadId
443458 : _checkLibraryIsLoadedFromLoadId,
444459 Arguments ([StringLiteral (loadId)]));
445460 }
446461}
462+
463+ /// Contains load IDs for each deferred [LibraryDependency] in the component.
464+ class LoadIdRepository extends MetadataRepository <int > {
465+ static const String _tag = 'dart2wasm.loadIds' ;
466+
467+ @override
468+ final Map <LibraryDependency , int > mapping = {};
469+
470+ @override
471+ int readFromBinary (Node node, BinarySource source) {
472+ return source.readUInt30 ();
473+ }
474+
475+ @override
476+ String get tag => _tag;
477+
478+ @override
479+ void writeToBinary (int metadata, Node node, BinarySink sink) {
480+ sink.writeUInt30 (metadata);
481+ }
482+ }
0 commit comments