Skip to content

[tool] Guard process writes to frontend server in ResidentCompiler #152358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
init
  • Loading branch information
andrewkolos committed Jul 31, 2024
commit d114fd3f890781cf52b912c1a80bbc65c3c0326d
118 changes: 68 additions & 50 deletions packages/flutter_tools/lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/platform.dart';
import 'base/process.dart';
import 'build_info.dart';
import 'convert.dart';

Expand Down Expand Up @@ -589,7 +590,7 @@ abstract class ResidentCompiler {
/// Should be invoked when results of compilation are accepted by the client.
///
/// Either [accept] or [reject] should be called after every [recompile] call.
void accept();
Future<void> accept();

/// Should be invoked when results of compilation are rejected by the client.
///
Expand All @@ -599,7 +600,7 @@ abstract class ResidentCompiler {
/// Should be invoked when frontend server compiler should forget what was
/// accepted previously so that next call to [recompile] produces complete
/// kernel file.
void reset();
Future<void> reset();

Future<Object> shutdown();
}
Expand Down Expand Up @@ -742,11 +743,9 @@ class DefaultResidentCompiler implements ResidentCompiler {
final String inputKey = Uuid().generateV4();

if (nativeAssets != null && nativeAssets.isNotEmpty) {
server.stdin.writeln('native-assets $nativeAssets');
_logger.printTrace('<- native-assets $nativeAssets');
await _writelnToServerStdin('native-assets $nativeAssets', printTrace: true);
}
server.stdin.writeln('recompile $mainUri $inputKey');
_logger.printTrace('<- recompile $mainUri $inputKey');
await _writelnToServerStdin('recompile $mainUri $inputKey', printTrace: true);
final List<Uri>? invalidatedFiles = request.invalidatedFiles;
if (invalidatedFiles != null) {
for (final Uri fileUri in invalidatedFiles) {
Expand All @@ -761,8 +760,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
_logger.printTrace(message);
}
}
server.stdin.writeln(inputKey);
_logger.printTrace('<- $inputKey');
await _writelnToServerStdin(inputKey, printTrace: true);

return _stdoutHandler.compilerOutput?.future;
}
Expand Down Expand Up @@ -899,12 +897,10 @@ class DefaultResidentCompiler implements ResidentCompiler {
}));

if (nativeAssetsUri != null && nativeAssetsUri.isNotEmpty) {
_server?.stdin.writeln('native-assets $nativeAssetsUri');
_logger.printTrace('<- native-assets $nativeAssetsUri');
await _writelnToServerStdin('native assets $nativeAssetsUri', printTrace: true);
}

_server?.stdin.writeln('compile $scriptUri');
_logger.printTrace('<- compile $scriptUri');
await _writelnToServerStdin('compile $scriptUri', printTrace: true);

return _stdoutHandler.compilerOutput?.future;
}
Expand Down Expand Up @@ -945,24 +941,24 @@ class DefaultResidentCompiler implements ResidentCompiler {
}

final String inputKey = Uuid().generateV4();
server.stdin
..writeln('compile-expression $inputKey')
..writeln(request.expression);
request.definitions?.forEach(server.stdin.writeln);
server.stdin.writeln(inputKey);
request.definitionTypes?.forEach(server.stdin.writeln);
server.stdin.writeln(inputKey);
request.typeDefinitions?.forEach(server.stdin.writeln);
server.stdin.writeln(inputKey);
request.typeBounds?.forEach(server.stdin.writeln);
server.stdin.writeln(inputKey);
request.typeDefaults?.forEach(server.stdin.writeln);
server.stdin
..writeln(inputKey)
..writeln(request.libraryUri ?? '')
..writeln(request.klass ?? '')
..writeln(request.method ?? '')
..writeln(request.isStatic);
await _writelnToServerStdinAll(<String>[
'compile-expression $inputKey',
request.expression,
...?request.definitions,
inputKey,
...?request.definitionTypes,
inputKey,
...?request.typeDefinitions,
inputKey,
...?request.typeBounds,
inputKey,
...?request.typeDefaults,
inputKey,
request.libraryUri ?? '',
request.klass ?? '',
request.method ?? '',
request.isStatic.toString(),
]);

return _stdoutHandler.compilerOutput?.future;
}
Expand Down Expand Up @@ -1000,27 +996,28 @@ class DefaultResidentCompiler implements ResidentCompiler {
}

final String inputKey = Uuid().generateV4();
server.stdin
..writeln('compile-expression-to-js $inputKey')
..writeln(request.libraryUri ?? '')
..writeln(request.line)
..writeln(request.column);
request.jsModules?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
server.stdin.writeln(inputKey);
request.jsFrameValues?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
server.stdin
..writeln(inputKey)
..writeln(request.moduleName ?? '')
..writeln(request.expression ?? '');
await _writelnToServerStdinAll(<String>[
'compile-expression-to-js $inputKey',
request.libraryUri ?? '',
request.line.toString(),
request.column.toString(),
for (final MapEntry<String, String> entry in request.jsModules?.entries ?? <MapEntry<String, String>>[])
'${entry.key}:${entry.value}',
inputKey,
for (final MapEntry<String, String> entry in request.jsFrameValues?.entries ?? <MapEntry<String, String>>[])
'${entry.key}:${entry.value}',
inputKey,
request.moduleName ?? '',
request.expression ?? ''
]);

return _stdoutHandler.compilerOutput?.future;
}

@override
void accept() {
Future<void> accept() async {
if (_compileRequestNeedsConfirmation) {
_server?.stdin.writeln('accept');
_logger.printTrace('<- accept');
await _writelnToServerStdin('accept', printTrace: true);
}
_compileRequestNeedsConfirmation = false;
}
Expand All @@ -1041,16 +1038,14 @@ class DefaultResidentCompiler implements ResidentCompiler {
return Future<CompilerOutput?>.value();
}
_stdoutHandler.reset(expectSources: false);
_server?.stdin.writeln('reject');
_logger.printTrace('<- reject');
await _writelnToServerStdin('reject', printTrace: true);
_compileRequestNeedsConfirmation = false;
return _stdoutHandler.compilerOutput?.future;
}

@override
void reset() {
_server?.stdin.writeln('reset');
_logger.printTrace('<- reset');
Future<void> reset() async {
await _writelnToServerStdin('reset', printTrace: true);
}

@override
Expand All @@ -1064,6 +1059,29 @@ class DefaultResidentCompiler implements ResidentCompiler {
server.kill();
return server.exitCode;
}

Future<void> _writelnToServerStdin(String line, {
bool printTrace = false,
}) async {
final Process? server = _server;
if (server == null) {
return;
}
await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line);
if (printTrace) {
_logger.printTrace('<- $line');
}
}

Future<void> _writelnToServerStdinAll(List<String>? lines) async {
final Process? server = _server;
if (server == null) {
return;
}
for (final String line in lines ?? <String>[]) {
await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line);
}
}
}

/// Convert a file URI into a multi-root scheme URI if provided, otherwise
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/lib/src/devfs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ class DevFS {
bool assetBuildFailed = false;
int syncedBytes = 0;
if (fullRestart) {
generator.reset();
await generator.reset();
}
// On a full restart, or on an initial compile for the attach based workflow,
// this will produce a full dill. Subsequent invocations will produce incremental
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/lib/src/isolated/devfs_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ class WebDevFS implements DevFS {
await _validateTemplateFile('flutter_bootstrap.js');
final DateTime candidateCompileTime = DateTime.now();
if (fullRestart) {
generator.reset();
await generator.reset();
}

// The tool generates an entrypoint file in a temp directory to handle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
appFailedToStart();
return 1;
}
device!.generator!.accept();
await device!.generator!.accept();
cacheInitialDillCompilation();
} else {
final WebBuilder webBuilder = WebBuilder(
Expand Down Expand Up @@ -418,7 +418,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
// Full restart is always false for web, since the extra recompile is wasteful.
final UpdateFSReport report = await _updateDevFS();
if (report.success) {
device!.generator!.accept();
await device!.generator!.accept();
} else {
status.stop();
await device!.generator!.reject();
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/lib/src/resident_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ class FlutterDevice {

Future<void> updateReloadStatus(bool wasReloadSuccessful) async {
if (wasReloadSuccessful) {
generator?.accept();
await generator?.accept();
} else {
await generator?.reject();
}
Expand Down
4 changes: 2 additions & 2 deletions packages/flutter_tools/lib/src/run_hot.dart
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class HotRunner extends ResidentRunner {
// VM must have accepted the kernel binary, there will be no reload
// report, so we let incremental compiler know that source code was accepted.
if (device!.generator != null) {
device.generator!.accept();
await device.generator!.accept();
}
final List<FlutterView> views = await device.vmService!.getFlutterViews();
for (final FlutterView view in views) {
Expand Down Expand Up @@ -626,7 +626,7 @@ class HotRunner extends ResidentRunner {
// VM must have accepted the kernel binary, there will be no reload
// report, so we let incremental compiler know that source code was accepted.
if (device!.generator != null) {
device.generator!.accept();
await device.generator!.accept();
}
}
// Check if the isolate is paused and resume it.
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/lib/src/test/runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ class SpawnPlugin extends PlatformPlugin {
fs: globals.fs,
nativeAssetsYaml: nativeAssetsYaml,
);
residentCompiler.accept();
await residentCompiler.accept();

globals.printTrace('Compiling ${sourceFile.absolute.uri} took ${compilerTime.elapsedMilliseconds}ms');
testTimeRecorder?.stop(TestTimePhases.Compile, testTimeRecorderStopwatch!);
Expand Down
4 changes: 2 additions & 2 deletions packages/flutter_tools/lib/src/test/test_compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ class TestCompiler {
} else {
request.result.complete(outputPath);
}
compiler!.accept();
compiler!.reset();
await compiler!.accept();
await compiler!.reset();
}
globals.printTrace('Compiling ${request.mainUri} took ${compilerTime.elapsedMilliseconds}ms');
testTimeRecorder?.stop(TestTimePhases.Compile, testTimeRecorderStopwatch!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ Future<void> _accept(
MemoryIOSink frontendServerStdIn,
String expected,
) async {
generator.accept();
await generator.accept();
final String commands = frontendServerStdIn.getAndClear();
final RegExp re = RegExp(expected);
expect(commands, matches(re));
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/test/general.shard/hot_shared.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class TestHotRunnerConfig extends HotRunnerConfig {

class FakeResidentCompiler extends Fake implements ResidentCompiler {
@override
void accept() {}
Future<void> accept() async {}
}

class FakeFlutterVmService extends Fake implements FlutterVmService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler {
}

@override
void accept() { }
Future<void> accept() async {}

@override
void reset() { }
Future<void> reset() async {}
}

class FakeProjectFileInvalidator extends Fake implements ProjectFileInvalidator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1508,10 +1508,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler {
}

@override
void accept() {}
Future<void> accept() async {}

@override
void reset() {}
Future<void> reset() async {}

@override
Future<CompilerOutput> reject() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler {
}

@override
void accept() { }
Future<void> accept() async {}

@override
void reset() { }
Future<void> reset() async {}

@override
Future<Object> shutdown() async {
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy