Files
sdk/pkg/kernel/bin/transform.dart
T
Aske Simon Christensen 5121a2e831 [cfe] Read product mode directly from environment in async transform.
When we perform constant evaluation in the CFE, the async transform
runs after constant evaluation. Thus, it can no longer use const
bool.fromEnvironment("dart.vm.product") to query whether the VM is
in product mode.

Instead, it can read the product mode define directly from the
environment defines given to the CFE and generate different code
depending on the value.

Change-Id: I2aabc4a84b50a940d35d5664ff4ebdf0680ed5c1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/111645
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2019-08-07 08:28:25 +00:00

138 lines
4.3 KiB
Dart
Executable File

#!/usr/bin/env dart
// Copyright (c) 2016, 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:async';
import 'dart:io';
import 'package:front_end/src/api_prototype/constant_evaluator.dart'
as constants show SimpleErrorReporter, transformComponent;
import 'package:args/args.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/src/tool/batch_util.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/transformations/continuation.dart' as cont;
import 'package:kernel/transformations/empty.dart' as empty;
import 'package:kernel/transformations/method_call.dart' as method_call;
import 'package:kernel/transformations/mixin_full_resolution.dart' as mix;
import 'package:kernel/transformations/coq.dart' as coq;
import 'package:kernel/vm/constants_native_effects.dart';
ArgParser parser = new ArgParser()
..addOption('format',
abbr: 'f',
allowed: ['text', 'bin'],
defaultsTo: 'bin',
help: 'Output format.')
..addOption('out', abbr: 'o', help: 'Output file.', defaultsTo: null)
..addFlag('verbose',
abbr: 'v',
negatable: false,
help: 'Be verbose (e.g. prints transformed main library).',
defaultsTo: false)
..addMultiOption('define', abbr: 'D', splitCommas: false)
..addOption('transformation',
abbr: 't',
help: 'The transformation to apply.',
defaultsTo: 'continuation');
main(List<String> arguments) async {
if (arguments.isNotEmpty && arguments[0] == '--batch') {
if (arguments.length != 1) {
throw '--batch cannot be used with other arguments';
}
await runBatch((arguments) => runTransformation(arguments));
} else {
CompilerOutcome outcome = await runTransformation(arguments);
exit(outcome == CompilerOutcome.Ok ? 0 : 1);
}
}
Future<CompilerOutcome> runTransformation(List<String> arguments) async {
ArgResults options = parser.parse(arguments);
if (options.rest.length != 1) {
throw 'Usage:\n${parser.usage}';
}
var input = options.rest.first;
var output = options['out'];
var format = options['format'];
var verbose = options['verbose'];
Map<String, String> defines = <String, String>{};
for (String define in options['define']) {
int index = define.indexOf('=');
String name;
String expression;
if (index != -1) {
name = define.substring(0, index);
expression = define.substring(index + 1);
} else {
name = define;
expression = define;
}
defines[name] = expression;
}
if (output == null) {
output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill';
}
var component = loadComponentFromBinary(input);
final coreTypes = new CoreTypes(component);
final hierarchy = new ClassHierarchy(component);
switch (options['transformation']) {
case 'continuation':
bool productMode = defines["dart.vm.product"] == "true";
component = cont.transformComponent(coreTypes, component,
productMode: productMode);
break;
case 'resolve-mixins':
mix.transformLibraries(
new NoneTarget(null), coreTypes, hierarchy, component.libraries);
break;
case 'coq':
component = coq.transformComponent(coreTypes, component);
break;
case 'constants':
final VmConstantsBackend backend = new VmConstantsBackend(coreTypes);
component = constants.transformComponent(
component, backend, defines, const constants.SimpleErrorReporter());
break;
case 'methodcall':
component =
method_call.transformComponent(coreTypes, hierarchy, component);
break;
case 'empty':
component = empty.transformComponent(component);
break;
default:
throw 'Unknown transformation';
}
// TODO(30631): Fix the verifier so we can check that the transform produced
// valid output.
//
// verifyComponent(component);
if (format == 'text') {
writeComponentToText(component, path: output);
} else {
assert(format == 'bin');
await writeComponentToBinary(component, output);
}
if (verbose) {
writeLibraryToText(component.mainMethod.parent as Library);
}
return CompilerOutcome.Ok;
}