Skip to content

Commit 2087d6d

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
initializeFromComponent has to include platform
For initializeFromComponent to work correctly the platform has to be provided (as the other libraries provided are linked to some platform, and loading another one is thus no good). This CL changes it so we don't load another one, and checks that the component we're trying to initialize from actually contains dart:core. Change-Id: I88d30436c101c589b0555ff70ae21297ed665d7b Reviewed-on: https://dart-review.googlesource.com/c/93435 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent 7f2a83e commit 2087d6d

File tree

6 files changed

+127
-106
lines changed

6 files changed

+127
-106
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ abstract class IncrementalKernelGenerator {
2626
initializeFromDillUri);
2727
}
2828

29+
/// Initialize the incremental compiler from a component.
30+
///
31+
/// Notice that the component has to include the platform, and that no other
32+
/// platform will be loaded.
2933
factory IncrementalKernelGenerator.fromComponent(
3034
CompilerOptions options, Uri entryPoint, Component component) {
3135
return new IncrementalCompiler.fromComponent(

pkg/front_end/lib/src/fasta/incremental_compiler.dart

Lines changed: 78 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import 'package:kernel/kernel.dart'
2727
Procedure,
2828
ProcedureKind,
2929
ReturnStatement,
30-
Source,
3130
TreeNode,
3231
TypeParameter;
3332

@@ -126,56 +125,62 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
126125
ticker.logMs("Read packages file");
127126

128127
if (dillLoadedData == null) {
129-
List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
130-
int bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
131-
if (initializeFromDillUri != null) {
132-
try {
133-
bytesLength += await initializeFromDill(uriTranslator, c, data);
134-
} catch (e, st) {
135-
// We might have loaded x out of y libraries into the component.
136-
// To avoid any unforeseen problems start over.
137-
bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
138-
139-
if (e is InvalidKernelVersionError || e is PackageChangedError) {
140-
// Don't report any warning.
141-
} else {
142-
Uri gzInitializedFrom;
143-
if (c.options.writeFileOnCrashReport) {
144-
gzInitializedFrom = saveAsGzip(
145-
data.initializationBytes, "initialize_from.dill");
146-
recordTemporaryFileForTesting(gzInitializedFrom);
147-
}
148-
if (e is CanonicalNameError) {
149-
Message message = gzInitializedFrom != null
150-
? templateInitializeFromDillNotSelfContained.withArguments(
151-
initializeFromDillUri.toString(), gzInitializedFrom)
152-
: templateInitializeFromDillNotSelfContainedNoDump
153-
.withArguments(initializeFromDillUri.toString());
154-
dillLoadedData.loader
155-
.addProblem(message, TreeNode.noOffset, 1, null);
128+
int bytesLength = 0;
129+
if (componentToInitializeFrom != null) {
130+
// If initializing from a component it has to include the sdk,
131+
// so we explicitly don't load it here.
132+
initializeFromComponent(uriTranslator, c, data);
133+
} else {
134+
List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
135+
bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
136+
if (initializeFromDillUri != null) {
137+
try {
138+
bytesLength += await initializeFromDill(uriTranslator, c, data);
139+
} catch (e, st) {
140+
// We might have loaded x out of y libraries into the component.
141+
// To avoid any unforeseen problems start over.
142+
bytesLength =
143+
prepareSummary(summaryBytes, uriTranslator, c, data);
144+
145+
if (e is InvalidKernelVersionError || e is PackageChangedError) {
146+
// Don't report any warning.
156147
} else {
157-
// Unknown error: Report problem as such.
158-
Message message = gzInitializedFrom != null
159-
? templateInitializeFromDillUnknownProblem.withArguments(
160-
initializeFromDillUri.toString(),
161-
"$e",
162-
"$st",
163-
gzInitializedFrom)
164-
: templateInitializeFromDillUnknownProblemNoDump
165-
.withArguments(
166-
initializeFromDillUri.toString(), "$e", "$st");
167-
dillLoadedData.loader
168-
.addProblem(message, TreeNode.noOffset, 1, null);
148+
Uri gzInitializedFrom;
149+
if (c.options.writeFileOnCrashReport) {
150+
gzInitializedFrom = saveAsGzip(
151+
data.initializationBytes, "initialize_from.dill");
152+
recordTemporaryFileForTesting(gzInitializedFrom);
153+
}
154+
if (e is CanonicalNameError) {
155+
Message message = gzInitializedFrom != null
156+
? templateInitializeFromDillNotSelfContained
157+
.withArguments(initializeFromDillUri.toString(),
158+
gzInitializedFrom)
159+
: templateInitializeFromDillNotSelfContainedNoDump
160+
.withArguments(initializeFromDillUri.toString());
161+
dillLoadedData.loader
162+
.addProblem(message, TreeNode.noOffset, 1, null);
163+
} else {
164+
// Unknown error: Report problem as such.
165+
Message message = gzInitializedFrom != null
166+
? templateInitializeFromDillUnknownProblem.withArguments(
167+
initializeFromDillUri.toString(),
168+
"$e",
169+
"$st",
170+
gzInitializedFrom)
171+
: templateInitializeFromDillUnknownProblemNoDump
172+
.withArguments(
173+
initializeFromDillUri.toString(), "$e", "$st");
174+
dillLoadedData.loader
175+
.addProblem(message, TreeNode.noOffset, 1, null);
176+
}
169177
}
170178
}
171179
}
172-
} else if (componentToInitializeFrom != null) {
173-
initializeFromComponent(uriTranslator, c, data);
174180
}
175181
appendLibraries(data, bytesLength);
176182

177183
await dillLoadedData.buildOutlines();
178-
summaryBytes = null;
179184
userBuilders = <Uri, LibraryBuilder>{};
180185
platformBuilders = <LibraryBuilder>[];
181186
dillLoadedData.loader.builders.forEach((uri, builder) {
@@ -522,35 +527,32 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
522527
// This procedure will set up compiler from [componentToInitializeFrom].
523528
void initializeFromComponent(UriTranslator uriTranslator, CompilerContext c,
524529
IncrementalCompilerData data) {
525-
ticker.logMs("Read initializeFromComponent");
526-
527-
// [libraries] and [uriToSource] from [componentToInitializeFrom] take
528-
// precedence over what was already read into [data.component]. Assumption
529-
// is that [data.component] is initialized with standard prebuilt various
530-
// platform libraries.
531-
List<Library> combinedLibs = <Library>[];
532-
Set<Uri> readLibs =
533-
componentToInitializeFrom.libraries.map((lib) => lib.fileUri).toSet();
534-
combinedLibs.addAll(componentToInitializeFrom.libraries);
535-
for (Library lib in data.component.libraries) {
536-
if (!readLibs.contains(lib.fileUri)) {
537-
combinedLibs.add(lib);
530+
ticker.logMs("About to initializeFromComponent");
531+
532+
dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
533+
data.component = new Component(
534+
libraries: componentToInitializeFrom.libraries,
535+
uriToSource: componentToInitializeFrom.uriToSource)
536+
..mainMethod = componentToInitializeFrom.mainMethod;
537+
data.userLoadedUriMain = componentToInitializeFrom.mainMethod;
538+
saveComponentProblems(data);
539+
540+
bool foundDartCore = false;
541+
for (int i = 0; i < data.component.libraries.length; i++) {
542+
Library library = data.component.libraries[i];
543+
if (library.importUri.scheme == "dart" &&
544+
library.importUri.path == "core") {
545+
foundDartCore = true;
546+
break;
538547
}
539548
}
540-
Map<Uri, Source> combinedMaps = new Map<Uri, Source>();
541-
combinedMaps.addAll(componentToInitializeFrom.uriToSource);
542-
Set<Uri> uris = combinedMaps.keys.toSet();
543-
for (MapEntry<Uri, Source> entry in data.component.uriToSource.entries) {
544-
if (!uris.contains(entry.key)) {
545-
combinedMaps[entry.key] = entry.value;
546-
}
549+
550+
if (!foundDartCore) {
551+
throw const InitializeFromComponentError("Did not find dart:core when "
552+
"tried to initialize from component.");
547553
}
548554

549-
data.component =
550-
new Component(libraries: combinedLibs, uriToSource: combinedMaps)
551-
..mainMethod = componentToInitializeFrom.mainMethod;
552-
data.userLoadedUriMain = data.component.mainMethod;
553-
saveComponentProblems(data);
555+
ticker.logMs("Ran initializeFromComponent");
554556
}
555557

556558
void appendLibraries(IncrementalCompilerData data, int bytesLength) {
@@ -798,6 +800,14 @@ class PackageChangedError {
798800
const PackageChangedError();
799801
}
800802

803+
class InitializeFromComponentError {
804+
final String message;
805+
806+
const InitializeFromComponentError(this.message);
807+
808+
String toString() => message;
809+
}
810+
801811
class IncrementalCompilerData {
802812
Procedure userLoadedUriMain = null;
803813
Component component = null;

pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
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.md file.
44

5-
# Initialize from component, where the component is linked to one sdk, and where
6-
# the incremental compiler loads another sdk. Risk when doing this: Having two
7-
# definitions of the same thing (e.g. the class 'String'), which could lead to
8-
# errors such as "The argument type 'dart.core::String' can't be assigned to
5+
# Initialize from component, where the component is linked to a sdk, and where
6+
# the incremental compiler (could) load another sdk.
7+
# Risk when doing this: Having two definitions of the same thing
8+
# (e.g. the class 'String'), which could lead to errors such as
9+
# "The argument type 'dart.core::String' can't be assigned to
910
# the parameter type 'dart.core::String'".
1011

1112
type: newworld
1213
strong: true
14+
omitPlatform: false
1315
worlds:
1416
- entry: main.dart
1517
errors: false
@@ -28,9 +30,11 @@ worlds:
2830
print("Hello from useString: $s");
2931
}
3032
expectedLibraryCount: 2
33+
expectsPlatform: true
3134
- entry: main.dart
3235
errors: false
3336
warnings: false
37+
expectInitializeFromDill: false
3438
fromComponent: true
3539
invalidate:
3640
- main.dart
@@ -47,4 +51,5 @@ worlds:
4751
void useString(String s) {
4852
print("Hello from useString: $s");
4953
}
50-
expectedLibraryCount: 2
54+
expectedLibraryCount: 2
55+
expectsPlatform: true

pkg/front_end/testcases/incremental_initialize_from_dill/status.status

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@
33
# BSD-style license that can be found in the LICENSE.md file.
44

55
# Status file for the test suite ../test/incremental_load_from_dill_yaml_test.dart.
6-
7-
load_from_component_explicitly_import_dart_core: Crash

pkg/vm/lib/frontend_server.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ class FrontendCompiler implements CompilerInterface {
333333
Component component;
334334
if (options['incremental']) {
335335
_compilerOptions = compilerOptions;
336-
_compilerOptions.omitPlatform = true;
336+
_compilerOptions.omitPlatform = false;
337337
_generator =
338338
generator ?? _createGenerator(new Uri.file(_initializeFromDill));
339339
await invalidateIfInitializingFromDill();

pkg/vm/lib/incremental_compiler.dart

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ const String kDebugProcedureName = ":Eval";
1717
class IncrementalCompiler {
1818
IncrementalKernelGenerator _generator;
1919

20-
// Component that reflect current state of the compiler, which has not
21-
// been yet accepted by the client. Is [null] if no compilation was done
22-
// since last accept/reject acknowledgement by the client.
23-
Component _candidate;
2420
// Component that reflect the state that was most recently accepted by the
2521
// client. Is [null], if no compilation results were accepted by the client.
2622
Component _lastKnownGood;
@@ -51,62 +47,70 @@ class IncrementalCompiler {
5147
entryPoint: entryPoint, fullComponent: fullComponent);
5248
initialized = true;
5349
fullComponent = false;
54-
final bool firstDelta = _pendingDeltas.isEmpty;
5550
_pendingDeltas.add(component);
56-
if (!firstDelta) {
57-
// If more than one delta is pending, we need to combine them.
58-
Procedure mainMethod;
59-
Map<Uri, Library> combined = <Uri, Library>{};
60-
for (Component delta in _pendingDeltas) {
61-
if (delta.mainMethod != null) {
62-
mainMethod = delta.mainMethod;
63-
}
64-
for (Library library in delta.libraries) {
65-
combined[library.importUri] = library;
66-
}
51+
return _combinePendingDeltas(false);
52+
}
53+
54+
_combinePendingDeltas(bool includePlatform) {
55+
Procedure mainMethod;
56+
Map<Uri, Library> combined = <Uri, Library>{};
57+
Map<Uri, Source> uriToSource = new Map<Uri, Source>();
58+
for (Component delta in _pendingDeltas) {
59+
if (delta.mainMethod != null) {
60+
mainMethod = delta.mainMethod;
61+
}
62+
uriToSource.addAll(delta.uriToSource);
63+
for (Library library in delta.libraries) {
64+
bool isPlatform =
65+
library.importUri.scheme == "dart" && !library.isSynthetic;
66+
if (!includePlatform && isPlatform) continue;
67+
combined[library.importUri] = library;
6768
}
68-
// TODO(vegorov) this needs to merge metadata repositories from deltas.
69-
component = new Component(libraries: combined.values.toList())
70-
..mainMethod = mainMethod;
7169
}
72-
_candidate = component;
73-
return component;
70+
71+
// TODO(vegorov) this needs to merge metadata repositories from deltas.
72+
return new Component(
73+
libraries: combined.values.toList(), uriToSource: uriToSource)
74+
..mainMethod = mainMethod;
7475
}
7576

7677
/// This lets incremental compiler know that results of last [compile] call
7778
/// were accepted, don't need to be included into subsequent [compile] calls
7879
/// results.
7980
accept() {
80-
_pendingDeltas.clear();
81-
8281
Map<Uri, Library> combined = <Uri, Library>{};
82+
Map<Uri, Source> uriToSource = <Uri, Source>{};
83+
8384
if (_lastKnownGood != null) {
8485
// TODO(aam): Figure out how to skip no-longer-used libraries from
8586
// [_lastKnownGood] libraries.
8687
for (Library library in _lastKnownGood.libraries) {
8788
combined[library.importUri] = library;
8889
}
90+
uriToSource.addAll(_lastKnownGood.uriToSource);
8991
}
90-
for (Library library in _candidate.libraries) {
92+
93+
Component candidate = _combinePendingDeltas(true);
94+
for (Library library in candidate.libraries) {
9195
combined[library.importUri] = library;
9296
}
97+
uriToSource.addAll(candidate.uriToSource);
98+
9399
_lastKnownGood = new Component(
94100
libraries: combined.values.toList(),
95-
uriToSource: _candidate.uriToSource,
96-
)..mainMethod = _candidate.mainMethod;
97-
for (final repo in _candidate.metadata.values) {
101+
uriToSource: uriToSource,
102+
)..mainMethod = candidate.mainMethod;
103+
for (final repo in candidate.metadata.values) {
98104
_lastKnownGood.addMetadataRepository(repo);
99105
}
100-
101-
_candidate = null;
106+
_pendingDeltas.clear();
102107
}
103108

104109
/// This lets incremental compiler know that results of last [compile] call
105110
/// were rejected. Subsequent [compile] or [compileExpression] calls need to
106111
/// be processed without changes picked up by rejected [compile] call.
107112
reject() async {
108113
_pendingDeltas.clear();
109-
_candidate = null;
110114
// Need to reset and warm up compiler so that expression evaluation requests
111115
// are processed in that known good state.
112116
_generator = new IncrementalKernelGenerator.fromComponent(

0 commit comments

Comments
 (0)