mirror of
https://github.com/dart-lang/sdk
synced 2024-09-20 02:39:27 +00:00
Support deserialized compilation of the empty program.
R=sigmund@google.com Review URL: https://codereview.chromium.org/1892093003 .
This commit is contained in:
parent
ea4a562517
commit
2ccfcf438a
|
@ -131,7 +131,7 @@ class ClosureFieldElement extends ElementX
|
|||
bool get hasResolvedAst => hasTreeElements;
|
||||
|
||||
ResolvedAst get resolvedAst {
|
||||
return new ParsedResolvedAst(this, null, treeElements);
|
||||
return new ParsedResolvedAst(this, null, null, treeElements);
|
||||
}
|
||||
|
||||
Expression get initializer {
|
||||
|
@ -346,7 +346,7 @@ class SynthesizedCallMethodElementX extends BaseFunctionElementX
|
|||
FunctionExpression parseNode(ParsingContext parsing) => node;
|
||||
|
||||
ResolvedAst get resolvedAst {
|
||||
return new ParsedResolvedAst(this, node, treeElements);
|
||||
return new ParsedResolvedAst(this, node, node.body, treeElements);
|
||||
}
|
||||
|
||||
Element get analyzableElement => closureClass.methodElement.analyzableElement;
|
||||
|
@ -379,6 +379,29 @@ class ClosureScope {
|
|||
f(LocalVariableElement variable, BoxFieldElement boxField)) {
|
||||
capturedVariables.forEach(f);
|
||||
}
|
||||
|
||||
String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (boxElement != null) {
|
||||
sb.write('box=$boxElement');
|
||||
}
|
||||
if (boxedLoopVariables.isNotEmpty) {
|
||||
if (sb.isNotEmpty) {
|
||||
sb.write(',');
|
||||
}
|
||||
sb.write('boxedLoopVariables=${boxedLoopVariables}');
|
||||
}
|
||||
if (capturedVariables.isNotEmpty) {
|
||||
if (sb.isNotEmpty) {
|
||||
sb.write(',');
|
||||
}
|
||||
sb.write('capturedVariables=');
|
||||
capturedVariables.forEach((Local local, BoxFieldElement field) {
|
||||
sb.write('$local->${field} ');
|
||||
});
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class ClosureClassMap {
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'dart:async' show Future;
|
|||
|
||||
import '../common.dart';
|
||||
import '../common/codegen.dart' show CodegenImpact;
|
||||
import '../common/resolution.dart' show ResolutionImpact;
|
||||
import '../common/resolution.dart' show ResolutionImpact, Frontend;
|
||||
import '../compile_time_constants.dart'
|
||||
show BackendConstantEnvironment, ConstantCompilerTask;
|
||||
import '../compiler.dart' show Compiler;
|
||||
|
@ -393,6 +393,9 @@ abstract class Backend {
|
|||
bool supportSerialization: true}) {
|
||||
return const ImpactStrategy();
|
||||
}
|
||||
|
||||
/// Backend access to the front-end.
|
||||
Frontend get frontend => compiler.resolution;
|
||||
}
|
||||
|
||||
/// Interface for resolving calls to foreign functions.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
library dart2js.common.codegen;
|
||||
|
||||
import '../closure.dart' show SynthesizedCallMethodElementX;
|
||||
import '../common.dart';
|
||||
import '../compiler.dart' show Compiler;
|
||||
import '../constants/values.dart' show ConstantValue;
|
||||
|
@ -225,6 +226,7 @@ class CodegenRegistry extends Registry {
|
|||
/// [WorkItem] used exclusively by the [CodegenEnqueuer].
|
||||
class CodegenWorkItem extends WorkItem {
|
||||
CodegenRegistry registry;
|
||||
final ResolvedAst resolvedAst;
|
||||
|
||||
factory CodegenWorkItem(Compiler compiler, AstElement element,
|
||||
ItemCompilationContext compilationContext) {
|
||||
|
@ -235,16 +237,14 @@ class CodegenWorkItem extends WorkItem {
|
|||
assert(invariant(
|
||||
element, compiler.enqueuer.resolution.hasBeenProcessed(element),
|
||||
message: "$element has not been resolved."));
|
||||
assert(invariant(element, element.hasResolvedAst,
|
||||
message: 'Resolution tree is null for $element in codegen work item'));
|
||||
return new CodegenWorkItem.internal(element, compilationContext);
|
||||
ResolvedAst resolvedAst = compiler.backend.frontend.getResolvedAst(element);
|
||||
return new CodegenWorkItem.internal(resolvedAst, compilationContext);
|
||||
}
|
||||
|
||||
CodegenWorkItem.internal(
|
||||
AstElement element, ItemCompilationContext compilationContext)
|
||||
: super(element, compilationContext);
|
||||
|
||||
ResolvedAst get resolvedAst => element.resolvedAst;
|
||||
ResolvedAst resolvedAst, ItemCompilationContext compilationContext)
|
||||
: this.resolvedAst = resolvedAst,
|
||||
super(resolvedAst.element, compilationContext);
|
||||
|
||||
WorldImpact run(Compiler compiler, CodegenEnqueuer world) {
|
||||
if (world.isProcessed(element)) return const WorldImpact();
|
||||
|
|
|
@ -185,8 +185,18 @@ class ListLiteralUse {
|
|||
}
|
||||
}
|
||||
|
||||
/// Interface for the accessing the front-end analysis.
|
||||
// TODO(johnniwinther): Find a better name for this.
|
||||
abstract class Frontend {
|
||||
/// Returns the `ResolvedAst` for the [element].
|
||||
ResolvedAst getResolvedAst(Element element);
|
||||
|
||||
/// Returns the [ResolutionImpact] for [element].
|
||||
ResolutionImpact getResolutionImpact(Element element);
|
||||
}
|
||||
|
||||
// TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
|
||||
abstract class Resolution {
|
||||
abstract class Resolution implements Frontend {
|
||||
ParsingContext get parsingContext;
|
||||
DiagnosticReporter get reporter;
|
||||
CoreTypes get coreTypes;
|
||||
|
|
|
@ -1850,6 +1850,9 @@ class _CompilerResolution implements Resolution {
|
|||
bool hasResolvedAst(Element element) {
|
||||
assert(invariant(element, element.isDeclaration,
|
||||
message: "Element $element must be the declaration."));
|
||||
if (compiler.serialization.isDeserialized(element)) {
|
||||
return compiler.serialization.hasResolvedAst(element);
|
||||
}
|
||||
return element is AstElement &&
|
||||
hasBeenResolved(element) &&
|
||||
element.hasResolvedAst;
|
||||
|
@ -1860,6 +1863,9 @@ class _CompilerResolution implements Resolution {
|
|||
assert(invariant(element, element.isDeclaration,
|
||||
message: "Element $element must be the declaration."));
|
||||
if (hasResolvedAst(element)) {
|
||||
if (compiler.serialization.isDeserialized(element)) {
|
||||
return compiler.serialization.getResolvedAst(element);
|
||||
}
|
||||
AstElement astElement = element;
|
||||
return astElement.resolvedAst;
|
||||
}
|
||||
|
|
|
@ -1199,9 +1199,12 @@ class AsyncMarker {
|
|||
/// Canonical list of marker values.
|
||||
///
|
||||
/// Added to make [AsyncMarker] enum-like.
|
||||
static const List<AsyncMarker> values =
|
||||
const <AsyncMarker>[SYNC, SYNC_STAR, ASYNC, ASYNC_STAR];
|
||||
|
||||
static const List<AsyncMarker> values = const <AsyncMarker>[
|
||||
SYNC,
|
||||
SYNC_STAR,
|
||||
ASYNC,
|
||||
ASYNC_STAR
|
||||
];
|
||||
|
||||
/// Index to this marker within [values].
|
||||
///
|
||||
|
@ -1660,10 +1663,19 @@ abstract class ResolvedAst {
|
|||
/// The kind of semantics definition used for this object.
|
||||
ResolvedAstKind get kind;
|
||||
|
||||
/// The AST node for [element]. This only available of [kind] is
|
||||
/// `ResolvedAstKind.PARSED`.
|
||||
/// The root AST node for the declaration of [element]. This only available if
|
||||
/// [kind] is `ResolvedAstKind.PARSED`.
|
||||
Node get node;
|
||||
|
||||
/// The AST node for the 'body' of [element].
|
||||
///
|
||||
/// For functions and constructors this is the root AST node of the method
|
||||
/// body, and for variables this is the root AST node of the initializer, if
|
||||
/// available.
|
||||
///
|
||||
/// This only available if [kind] is `ResolvedAstKind.PARSED`.
|
||||
Node get body;
|
||||
|
||||
/// The [TreeElements] containing the resolution data for [node]. This only
|
||||
/// available of [kind] is `ResolvedAstKind.PARSED`.
|
||||
TreeElements get elements;
|
||||
|
@ -1674,9 +1686,10 @@ abstract class ResolvedAst {
|
|||
class ParsedResolvedAst implements ResolvedAst {
|
||||
final Element element;
|
||||
final Node node;
|
||||
final Node body;
|
||||
final TreeElements elements;
|
||||
|
||||
ParsedResolvedAst(this.element, this.node, this.elements);
|
||||
ParsedResolvedAst(this.element, this.node, this.body, this.elements);
|
||||
|
||||
ResolvedAstKind get kind => ResolvedAstKind.PARSED;
|
||||
|
||||
|
@ -1698,7 +1711,12 @@ class SynthesizedResolvedAst implements ResolvedAst {
|
|||
|
||||
@override
|
||||
Node get node {
|
||||
throw new UnsupportedError('$this does not have an AST');
|
||||
throw new UnsupportedError('$this does not have a root AST node');
|
||||
}
|
||||
|
||||
@override
|
||||
Node get body {
|
||||
throw new UnsupportedError('$this does not have a body AST node');
|
||||
}
|
||||
|
||||
String toString() => '$kind:$element';
|
||||
|
|
|
@ -3269,7 +3269,15 @@ abstract class AstElementMixin implements AstElement {
|
|||
}
|
||||
|
||||
ResolvedAst get resolvedAst {
|
||||
Node node = definingElement.node;
|
||||
Node body;
|
||||
if (definingElement.isField) {
|
||||
FieldElement field = definingElement;
|
||||
body = field.initializer;
|
||||
} else if (node != null && node.asFunctionExpression() != null) {
|
||||
body = node.asFunctionExpression().body;
|
||||
}
|
||||
return new ParsedResolvedAst(
|
||||
declaration, definingElement.node, definingElement.treeElements);
|
||||
declaration, node, body, definingElement.treeElements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -511,6 +511,8 @@ class JavaScriptBackend extends Backend {
|
|||
final BackendHelpers helpers;
|
||||
final BackendImpacts impacts;
|
||||
|
||||
final JSFrontendAccess frontend;
|
||||
|
||||
JavaScriptBackend(Compiler compiler,
|
||||
{bool generateSourceMap: true,
|
||||
bool useStartupEmitter: false,
|
||||
|
@ -529,6 +531,7 @@ class JavaScriptBackend extends Backend {
|
|||
: const JavaScriptSourceInformationStrategy(),
|
||||
helpers = new BackendHelpers(compiler),
|
||||
impacts = new BackendImpacts(compiler),
|
||||
frontend = new JSFrontendAccess(compiler),
|
||||
super(compiler) {
|
||||
emitter = new CodeEmitterTask(
|
||||
compiler, namer, generateSourceMap, useStartupEmitter);
|
||||
|
@ -2475,6 +2478,32 @@ class JavaScriptBackend extends Backend {
|
|||
}
|
||||
}
|
||||
|
||||
class JSFrontendAccess implements Frontend {
|
||||
final Compiler compiler;
|
||||
|
||||
JSFrontendAccess(this.compiler);
|
||||
|
||||
Resolution get resolution => compiler.resolution;
|
||||
|
||||
@override
|
||||
ResolutionImpact getResolutionImpact(Element element) {
|
||||
return resolution.getResolutionImpact(element);
|
||||
}
|
||||
|
||||
@override
|
||||
ResolvedAst getResolvedAst(Element element) {
|
||||
if (element is SynthesizedCallMethodElementX) {
|
||||
return element.resolvedAst;
|
||||
} else if (element is ConstructorBodyElementX) {
|
||||
return element.resolvedAst;
|
||||
} else {
|
||||
assert(invariant(element, resolution.hasResolvedAst(element.declaration),
|
||||
message: 'No ResolvedAst for $element'));
|
||||
return resolution.getResolvedAst(element.declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handling of special annotations for tests.
|
||||
class Annotations {
|
||||
static final Uri PACKAGE_EXPECT =
|
||||
|
|
|
@ -18,7 +18,13 @@ import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem;
|
|||
import '../common/names.dart' show Identifiers, Names, Selectors, Uris;
|
||||
import '../common/registry.dart' show EagerRegistry, Registry;
|
||||
import '../common/resolution.dart'
|
||||
show Feature, ListLiteralUse, MapLiteralUse, Resolution, ResolutionImpact;
|
||||
show
|
||||
Feature,
|
||||
Frontend,
|
||||
ListLiteralUse,
|
||||
MapLiteralUse,
|
||||
Resolution,
|
||||
ResolutionImpact;
|
||||
import '../common/tasks.dart' show CompilerTask;
|
||||
import '../common/work.dart' show ItemCompilationContext;
|
||||
import '../compile_time_constants.dart';
|
||||
|
@ -32,6 +38,7 @@ import '../deferred_load.dart' show DeferredLoadTask;
|
|||
import '../diagnostics/invariant.dart' show DEBUG_MODE;
|
||||
import '../dump_info.dart' show DumpInfoTask;
|
||||
import '../elements/elements.dart';
|
||||
import '../elements/modelx.dart' show ConstructorBodyElementX;
|
||||
import '../elements/visitor.dart' show BaseElementVisitor;
|
||||
import '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
|
||||
import '../io/code_output.dart';
|
||||
|
|
|
@ -757,6 +757,8 @@ bool testResolvedAstEquivalence(
|
|||
resolvedAst1.element, resolvedAst2.element) &&
|
||||
new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
|
||||
'node', resolvedAst1.node, resolvedAst2.node) &&
|
||||
new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
|
||||
'body', resolvedAst1.body, resolvedAst2.body) &&
|
||||
testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ class Key {
|
|||
static const Key ALIAS = const Key('alias');
|
||||
static const Key ARGUMENTS = const Key('arguments');
|
||||
static const Key ASYNC_MARKER = const Key('asyncMarker');
|
||||
static const Key BODY = const Key('body');
|
||||
static const Key BOUND = const Key('bound');
|
||||
static const Key CACHED_TYPE = const Key('cachedType');
|
||||
static const Key CALL_STRUCTURE = const Key('callStructure');
|
||||
|
|
|
@ -108,6 +108,9 @@ class ResolvedAstSerializer extends Visitor {
|
|||
Key.URI,
|
||||
elements.analyzedElement.compilationUnit.script.resourceUri,
|
||||
elements.analyzedElement.compilationUnit.script.resourceUri);
|
||||
if (resolvedAst.body != null) {
|
||||
objectEncoder.setInt(Key.BODY, nodeIndices[resolvedAst.body]);
|
||||
}
|
||||
AstKind kind;
|
||||
if (element.enclosingClass is EnumClassElement) {
|
||||
if (element.name == 'index') {
|
||||
|
@ -479,6 +482,11 @@ class ResolvedAstDeserializer {
|
|||
AstIndexComputer indexComputer = new AstIndexComputer();
|
||||
Map<Node, int> nodeIndices = indexComputer.nodeIndices;
|
||||
List<Node> nodeList = indexComputer.nodeList;
|
||||
Node body;
|
||||
int bodyNodeIndex = objectDecoder.getInt(Key.BODY, isOptional: true);
|
||||
if (bodyNodeIndex != null) {
|
||||
body = nodeList[bodyNodeIndex];
|
||||
}
|
||||
root.accept(indexComputer);
|
||||
|
||||
List<JumpTarget> jumpTargets = <JumpTarget>[];
|
||||
|
@ -594,6 +602,6 @@ class ResolvedAstDeserializer {
|
|||
}
|
||||
}
|
||||
}
|
||||
return new ParsedResolvedAst(element, root, elements);
|
||||
return new ParsedResolvedAst(element, root, body, elements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,14 @@ class SerializationTask extends CompilerTask implements LibraryDeserializer {
|
|||
return new DeserializedResolutionWorkItem(
|
||||
element, context, deserializer.computeWorldImpact(element));
|
||||
}
|
||||
|
||||
bool hasResolvedAst(Element element) {
|
||||
return deserializer != null ? deserializer.hasResolvedAst(element) : false;
|
||||
}
|
||||
|
||||
ResolvedAst getResolvedAst(Element element) {
|
||||
return deserializer != null ? deserializer.getResolvedAst(element) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// A [ResolutionWorkItem] for a deserialized element.
|
||||
|
@ -84,6 +92,7 @@ class DeserializedResolutionWorkItem implements ResolutionWorkItem {
|
|||
abstract class DeserializerSystem {
|
||||
Future<LibraryElement> readLibrary(Uri resolvedUri);
|
||||
bool isDeserialized(Element element);
|
||||
bool hasResolvedAst(Element element);
|
||||
ResolvedAst getResolvedAst(Element element);
|
||||
ResolutionImpact getResolutionImpact(Element element);
|
||||
WorldImpact computeWorldImpact(Element element);
|
||||
|
|
|
@ -327,8 +327,8 @@ class LocalsHandler {
|
|||
void startFunction(AstElement element, ast.Node node) {
|
||||
assert(invariant(element, element.isImplementation));
|
||||
Compiler compiler = builder.compiler;
|
||||
closureData = compiler.closureToClassMapper
|
||||
.computeClosureToClassMapping(element.resolvedAst);
|
||||
closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
|
||||
compiler.backend.frontend.getResolvedAst(element.declaration));
|
||||
|
||||
if (element is FunctionElement) {
|
||||
FunctionElement functionElement = element;
|
||||
|
@ -457,7 +457,8 @@ class LocalsHandler {
|
|||
builder.reporter.internalError(builder.compiler.currentElement,
|
||||
"Runtime type information not available for $local.");
|
||||
} else {
|
||||
builder.reporter.internalError(local, "Cannot find value $local.");
|
||||
builder.reporter.internalError(
|
||||
local, "Cannot find value $local in ${directLocals.keys}.");
|
||||
}
|
||||
}
|
||||
HInstruction value = directLocals[local];
|
||||
|
@ -1377,6 +1378,7 @@ class SsaBuilder extends ast.Visitor
|
|||
if (compiler.elementHasCompileTimeError(element)) return false;
|
||||
|
||||
FunctionElement function = element;
|
||||
ResolvedAst functionResolvedAst = backend.frontend.getResolvedAst(function);
|
||||
bool insideLoop = loopNesting > 0 || graph.calledInLoop;
|
||||
|
||||
// Bail out early if the inlining decision is in the cache and we can't
|
||||
|
@ -1436,7 +1438,7 @@ class SsaBuilder extends ast.Visitor
|
|||
|
||||
bool doesNotContainCode() {
|
||||
// A function with size 1 does not contain any code.
|
||||
return InlineWeeder.canBeInlined(function, 1, true,
|
||||
return InlineWeeder.canBeInlined(functionResolvedAst, 1, true,
|
||||
enableUserAssertions: compiler.options.enableUserAssertions);
|
||||
}
|
||||
|
||||
|
@ -1444,7 +1446,7 @@ class SsaBuilder extends ast.Visitor
|
|||
// The call is on a path which is executed rarely, so inline only if it
|
||||
// does not make the program larger.
|
||||
if (isCalledOnce(element)) {
|
||||
return InlineWeeder.canBeInlined(function, -1, false,
|
||||
return InlineWeeder.canBeInlined(functionResolvedAst, -1, false,
|
||||
enableUserAssertions: compiler.options.enableUserAssertions);
|
||||
}
|
||||
// TODO(sra): Measure if inlining would 'reduce' the size. One desirable
|
||||
|
@ -1482,7 +1484,7 @@ class SsaBuilder extends ast.Visitor
|
|||
if (cachedCanBeInlined == true) {
|
||||
// We may have forced the inlining of some methods. Therefore check
|
||||
// if we can inline this method regardless of size.
|
||||
assert(InlineWeeder.canBeInlined(function, -1, false,
|
||||
assert(InlineWeeder.canBeInlined(functionResolvedAst, -1, false,
|
||||
allowLoops: true,
|
||||
enableUserAssertions: compiler.options.enableUserAssertions));
|
||||
return true;
|
||||
|
@ -1507,7 +1509,7 @@ class SsaBuilder extends ast.Visitor
|
|||
}
|
||||
bool canInline;
|
||||
canInline = InlineWeeder.canBeInlined(
|
||||
function, maxInliningNodes, useMaxInliningNodes,
|
||||
functionResolvedAst, maxInliningNodes, useMaxInliningNodes,
|
||||
enableUserAssertions: compiler.options.enableUserAssertions);
|
||||
if (canInline) {
|
||||
backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
|
||||
|
@ -1531,7 +1533,7 @@ class SsaBuilder extends ast.Visitor
|
|||
}
|
||||
List<HInstruction> compiledArguments = completeSendArgumentsList(
|
||||
function, selector, providedArguments, currentNode);
|
||||
enterInlinedMethod(function, currentNode, compiledArguments,
|
||||
enterInlinedMethod(function, functionResolvedAst, compiledArguments,
|
||||
instanceType: instanceType);
|
||||
inlinedFrom(function, () {
|
||||
if (!isReachable) {
|
||||
|
@ -1678,7 +1680,7 @@ class SsaBuilder extends ast.Visitor
|
|||
HGraph buildMethod(FunctionElement functionElement) {
|
||||
assert(invariant(functionElement, functionElement.isImplementation));
|
||||
graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
|
||||
ast.FunctionExpression function = functionElement.node;
|
||||
ast.FunctionExpression function = resolvedAst.node;
|
||||
assert(function != null);
|
||||
assert(elements.getFunctionDefinition(function) != null);
|
||||
openFunction(functionElement, function);
|
||||
|
@ -1832,9 +1834,12 @@ class SsaBuilder extends ast.Visitor
|
|||
void setupStateForInlining(
|
||||
FunctionElement function, List<HInstruction> compiledArguments,
|
||||
{InterfaceType instanceType}) {
|
||||
ResolvedAst resolvedAst =
|
||||
compiler.backend.frontend.getResolvedAst(function.declaration);
|
||||
assert(resolvedAst != null);
|
||||
localsHandler = new LocalsHandler(this, function, instanceType);
|
||||
localsHandler.closureData = compiler.closureToClassMapper
|
||||
.computeClosureToClassMapping(function.resolvedAst);
|
||||
localsHandler.closureData =
|
||||
compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst);
|
||||
returnLocal = new SyntheticLocal("result", function);
|
||||
localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler));
|
||||
|
||||
|
@ -1863,8 +1868,6 @@ class SsaBuilder extends ast.Visitor
|
|||
}
|
||||
assert(argumentIndex == compiledArguments.length);
|
||||
|
||||
resolvedAst = function.resolvedAst;
|
||||
assert(resolvedAst != null);
|
||||
returnType = signature.type.returnType;
|
||||
stack = <HInstruction>[];
|
||||
|
||||
|
@ -2008,7 +2011,7 @@ class SsaBuilder extends ast.Visitor
|
|||
|
||||
// Build the initializers in the context of the new constructor.
|
||||
ResolvedAst oldResolvedAst = resolvedAst;
|
||||
resolvedAst = callee.resolvedAst;
|
||||
resolvedAst = backend.frontend.getResolvedAst(callee);
|
||||
ClosureClassMap oldClosureData = localsHandler.closureData;
|
||||
ClosureClassMap newClosureData = compiler.closureToClassMapper
|
||||
.computeClosureToClassMapping(resolvedAst);
|
||||
|
@ -2175,7 +2178,7 @@ class SsaBuilder extends ast.Visitor
|
|||
} else {
|
||||
ast.Node right = initializer;
|
||||
ResolvedAst savedResolvedAst = resolvedAst;
|
||||
resolvedAst = member.resolvedAst;
|
||||
resolvedAst = backend.frontend.getResolvedAst(member);
|
||||
// In case the field initializer uses closures, run the
|
||||
// closure to class mapper.
|
||||
compiler.closureToClassMapper
|
||||
|
@ -2382,7 +2385,7 @@ class SsaBuilder extends ast.Visitor
|
|||
bodyCallInputs.add(interceptor);
|
||||
}
|
||||
bodyCallInputs.add(newObject);
|
||||
ResolvedAst resolvedAst = constructor.resolvedAst;
|
||||
ResolvedAst resolvedAst = backend.frontend.getResolvedAst(constructor);
|
||||
ast.Node node = resolvedAst.node;
|
||||
ClosureClassMap parameterClosureData =
|
||||
compiler.closureToClassMapper.getMappingForNestedFunction(node);
|
||||
|
@ -7879,8 +7882,8 @@ class SsaBuilder extends ast.Visitor
|
|||
* This method is invoked before inlining the body of [function] into this
|
||||
* [SsaBuilder].
|
||||
*/
|
||||
void enterInlinedMethod(FunctionElement function, ast.Node _,
|
||||
List<HInstruction> compiledArguments,
|
||||
void enterInlinedMethod(FunctionElement function,
|
||||
ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments,
|
||||
{InterfaceType instanceType}) {
|
||||
AstInliningState state = new AstInliningState(
|
||||
function,
|
||||
|
@ -7891,6 +7894,7 @@ class SsaBuilder extends ast.Visitor
|
|||
localsHandler,
|
||||
inTryStatement,
|
||||
allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function));
|
||||
resolvedAst = functionResolvedAst;
|
||||
inliningStack.add(state);
|
||||
|
||||
// Setting up the state of the (AST) builder is performed even when the
|
||||
|
@ -8087,14 +8091,14 @@ class InlineWeeder extends ast.Visitor {
|
|||
this.enableUserAssertions);
|
||||
|
||||
static bool canBeInlined(
|
||||
FunctionElement function, int maxInliningNodes, bool useMaxInliningNodes,
|
||||
ResolvedAst resolvedAst, int maxInliningNodes, bool useMaxInliningNodes,
|
||||
{bool allowLoops: false, bool enableUserAssertions: null}) {
|
||||
assert(enableUserAssertions is bool); // Ensure we passed it.
|
||||
if (function.resolvedAst.elements.containsTryStatement) return false;
|
||||
if (resolvedAst.elements.containsTryStatement) return false;
|
||||
|
||||
InlineWeeder weeder = new InlineWeeder(maxInliningNodes,
|
||||
useMaxInliningNodes, allowLoops, enableUserAssertions);
|
||||
ast.FunctionExpression functionExpression = function.node;
|
||||
ast.FunctionExpression functionExpression = resolvedAst.node;
|
||||
weeder.visit(functionExpression.initializers);
|
||||
weeder.visit(functionExpression.body);
|
||||
weeder.visit(functionExpression.asyncModifier);
|
||||
|
|
62
tests/compiler/dart2js/serialization_compilation_test.dart
Normal file
62
tests/compiler/dart2js/serialization_compilation_test.dart
Normal file
|
@ -0,0 +1,62 @@
|
|||
// 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.
|
||||
|
||||
library dart2js.serialization_compilation_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:compiler/src/commandline_options.dart';
|
||||
import 'package:compiler/src/common/backend_api.dart';
|
||||
import 'package:compiler/src/common/names.dart';
|
||||
import 'package:compiler/src/compiler.dart';
|
||||
import 'package:compiler/src/filenames.dart';
|
||||
import 'memory_compiler.dart';
|
||||
import 'serialization_helper.dart';
|
||||
import 'serialization_test_data.dart';
|
||||
import 'output_collector.dart';
|
||||
|
||||
main(List<String> args) {
|
||||
asyncTest(() async {
|
||||
Arguments arguments = new Arguments.from(args);
|
||||
String serializedData = await serializeDartCore(
|
||||
arguments: arguments,
|
||||
serializeResolvedAst: true);
|
||||
if (arguments.filename != null) {
|
||||
Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
|
||||
await compile(serializedData, entryPoint, null);
|
||||
} else {
|
||||
Uri entryPoint = Uri.parse('memory:main.dart');
|
||||
// TODO(johnniwinther): Handle the remaining tests.
|
||||
for (Test test in TESTS.sublist(0, 1)) {
|
||||
await compile(serializedData, entryPoint, test,
|
||||
verbose: arguments.verbose);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future compile(String serializedData, Uri entryPoint, Test test,
|
||||
{bool verbose: false}) async {
|
||||
String testDescription =
|
||||
test != null ? test.sourceFiles[entryPoint.path] : '${entryPoint}';
|
||||
print('------------------------------------------------------------------');
|
||||
print('compile ${testDescription}');
|
||||
print('------------------------------------------------------------------');
|
||||
OutputCollector outputCollector = new OutputCollector();
|
||||
await runCompiler(
|
||||
entryPoint: entryPoint,
|
||||
memorySourceFiles: test != null ? test.sourceFiles : const {},
|
||||
options: [Flags.disableTypeInference,
|
||||
Flags.disableInlining,
|
||||
Flags.noSourceMaps],
|
||||
outputProvider: outputCollector,
|
||||
beforeRun: (Compiler compiler) {
|
||||
deserialize(compiler, serializedData, deserializeResolvedAst: true);
|
||||
});
|
||||
if (verbose) {
|
||||
print(outputCollector.getOutput('', 'js'));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue