Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Unified Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2512023002: Add types for map literal construction with kernel code. (Closed)
Patch Set: implicitInstantiations Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/builder_kernel.dart
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 3f407cab4f35bd7c4a41ab38c29c0d1ebc10b184..7050eae76ef968d6972f3464167f9e0ea2b1f566 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -29,6 +29,7 @@ import 'loop_handler.dart';
import 'nodes.dart';
import 'ssa_branch_builder.dart';
import 'type_builder.dart';
+import 'types.dart' show TypeMaskFactory;
class SsaKernelBuilderTask extends CompilerTask {
final JavaScriptBackend backend;
@@ -57,6 +58,14 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
final ResolvedAst resolvedAst;
final CodegenRegistry registry;
+ /// A stack of [DartType]s that have been seen during inlining of factory
+ /// constructors. These types are preserved in [HInvokeStatic]s and
+ /// [HCreate]s inside the inline code and registered during code generation
+ /// for these nodes.
+ // TODO(karlklose): consider removing this and keeping the (substituted) types
+ // of the type variables in an environment (like the [LocalsHandler]).
+ final List<DartType> currentImplicitInstantiations = <DartType>[];
+
@override
JavaScriptBackend get backend => compiler.backend;
@@ -320,6 +329,18 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
closeFunction();
}
+ void addImplicitInstantiation(DartType type) {
+ if (type != null) {
+ currentImplicitInstantiations.add(type);
+ }
+ }
+
+ void removeImplicitInstantiation(DartType type) {
+ if (type != null) {
+ currentImplicitInstantiations.removeLast();
+ }
+ }
+
void openFunction() {
HBasicBlock block = graph.addNewBlock();
open(graph.entry);
@@ -715,7 +736,9 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
stack.add(graph.addConstantNull(compiler));
}
- HInstruction setRtiIfNeeded(HInstruction object, ir.ListLiteral listLiteral) {
+ /// Set the runtime type information if necessary.
+ HInstruction setListRuntimeTypeInfoIfNeeded(
+ HInstruction object, ir.ListLiteral listLiteral) {
InterfaceType type = localsHandler
.substInContext(elements.getType(astAdapter.getNode(listLiteral)));
if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
@@ -744,7 +767,8 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
}
listInstruction = new HLiteralList(elements, backend.extendableArrayType);
add(listInstruction);
- listInstruction = setRtiIfNeeded(listInstruction, listLiteral);
+ listInstruction =
+ setListRuntimeTypeInfoIfNeeded(listInstruction, listLiteral);
}
TypeMask type = astAdapter.typeOfNewList(targetElement, listLiteral);
@@ -783,8 +807,52 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
inputs.add(argList);
}
- // TODO(het): Add type information
- _pushStaticInvocation(constructor, inputs, backend.dynamicType);
+ assert(constructor.kind == ir.ProcedureKind.Factory);
+
+ InterfaceType type = localsHandler
+ .substInContext(elements.getType(astAdapter.getNode(mapLiteral)));
+
+ ir.Class cls = constructor.enclosingClass;
+
+ if (backend.classNeedsRti(astAdapter.getElement(cls))) {
+ List<HInstruction> typeInputs = <HInstruction>[];
+ type.typeArguments.forEach((DartType argument) {
+ typeInputs
+ .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
+ });
+
+ // We lift this common call pattern into a helper function to save space
+ // in the output.
+ if (typeInputs.every((HInstruction input) => input.isNull())) {
+ if (constructorArgs.isEmpty) {
+ constructor = astAdapter.mapLiteralUntypedEmptyMaker;
+ } else {
+ constructor = astAdapter.mapLiteralUntypedMaker;
+ }
+ } else {
+ inputs.addAll(typeInputs);
+ }
+ }
+
+ // If runtime type information is needed and the map literal has no type
+ // parameters, 'constructor' is a static function that forwards the call to
+ // the factory constructor without type parameters.
+ assert(constructor.kind == ir.ProcedureKind.Factory);
+
+ // The instruction type will always be a subtype of the mapLiteralClass, but
+ // type inference might discover a more specific type, or find nothing (in
+ // dart2js unit tests).
+ TypeMask mapType = new TypeMask.nonNullSubtype(
+ astAdapter.getElement(astAdapter.mapLiteralClass),
+ compiler.closedWorld);
+ TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
+ astAdapter.getElement(constructor), compiler);
+ TypeMask instructionType =
+ mapType.intersection(returnTypeMask, compiler.closedWorld);
+
+ addImplicitInstantiation(type);
+ _pushStaticInvocation(constructor, inputs, instructionType);
+ removeImplicitInstantiation(type);
}
@override
@@ -917,6 +985,10 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
HInstruction instruction = new HInvokeStatic(
astAdapter.getMember(target), arguments, typeMask,
targetCanThrow: astAdapter.getCanThrow(target));
+ if (currentImplicitInstantiations.isNotEmpty) {
+ instruction.instantiatedTypes =
+ new List<DartType>.from(currentImplicitInstantiations);
+ }
instruction.sideEffects = astAdapter.getSideEffects(target);
push(instruction);
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698