| Index: pkg/compiler/lib/src/ssa/builder.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
|
| index 3cb1c8246b7d9ae19b5968cbcfffd8543e427521..a26c26e90ff3e184a2a686b7ff3c74b81caf4ef9 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder.dart
|
| @@ -141,7 +141,16 @@ class SsaBuilder extends ast.Visitor
|
| // used only for codegen, but currently we want to experiment using it for
|
| // code-analysis too.
|
| final CodegenRegistry registry;
|
| +
|
| + /// All results from the global type-inference analysis.
|
| final GlobalTypeInferenceResults inferenceResults;
|
| +
|
| + /// Results from the global type-inference analysis corresponding to the
|
| + /// current element being visited.
|
| + ///
|
| + /// Invariant: this property is updated together with [resolvedAst].
|
| + GlobalTypeInferenceElementResult elementInferenceResults;
|
| +
|
| final JavaScriptBackend backend;
|
| final ConstantSystem constantSystem;
|
| final RuntimeTypes rti;
|
| @@ -193,6 +202,8 @@ class SsaBuilder extends ast.Visitor
|
| this.inferenceResults = backend.compiler.globalInference.results {
|
| assert(target.isImplementation);
|
| compiler = backend.compiler;
|
| + elementInferenceResults = _resultOf(target);
|
| + assert(elementInferenceResults != null);
|
| graph.element = target;
|
| sourceElementStack.add(target);
|
| sourceInformationBuilder =
|
| @@ -234,6 +245,17 @@ class SsaBuilder extends ast.Visitor
|
| // implementation/declaration distinction.
|
| Element get sourceElement => sourceElementStack.last;
|
|
|
| + /// Helper to retrieve global inference results for [element] with special
|
| + /// care for `ConstructorBodyElement`s which don't exist at the time the
|
| + /// global analysis run.
|
| + ///
|
| + /// Note: this helper is used selectively. When we know that we are in a
|
| + /// context were we don't expect to see a constructor body element, we
|
| + /// directly fetch the data from the global inference results.
|
| + GlobalTypeInferenceElementResult _resultOf(AstElement element) =>
|
| + inferenceResults.resultOf(
|
| + element is ConstructorBodyElementX ? element.constructor : element);
|
| +
|
| bool get _checkOrTrustTypes =>
|
| compiler.options.enableTypeAssertions ||
|
| compiler.options.trustTypeAnnotations;
|
| @@ -436,7 +458,7 @@ class SsaBuilder extends ast.Visitor
|
| // A generative constructor body is not seen by global analysis,
|
| // so we should not query for its type.
|
| if (!element.isGenerativeConstructorBody) {
|
| - if (inferenceResults.throwsAlways(element)) {
|
| + if (inferenceResults.resultOf(element).throwsAlways) {
|
| isReachable = false;
|
| return false;
|
| }
|
| @@ -568,12 +590,10 @@ class SsaBuilder extends ast.Visitor
|
| return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
|
| }
|
|
|
| - bool isFunctionCalledOnce(Element element) {
|
| - if (element is ConstructorBodyElement) {
|
| - // ConstructorBodyElements are not in the type inference graph.
|
| - return false;
|
| - }
|
| - return inferenceResults.isCalledOnce(element);
|
| + bool isFunctionCalledOnce(element) {
|
| + // ConstructorBodyElements are not in the type inference graph.
|
| + if (element is ConstructorBodyElement) return false;
|
| + return inferenceResults.resultOf(element).isCalledOnce;
|
| }
|
|
|
| bool isCalledOnce(Element element) {
|
| @@ -759,8 +779,8 @@ class SsaBuilder extends ast.Visitor
|
| }
|
| }
|
|
|
| - closeAndGotoExit(new HReturn(value, sourceInformationBuilder.buildReturn(
|
| - sourceInfoNode)));
|
| + closeAndGotoExit(new HReturn(
|
| + value, sourceInformationBuilder.buildReturn(sourceInfoNode)));
|
| return closeFunction();
|
| }
|
|
|
| @@ -868,6 +888,7 @@ class SsaBuilder extends ast.Visitor
|
| returnLocal = state.oldReturnLocal;
|
| inTryStatement = state.inTryStatement;
|
| resolvedAst = state.oldResolvedAst;
|
| + elementInferenceResults = state.oldElementInferenceResults;
|
| returnType = state.oldReturnType;
|
| assert(stack.isEmpty);
|
| stack = state.oldStack;
|
| @@ -1000,6 +1021,8 @@ class SsaBuilder extends ast.Visitor
|
| // Build the initializers in the context of the new constructor.
|
| ResolvedAst oldResolvedAst = resolvedAst;
|
| resolvedAst = callee.resolvedAst;
|
| + final oldElementInferenceResults = elementInferenceResults;
|
| + elementInferenceResults = inferenceResults.resultOf(callee);
|
| ClosureClassMap oldClosureData = localsHandler.closureData;
|
| ClosureClassMap newClosureData =
|
| compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
|
| @@ -1010,6 +1033,7 @@ class SsaBuilder extends ast.Visitor
|
| buildInitializers(callee, constructorResolvedAsts, fieldValues);
|
| localsHandler.closureData = oldClosureData;
|
| resolvedAst = oldResolvedAst;
|
| + elementInferenceResults = oldElementInferenceResults;
|
| });
|
| }
|
|
|
| @@ -1172,11 +1196,14 @@ class SsaBuilder extends ast.Visitor
|
| ast.Node right = initializer;
|
| ResolvedAst savedResolvedAst = resolvedAst;
|
| resolvedAst = fieldResolvedAst;
|
| + final oldElementInferenceResults = elementInferenceResults;
|
| + elementInferenceResults = inferenceResults.resultOf(member);
|
| // In case the field initializer uses closures, run the
|
| // closure to class mapper.
|
| compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
|
| inlinedFrom(fieldResolvedAst, () => right.accept(this));
|
| resolvedAst = savedResolvedAst;
|
| + elementInferenceResults = oldElementInferenceResults;
|
| fieldValues[member] = pop();
|
| }
|
| });
|
| @@ -2069,7 +2096,7 @@ class SsaBuilder extends ast.Visitor
|
| }
|
|
|
| pushInvokeDynamic(node, elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements), [operand],
|
| + elementInferenceResults.typeOfSend(node), [operand],
|
| sourceInformation: sourceInformationBuilder.buildGeneric(node));
|
| }
|
|
|
| @@ -2100,7 +2127,7 @@ class SsaBuilder extends ast.Visitor
|
| visitAndPop(left),
|
| visitAndPop(right),
|
| elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements),
|
| + elementInferenceResults.typeOfSend(node),
|
| node,
|
| sourceInformation:
|
| sourceInformationBuilder.buildGeneric(node.selector));
|
| @@ -2263,7 +2290,7 @@ class SsaBuilder extends ast.Visitor
|
| void generateDynamicGet(ast.Send node) {
|
| HInstruction receiver = generateInstanceSendReceiver(node);
|
| generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements), receiver);
|
| + elementInferenceResults.typeOfSend(node), receiver);
|
| }
|
|
|
| /// Generate a closurization of the static or top level [function].
|
| @@ -2312,7 +2339,7 @@ class SsaBuilder extends ast.Visitor
|
| generateInstanceGetterWithCompiledReceiver(
|
| node,
|
| elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements),
|
| + elementInferenceResults.typeOfSend(node),
|
| expression);
|
| });
|
| }
|
| @@ -2377,7 +2404,7 @@ class SsaBuilder extends ast.Visitor
|
| if (selector == null) {
|
| assert(send != null);
|
| selector = elements.getSelector(send);
|
| - mask ??= inferenceResults.typeOfSend(send, elements);
|
| + mask ??= elementInferenceResults.typeOfSend(send);
|
| }
|
| if (location == null) {
|
| assert(send != null);
|
| @@ -2648,7 +2675,7 @@ class SsaBuilder extends ast.Visitor
|
|
|
| void _generateDynamicSend(ast.Send node, HInstruction receiver) {
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = inferenceResults.typeOfSend(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfSend(node);
|
| SourceInformation sourceInformation =
|
| sourceInformationBuilder.buildCall(node, node.selector);
|
|
|
| @@ -4427,7 +4454,7 @@ class SsaBuilder extends ast.Visitor
|
| receiver,
|
| rhs,
|
| elements.getOperatorSelectorInComplexSendSet(node),
|
| - inferenceResults.typeOfOperator(node, elements),
|
| + elementInferenceResults.typeOfOperator(node),
|
| node,
|
| sourceInformation:
|
| sourceInformationBuilder.buildGeneric(node.assignmentOperator));
|
| @@ -4790,7 +4817,7 @@ class SsaBuilder extends ast.Visitor
|
| }
|
|
|
| pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node),
|
| - inferenceResults.typeOfGetter(node, elements), [receiver, index]);
|
| + elementInferenceResults.typeOfGetter(node), [receiver, index]);
|
| HInstruction getterInstruction = pop();
|
| if (node.isIfNullAssignment) {
|
| // Compile x[i] ??= e as:
|
| @@ -4805,7 +4832,7 @@ class SsaBuilder extends ast.Visitor
|
| pushInvokeDynamic(
|
| node,
|
| elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements),
|
| + elementInferenceResults.typeOfSend(node),
|
| [receiver, index, value]);
|
| pop();
|
| stack.add(value);
|
| @@ -4813,11 +4840,8 @@ class SsaBuilder extends ast.Visitor
|
| } else {
|
| handleComplexOperatorSend(node, getterInstruction, arguments);
|
| HInstruction value = pop();
|
| - pushInvokeDynamic(
|
| - node,
|
| - elements.getSelector(node),
|
| - inferenceResults.typeOfSend(node, elements),
|
| - [receiver, index, value]);
|
| + pushInvokeDynamic(node, elements.getSelector(node),
|
| + elementInferenceResults.typeOfSend(node), [receiver, index, value]);
|
| pop();
|
| if (node.isPostfix) {
|
| stack.add(getterInstruction);
|
| @@ -5021,7 +5045,7 @@ class SsaBuilder extends ast.Visitor
|
| generateInstanceGetterWithCompiledReceiver(
|
| node,
|
| elements.getGetterSelectorInComplexSendSet(node),
|
| - inferenceResults.typeOfGetter(node, elements),
|
| + elementInferenceResults.typeOfGetter(node),
|
| receiver);
|
| HInstruction getterInstruction = pop();
|
| if (node.isIfNullAssignment) {
|
| @@ -5484,7 +5508,7 @@ class SsaBuilder extends ast.Visitor
|
| }
|
|
|
| _inferredTypeOfNewList(ast.Node node) =>
|
| - inferenceResults.typeOfNewList(sourceElement, node) ??
|
| + _resultOf(sourceElement).typeOfNewList(node) ??
|
| compiler.commonMasks.dynamicType;
|
|
|
| visitConditional(ast.Conditional node) {
|
| @@ -5580,7 +5604,7 @@ class SsaBuilder extends ast.Visitor
|
|
|
| HInstruction buildCondition() {
|
| Selector selector = Selectors.moveNext;
|
| - TypeMask mask = inferenceResults.typeOfIteratorMoveNext(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
|
| pushInvokeDynamic(node, selector, mask, [streamIterator]);
|
| HInstruction future = pop();
|
| push(new HAwait(
|
| @@ -5592,8 +5616,7 @@ class SsaBuilder extends ast.Visitor
|
|
|
| void buildBody() {
|
| Selector call = Selectors.current;
|
| - TypeMask callMask =
|
| - inferenceResults.typeOfIteratorCurrent(node, elements);
|
| + TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node);
|
| pushInvokeDynamic(node, call, callMask, [streamIterator]);
|
|
|
| ast.Node identifier = node.declaredIdentifier;
|
| @@ -5602,7 +5625,7 @@ class SsaBuilder extends ast.Visitor
|
| HInstruction value = pop();
|
| if (identifier.asSend() != null &&
|
| Elements.isInstanceSend(identifier, elements)) {
|
| - TypeMask mask = inferenceResults.typeOfSend(identifier, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfSend(identifier);
|
| HInstruction receiver = generateInstanceSendReceiver(identifier);
|
| assert(receiver != null);
|
| generateInstanceSetterWithCompiledReceiver(null, receiver, value,
|
| @@ -5641,7 +5664,7 @@ class SsaBuilder extends ast.Visitor
|
| // method is inlined. We would require full scalar replacement in that
|
| // case.
|
|
|
| - TypeMask mask = inferenceResults.typeOfIterator(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfIterator(node);
|
|
|
| ClosedWorld closedWorld = compiler.closedWorld;
|
| if (mask != null &&
|
| @@ -5666,7 +5689,7 @@ class SsaBuilder extends ast.Visitor
|
|
|
| void buildInitializer() {
|
| Selector selector = Selectors.iterator;
|
| - TypeMask mask = inferenceResults.typeOfIterator(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfIterator(node);
|
| visit(node.expression);
|
| HInstruction receiver = pop();
|
| pushInvokeDynamic(node, selector, mask, [receiver]);
|
| @@ -5675,14 +5698,14 @@ class SsaBuilder extends ast.Visitor
|
|
|
| HInstruction buildCondition() {
|
| Selector selector = Selectors.moveNext;
|
| - TypeMask mask = inferenceResults.typeOfIteratorMoveNext(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
|
| pushInvokeDynamic(node, selector, mask, [iterator]);
|
| return popBoolified();
|
| }
|
|
|
| void buildBody() {
|
| Selector call = Selectors.current;
|
| - TypeMask mask = inferenceResults.typeOfIteratorCurrent(node, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node);
|
| pushInvokeDynamic(node, call, mask, [iterator]);
|
| buildAssignLoopVariable(node, pop());
|
| visit(node.body);
|
| @@ -5699,7 +5722,7 @@ class SsaBuilder extends ast.Visitor
|
|
|
| if (identifier.asSend() != null &&
|
| Elements.isInstanceSend(identifier, elements)) {
|
| - TypeMask mask = inferenceResults.typeOfSend(identifier, elements);
|
| + TypeMask mask = elementInferenceResults.typeOfSend(identifier);
|
| HInstruction receiver = generateInstanceSendReceiver(identifier);
|
| assert(receiver != null);
|
| generateInstanceSetterWithCompiledReceiver(null, receiver, value,
|
| @@ -6638,8 +6661,10 @@ class SsaBuilder extends ast.Visitor
|
| stack,
|
| localsHandler,
|
| inTryStatement,
|
| - allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function));
|
| + isCalledOnce(function),
|
| + elementInferenceResults);
|
| resolvedAst = functionResolvedAst;
|
| + elementInferenceResults = _resultOf(function);
|
| inliningStack.add(state);
|
|
|
| // Setting up the state of the (AST) builder is performed even when the
|
| @@ -6960,6 +6985,7 @@ class AstInliningState extends InliningState {
|
| final LocalsHandler oldLocalsHandler;
|
| final bool inTryStatement;
|
| final bool allFunctionsCalledOnce;
|
| + final GlobalTypeInferenceElementResult oldElementInferenceResults;
|
|
|
| AstInliningState(
|
| FunctionElement function,
|
| @@ -6969,7 +6995,8 @@ class AstInliningState extends InliningState {
|
| this.oldStack,
|
| this.oldLocalsHandler,
|
| this.inTryStatement,
|
| - this.allFunctionsCalledOnce)
|
| + this.allFunctionsCalledOnce,
|
| + this.oldElementInferenceResults)
|
| : super(function);
|
| }
|
|
|
|
|