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

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

Issue 2549233004: Handle closures, aka FunctionExpression in Kernel! (Closed)
Patch Set: . Created 4 years 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 | no next file » | 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 6acd15dc3215aeb04e5482829cab9546b950ff30..b63ca0d67d543914539515a163c5c7b3f6918d8c 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4,6 +4,7 @@
import 'package:kernel/ast.dart' as ir;
+import '../closure.dart';
import '../common.dart';
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
import '../common/names.dart';
@@ -114,6 +115,14 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
}
if (originTarget is FunctionElement) {
target = kernel.functions[originTarget];
+ // Closures require a lookup one level deeper in the closure class mapper.
+ if (target == null) {
+ ClosureClassMap classMap = compiler.closureToClassMapper
+ .getClosureToClassMapping(originTarget.resolvedAst);
+ if (classMap.closureElement != null) {
+ target = kernel.localFunctions[classMap.closureElement];
+ }
+ }
} else if (originTarget is FieldElement) {
target = kernel.fields[originTarget];
}
@@ -123,11 +132,17 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
// TODO(het): no reason to do this here...
HInstruction.idCounter = 0;
if (target is ir.Procedure) {
- buildProcedure(target);
+ target = (target as ir.Procedure).function;
+ buildFunctionNode(target);
} else if (target is ir.Field) {
buildField(target);
} else if (target is ir.Constructor) {
buildConstructor(target);
+ } else if (target is ir.FunctionExpression) {
+ target = (target as ir.FunctionExpression).function;
+ buildFunctionNode(target);
+ } else {
+ throw 'No case implemented to handle $target';
}
assert(graph.isValid());
return graph;
@@ -334,10 +349,11 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
type, kind, original.instructionType, reifiedType, original);
}
- /// Builds a SSA graph for [procedure].
- void buildProcedure(ir.Procedure procedure) {
+ /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and
+ /// Procedures.
+ void buildFunctionNode(ir.FunctionNode functionNode) {
openFunction();
- procedure.function.body.accept(this);
+ functionNode.body.accept(this);
closeFunction();
}
@@ -433,10 +449,10 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
if (returnStatement.expression == null) {
value = graph.addConstantNull(compiler);
} else {
- assert(target is ir.Procedure);
+ assert(target is ir.FunctionNode);
returnStatement.expression.accept(this);
value = typeBuilder.potentiallyCheckOrTrustType(pop(),
- astAdapter.getFunctionReturnType((target as ir.Procedure).function));
+ astAdapter.getFunctionReturnType(target));
}
// TODO(het): Add source information
// TODO(het): Set a return value instead of closing the function when we
@@ -1319,8 +1335,8 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
String isolateName = backend.namer.staticStateHolder;
SideEffects sideEffects = new SideEffects.empty();
sideEffects.setAllSideEffects();
- push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
- backend.dynamicType, inputs,
+ push(new HForeignCode(
+ js.js.parseForeignJS("$isolateName = #"), backend.dynamicType, inputs,
nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
effects: sideEffects));
}
@@ -1562,6 +1578,37 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
}
}
+ @override
+ void visitFunctionExpression(ir.FunctionExpression funcExpression) {
+ LocalFunctionElement methodElement = astAdapter.getElement(funcExpression);
+ ClosureClassMap nestedClosureData = compiler.closureToClassMapper
+ .getClosureToClassMapping(methodElement.resolvedAst);
+ assert(nestedClosureData != null);
+ assert(nestedClosureData.closureClassElement != null);
+ ClosureClassElement closureClassElement =
+ nestedClosureData.closureClassElement;
+ FunctionElement callElement = nestedClosureData.callElement;
+ // TODO(ahe): This should be registered in codegen, not here.
+ // TODO(johnniwinther): Is [registerStaticUse] equivalent to
+ // [addToWorkList]?
+ registry?.registerStaticUse(new StaticUse.foreignUse(callElement));
+
+ List<HInstruction> capturedVariables = <HInstruction>[];
+ closureClassElement.closureFields.forEach((ClosureFieldElement field) {
+ Local capturedLocal =
+ nestedClosureData.getLocalVariableForClosureField(field);
+ assert(capturedLocal != null);
+ capturedVariables.add(localsHandler.readLocal(capturedLocal));
+ });
+
+ TypeMask type =
+ new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld);
+ // TODO(efortuna): Add source information here.
+ push(new HCreate(closureClassElement, capturedVariables, type));
+
+ registry?.registerInstantiatedClosure(methodElement);
+ }
+
// TODO(het): Decide when to inline
@override
void visitMethodInvocation(ir.MethodInvocation invocation) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698