| #!tools/sdks/dart-sdk/bin/dart | 
 | // Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | import 'dart:io'; | 
 |  | 
 | import 'package:pool/pool.dart'; | 
 |  | 
 | final pool = Pool(Platform.numberOfProcessors); | 
 |  | 
 | void main(List<String> args) async { | 
 |   final sdkRoot = Platform.script.resolve('../').toFilePath(); | 
 |   Directory.current = Directory(sdkRoot); | 
 |  | 
 |   final extractedOffsetsFile = | 
 |       'runtime/vm/compiler/runtime_offsets_extracted.h'; | 
 |  | 
 |   final old = File(extractedOffsetsFile).readAsStringSync(); | 
 |   final header = old.substring(0, old.indexOf('\n#if ')); | 
 |   final footer = old.substring(old.lastIndexOf('\n#endif ')); | 
 |  | 
 |   // Build all configurations | 
 |   await forAllConfigurationsMode(( | 
 |     String buildDir, | 
 |     String mode, | 
 |     String arch, | 
 |   ) async { | 
 |     print('Building $buildDir'); | 
 |     await run([ | 
 |       'tools/build.py', | 
 |       ...args, | 
 |       '-a$arch', | 
 |       '-m$mode', | 
 |       '--no-rbe', | 
 |       'offsets_extractor', | 
 |       'offsets_extractor_aotruntime', | 
 |     ]); | 
 |     print('Building $buildDir - done'); | 
 |   }); | 
 |  | 
 |   final (jit, aot) = await ( | 
 |     forAllConfigurationsMode((String buildDir, _, __) async { | 
 |       return await run(['$buildDir/offsets_extractor']); | 
 |     }).then<String>((lines) => lines.join('\n')), | 
 |     forAllConfigurationsMode((String buildDir, _, __) async { | 
 |       return await run(['$buildDir/offsets_extractor_aotruntime']); | 
 |     }).then<String>((lines) => lines.join('\n')), | 
 |   ).wait; | 
 |  | 
 |   if (exitCode == 0) { | 
 |     final output = StringBuffer(); | 
 |     output.writeln(header); | 
 |     output.writeln(jit); | 
 |     output.writeln(aot); | 
 |     output.writeln(footer); | 
 |     File(extractedOffsetsFile).writeAsStringSync(output.toString()); | 
 |     print('Written $extractedOffsetsFile'); | 
 |     print('Running `git cl format $extractedOffsetsFile'); | 
 |     await run(['git', 'cl', 'format', extractedOffsetsFile]); | 
 |   } | 
 | } | 
 |  | 
 | Future<List<T>> forAllConfigurationsMode<T>( | 
 |   Future<T> Function(String buildDir, String mode, String arch) fun, | 
 | ) async { | 
 |   final archs = [ | 
 |     'simarm', | 
 |     'x64', | 
 |     'ia32', | 
 |     'simarm64', | 
 |     'x64c', | 
 |     'simarm64c', | 
 |     'simriscv32', | 
 |     'simriscv64', | 
 |   ]; | 
 |   final futures = <Future<T>>[]; | 
 |   for (final mode in ['release', 'product']) { | 
 |     for (final arch in archs) { | 
 |       final buildDir = 'out/${mode.capitalized}${arch.upper}/'; | 
 |       futures.add(pool.withResource(() => fun(buildDir, mode, arch))); | 
 |     } | 
 |   } | 
 |   return await Future.wait(futures); | 
 | } | 
 |  | 
 | Future<String> run(List<String> args) async { | 
 |   final result = await Process.run( | 
 |     args.first, | 
 |     args.skip(1).toList(), | 
 |     runInShell: true, | 
 |   ); | 
 |   if (result.exitCode != 0) { | 
 |     exitCode = result.exitCode; | 
 |     print('Running ${args.join(' ')} has failed with exit code $exitCode:'); | 
 |     print('${result.stdout}'); | 
 |     print('${result.stderr}'); | 
 |   } | 
 |   return result.stdout; | 
 | } | 
 |  | 
 | extension on String { | 
 |   String get capitalized => substring(0, 1).toUpperCase() + substring(1); | 
 |   String get upper => toUpperCase(); | 
 | } |