blob: 8bf56e0a774348d3fdd2877dfa6b6b58a4c0b0de [file] [log] [blame]
// Copyright (c) 2017, 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.
/// Defines the VM-specific translation of Dart source code to kernel binaries.
library vm.kernel_front_end;
import 'dart:async';
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions, ErrorHandler;
import 'package:front_end/src/api_prototype/kernel_generator.dart'
show kernelForProgram;
import 'package:front_end/src/api_prototype/compilation_message.dart'
show CompilationMessage, Severity;
import 'package:front_end/src/fasta/severity.dart' show Severity;
import 'package:kernel/ast.dart' show Component, StaticGet, Field;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
import 'transformations/devirtualization.dart' as devirtualization
show transformComponent;
import 'transformations/mixin_deduplication.dart' as mixin_deduplication
show transformComponent;
import 'transformations/no_dynamic_invocations_annotator.dart'
as no_dynamic_invocations_annotator show transformComponent;
import 'transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
/// Generates a kernel representation of the program whose main library is in
/// the given [source]. Intended for whole program (non-modular) compilation.
/// VM-specific replacement of [kernelForProgram].
Future<Component> compileToKernel(Uri source, CompilerOptions options,
{bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
List<String> entryPoints,
bool genBytecode: false}) async {
// Replace error handler to detect if there are compilation errors.
final errorDetector =
new ErrorDetector(previousErrorHandler: options.onError);
options.onError = errorDetector;
final component = await kernelForProgram(source, options);
// Restore error handler (in case 'options' are reused).
options.onError = errorDetector.previousErrorHandler;
// Run global transformations only if component is correct.
if (aot && (component != null) && !errorDetector.hasCompilationErrors) {
component, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
if (genBytecode && component != null) {
generateBytecode(component, strongMode: options.strongMode);
return component;
_runGlobalTransformations(Component component, bool strongMode,
bool useGlobalTypeFlowAnalysis, List<String> entryPoints) {
if (strongMode) {
final coreTypes = new CoreTypes(component);
// TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
// mixin applications when creating mixin applications in frontend,
// so all backends (and all transformation passes from the very beginning)
// can benefit from mixin de-duplication.
// At least, in addition to VM/AOT case we should run this transformation
// when building a platform dill file for VM/JIT case.
if (useGlobalTypeFlowAnalysis) {
globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
} else {
devirtualization.transformComponent(coreTypes, component);
void _patchVmConstants(CoreTypes coreTypes) {
// Fix to be a const field equal to Endial.little instead of
// a final field. VM does not support big-endian architectures at the
// moment.
// Can't use normal patching process for this because CFE does not
// support patching fields.
// See for the background.
final Field host =
coreTypes.index.getMember('dart:typed_data', 'Endian', 'host');
host.isConst = true;
host.initializer = new StaticGet(
coreTypes.index.getMember('dart:typed_data', 'Endian', 'little'))
..parent = host;
class ErrorDetector {
final ErrorHandler previousErrorHandler;
bool hasCompilationErrors = false;
void call(CompilationMessage message) {
if (message.severity == Severity.error) {
hasCompilationErrors = true;