Skip to content

Commit be7ff1d

Browse files
johnniwintherCommit Bot
authored and
Commit Bot
committed
[cfe] Add MacroSerializer
This adds a [MacroSerializer] interface to abstract how URIs are created for precompiled macro components. Two strategies are added. The existing solution using a temporary directory in TempDirMacroSerializer and a new solution using the recently added (experimental) Isolate.createUriForKernelBlob feature in IsolateSerializer. Change-Id: Id7117cc518f09e9b3762d6ca924c788c81fd9ac0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/234282 Reviewed-by: Jens Johansen <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 514f678 commit be7ff1d

10 files changed

+120
-35
lines changed

pkg/front_end/lib/src/api_prototype/compiler_options.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'package:kernel/target/targets.dart' show Target;
1919
import '../base/nnbd_mode.dart';
2020

2121
import '../fasta/kernel/macro.dart';
22+
import '../macro_serializer.dart';
2223
import 'experimental_flags.dart'
2324
show
2425
AllowedExperimentalFlags,
@@ -137,7 +138,7 @@ class CompilerOptions {
137138
/// by the macro executor provided by [macroExecutorProvider].
138139
///
139140
/// This is part of the experimental macro feature.
140-
Future<Uri> Function(Component)? macroSerializer;
141+
MacroSerializer? macroSerializer;
141142

142143
/// Whether to generate code for the SDK.
143144
///
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:isolate';
6+
7+
import 'package:kernel/kernel.dart';
8+
import 'macro_serializer.dart';
9+
10+
/// [MacroSerializer] that uses blobs registered with the current [Isolate] to
11+
/// give access to precompiled macro [Component]s.
12+
///
13+
/// This can only be used with the [Isolate]-based macro executor.
14+
class IsolateMacroSerializer implements MacroSerializer {
15+
final List<Uri> _createdUris = [];
16+
17+
@override
18+
Future<void> close() {
19+
for (Uri uri in _createdUris) {
20+
(Isolate.current as dynamic).unregisterKernelBlobUri(uri);
21+
}
22+
_createdUris.clear();
23+
return new Future.value();
24+
}
25+
26+
@override
27+
Future<Uri> createUriForComponent(Component component) {
28+
Uri uri = (Isolate.current as dynamic)
29+
.createUriForKernelBlob(writeComponentToBytes(component));
30+
_createdUris.add(uri);
31+
return new Future.value(uri);
32+
}
33+
}

pkg/front_end/lib/src/kernel_generator_impl.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ Future<void> _compileMacros(NeededPrecompilations neededPrecompilations,
303303
precompilationOptions..fileSystem = new HybridFileSystem(fs);
304304
CompilerResult? compilerResult =
305305
await kernelForProgramInternal(uri, precompilationOptions);
306-
Uri precompiledUri =
307-
await options.macroSerializer!(compilerResult!.component!);
306+
Uri precompiledUri = await options.macroSerializer!
307+
.createUriForComponent(compilerResult!.component!);
308308
Map<MacroClass, Uri> precompiledMacroUris =
309309
options.precompiledMacroUris ??= {};
310310
neededPrecompilations.macroDeclarations
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:kernel/ast.dart';
6+
7+
/// Interface for supporting serialization of [Component]s for macro
8+
/// precompilation.
9+
abstract class MacroSerializer {
10+
/// Returns a [Uri] that can be accessed by the macro executor.
11+
Future<Uri> createUriForComponent(Component component);
12+
13+
/// Releases all resources of this serializer.
14+
///
15+
/// This must be called when the [Uri]s created by [createUriForComponent]
16+
/// are no longer needed.
17+
Future<void> close();
18+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'package:kernel/ast.dart';
8+
import 'package:kernel/kernel.dart';
9+
10+
import 'fasta/kernel/utils.dart';
11+
import 'macro_serializer.dart';
12+
13+
/// [MacroSerializer] that uses .dill files stored in a temporary directory to
14+
/// provided [Uri]s for precompiled macro [Component]s.
15+
///
16+
/// This can be used other with the isolate and process based macro executors.
17+
class TempDirMacroSerializer implements MacroSerializer {
18+
final String? name;
19+
Directory? tempDirectory;
20+
int precompiledCount = 0;
21+
22+
TempDirMacroSerializer([this.name]);
23+
24+
Future<Directory> _ensureDirectory() async {
25+
return tempDirectory ??= await Directory.systemTemp.createTemp(name);
26+
}
27+
28+
@override
29+
Future<Uri> createUriForComponent(Component component) async {
30+
Directory directory = await _ensureDirectory();
31+
Uri uri =
32+
directory.absolute.uri.resolve('macros${precompiledCount++}.dill');
33+
await writeComponentToFile(component, uri);
34+
return uri;
35+
}
36+
37+
@override
38+
Future<void> close() async {
39+
try {
40+
await tempDirectory?.delete(recursive: true);
41+
} catch (_) {}
42+
}
43+
}

pkg/front_end/test/macro_api_test.dart

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,26 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'dart:io' show Directory, Platform;
5+
import 'dart:io' show Platform;
66

7-
import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
87
import 'package:_fe_analyzer_shared/src/macros/executor/isolated_executor.dart'
98
as isolatedExecutor;
9+
import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
1010
import 'package:expect/expect.dart';
1111
import 'package:front_end/src/api_prototype/experimental_flags.dart';
1212
import 'package:front_end/src/api_prototype/front_end.dart';
1313
import 'package:front_end/src/compute_platform_binaries_location.dart';
1414
import 'package:front_end/src/fasta/kernel/macro.dart';
15-
import 'package:front_end/src/fasta/kernel/utils.dart';
15+
import 'package:front_end/src/isolate_macro_serializer.dart';
16+
import 'package:front_end/src/macro_serializer.dart';
1617
import 'package:front_end/src/testing/id_testing_helper.dart';
17-
import 'package:kernel/ast.dart' hide Arguments;
18-
import 'package:kernel/kernel.dart';
1918
import 'package:kernel/target/targets.dart';
2019
import 'package:vm/target/vm.dart';
2120

2221
Future<void> main(List<String> args) async {
2322
enableMacros = true;
2423

25-
Directory tempDirectory =
26-
await Directory.systemTemp.createTemp('macro_api_test');
27-
int precompiledCount = 0;
24+
MacroSerializer macroSerializer = new IsolateMacroSerializer();
2825
try {
2926
CompilerOptions options = new CompilerOptions();
3027
options.sdkRoot = computePlatformBinariesLocation();
@@ -37,12 +34,7 @@ Future<void> main(List<String> args) async {
3734
};
3835
options.precompiledMacroUris = {};
3936
options.target = options.macroTarget = new VmTarget(new TargetFlags());
40-
options.macroSerializer = (Component component) async {
41-
Uri uri = tempDirectory.absolute.uri
42-
.resolve('macros${precompiledCount++}.dill');
43-
await writeComponentToFile(component, uri);
44-
return uri;
45-
};
37+
options.macroSerializer = macroSerializer;
4638

4739
InternalCompilerResult result = await kernelForProgramInternal(
4840
Platform.script.resolve(
@@ -51,6 +43,6 @@ Future<void> main(List<String> args) async {
5143
retainDataForTesting: true) as InternalCompilerResult;
5244
Expect.isFalse(result.kernelTargetForTesting!.loader.hasSeenError);
5345
} finally {
54-
await tempDirectory.delete(recursive: true);
46+
await macroSerializer.close();
5547
}
5648
}

pkg/front_end/test/macro_application/macro_application_test.dart

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ import 'package:front_end/src/api_prototype/experimental_flags.dart';
1717
import 'package:front_end/src/fasta/builder/field_builder.dart';
1818
import 'package:front_end/src/fasta/builder/member_builder.dart';
1919
import 'package:front_end/src/fasta/kernel/macro.dart';
20-
import 'package:front_end/src/fasta/kernel/utils.dart';
2120
import 'package:front_end/src/fasta/source/source_class_builder.dart';
2221
import 'package:front_end/src/fasta/source/source_library_builder.dart';
22+
import 'package:front_end/src/macro_serializer.dart';
23+
import 'package:front_end/src/temp_dir_macro_serializer.dart';
2324
import 'package:front_end/src/testing/compiler_common.dart';
2425
import 'package:front_end/src/testing/id_extractor.dart';
2526
import 'package:front_end/src/testing/id_testing_helper.dart';
@@ -36,8 +37,8 @@ Future<void> main(List<String> args) async {
3637
bool generateExpectations = args.contains('-g');
3738
enableMacros = true;
3839

39-
Directory tempDirectory =
40-
await Directory.systemTemp.createTemp('macro_application');
40+
MacroSerializer macroSerializer =
41+
new TempDirMacroSerializer('macro_application');
4142
try {
4243
Directory dataDir =
4344
new Directory.fromUri(Platform.script.resolve('data/tests'));
@@ -46,23 +47,22 @@ Future<void> main(List<String> args) async {
4647
createUriForFileName: createUriForFileName,
4748
onFailure: onFailure,
4849
runTest: runTestFor(const MacroDataComputer(), [
49-
new MacroTestConfig(dataDir, tempDirectory,
50+
new MacroTestConfig(dataDir, macroSerializer,
5051
generateExpectations: generateExpectations)
5152
]),
5253
preserveWhitespaceInAnnotations: true);
5354
} finally {
54-
await tempDirectory.delete(recursive: true);
55+
await macroSerializer.close();
5556
}
5657
}
5758

5859
class MacroTestConfig extends TestConfig {
5960
final Directory dataDir;
60-
final Directory tempDirectory;
61+
final MacroSerializer macroSerializer;
6162
final bool generateExpectations;
62-
int precompiledCount = 0;
6363
final Map<MacroClass, Uri> precompiledMacroUris = {};
6464

65-
MacroTestConfig(this.dataDir, this.tempDirectory,
65+
MacroTestConfig(this.dataDir, this.macroSerializer,
6666
{required this.generateExpectations})
6767
: super(cfeMarker, 'cfe',
6868
explicitExperimentalFlags: {ExperimentalFlag.macros: true},
@@ -76,12 +76,7 @@ class MacroTestConfig extends TestConfig {
7676
};
7777
options.precompiledMacroUris = precompiledMacroUris;
7878
options.macroTarget = new VmTarget(new TargetFlags());
79-
options.macroSerializer = (Component component) async {
80-
Uri uri = tempDirectory.absolute.uri
81-
.resolve('macros${precompiledCount++}.dill');
82-
await writeComponentToFile(component, uri);
83-
return uri;
84-
};
79+
options.macroSerializer = macroSerializer;
8580
}
8681

8782
@override

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ bj
123123
bk
124124
blindly
125125
blob
126+
blobs
126127
blocking
127128
bmp
128129
bn
@@ -1393,6 +1394,7 @@ unparsed
13931394
unpleasant
13941395
unqualified
13951396
unreachable
1397+
unregister
13961398
unseen
13971399
unset
13981400
unshadowed

pkg/kernel/lib/kernel.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
///
1414
library kernel;
1515

16+
import 'dart:typed_data';
17+
1618
import 'ast.dart';
1719
import 'binary/ast_to_binary.dart';
1820
import 'binary/ast_from_binary.dart';
@@ -61,7 +63,7 @@ Future writeComponentToBinary(Component component, String path) {
6163
return future;
6264
}
6365

64-
List<int> writeComponentToBytes(Component component) {
66+
Uint8List writeComponentToBytes(Component component) {
6567
BytesSink sink = new BytesSink();
6668
new BinaryPrinter(sink).writeComponentFile(component);
6769
return sink.builder.toBytes();

runtime/tests/vm/dart/spawn_uri_from_kernel_blob_test.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import 'dart:io' show Platform;
1010
import 'dart:isolate' show Isolate, ReceivePort;
11-
import 'dart:typed_data' show Uint8List;
1211

1312
import "package:expect/expect.dart";
1413
import 'package:front_end/src/api_unstable/vm.dart'
@@ -33,7 +32,7 @@ main() async {
3332
};
3433
final Component component =
3534
(await kernelForProgram(sourceUri, options))!.component!;
36-
final kernelBlob = writeComponentToBytes(component) as Uint8List;
35+
final kernelBlob = writeComponentToBytes(component);
3736

3837
final kernelBlobUri =
3938
(Isolate.current as dynamic).createUriForKernelBlob(kernelBlob);

0 commit comments

Comments
 (0)